Boothand Posted March 5, 2015 Posted March 5, 2015 One thing I've never grasped, even after reading about it a lot, is blendFuncs. I'm sure I'm not alone... I need a thorough explanation of blendFunc logic, explained differently than the shader manual does it, so that I can freeform blendFunc my way through Jedi Knight. How do the blendFuncs relate to the current stages vs previous stages? What is really the color buffer?If you could also put it in a way that could let me understand how to do the following it would be very helpful: -Have an unaltered texture to do tcMod operations on, such as scrolling a tiled texture. The texture's alpha channel (not scrolling) filters the visibility of the whole texture. End result would be: A light with a gradient falloff, but with a slow scroll overlaying it based on the texture, not the alpha.
Asgarath83 Posted March 5, 2015 Posted March 5, 2015 For what i see by try and error method doing shadering for my cathedral....GL_ONE GL_ONE... -> full brightness shader, it's good for fire of glowing particles. in materials. it make they too brights, also in MD3. use it for glowing lighting texture, but not for MD3 or any kind of materials.GL_ZERO GL_ZERO -> make completely dark and opaque the objects. GL_ONE GL_ZERO -> not change much of the brightness. it's good for make lighting diffuse of glm models.GL_ONE GL_SRC_COLOR : .-> as GL_ONE GL_ZERO, but the model is little more bright and with a different RGB filter...GL_SRC_ALPHA ETC -> with alphagen and alphaconst parms make the texture translucent... you can watch throught it.GL_DST_COLOR GL_ZERO -> with rgbgen Identity, it's the better shadering for MD3 models. it's good also for the most of the materials of brushesGL_DST_COLOR GL_SRC_COLOR -> make things with color little differnet and more light of GL_DST_COLOR GL_ZERO. i not like much because create strange kind of tonality and false colors... >.< it's not much good to see.GL_SRC_ALPHA GL_ONE_:MINUS_SRC_ALPHA it's fine for MD3 translucent reflect tcgen enviroment effects. i make a marble reflex with this parameter. in tcgen enviroment stage. rgbGen Lighting Diffuse -> On glm model, not on MD3, on MD3 make it blacks.// Alphagen Lightingspecular-> good for making metal tcgen enviroment on blades and saber or metal surfaces like armors of GLM npcs or weapons. the tggen enviroment scroll the metal reflex at second of the camer view and moving of player.rgnGen vertex : use it on planar and bidimensional surfaces, like flags or leathers or leaves... if you use the $lightmap parameter, this affected about light diffusion and illumination of model or the brush, lightmap need to be followed by rgbgen parameter. using $lightmap on my md3 model i obtained morbid and soffuse lighting... :3$whiteimage: apply a white filter on the textures... i not know much about this function... i try to use at the start of my shadering works, by after i change to lightmap because it make the MD3 too brights on Meta build of the map. This is my experience with shadering,. i not know much other and i read too the Quake3 manual. atthe end, i used for many of my textures the DST_COLOR GL_ZERO, the lightmap for the stone textures of MD3 domes, and the SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA tcgen enviroment for the reflexes of my marble textures...i think every one use a different combination at second of they necessity, many thing depend by your buld and your ambiental and worldspawn and sunny skybox parameters.
Boothand Posted March 5, 2015 Author Posted March 5, 2015 I need to understand the logic though, so I can make shaders myself (which I've done quite a lot, but never really with the understanding of blendFuncs). Guessing doesn't get me far.
Ramikad Posted March 5, 2015 Posted March 5, 2015 rgbGen vertex : use it on planar and bidimensional surfaces, like flags or leathers or leaves... Tch... Used that with a misc_model_static, and what do I get? A horribly annoying flickering on the branches. Damn shaders
Xycaleth Posted March 5, 2015 Posted March 5, 2015 blendFunc is fairly simple to understand. All colours can be represented using 3 numbers, Red, Green, Blue, with a 4th number for transparency (the alpha) - in Photoshop or GIMP, you can use the colour picker to show you these numbers (or components) of the colour. These values are in the range 0 - 255. In graphics, you "normalize" these values, so they become 0.0 - 1.0. blendFunc is a way to tell the graphics card how you want two colours to be blended, where the first colour is the source, and the second colour is the destination (i.e. what's already been drawn). Blending then happens like so... sourceColor * srcBlendFunc + destinationColor * dstBlendFuncSo for example, you might write "blendFunc GL_ONE GL_ZERO". GL_ONE is your srcBlendFunc (source blend function), and GL_ZERO is your dstBlendFunc (destination blend function). GL_ONE GL_ZERO also happens to be the default blendFunc. The maths then works out like this: final color = source color * 1 + destination color * 0You can simplify this because 0 * x = 0. final color = source colorLet's take another example... blending based on alpha transparency is pretty common. This is "blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA". The final colour is then calculated: final color = source color * source color's alpha + destination color * (1 - source color's alpha)Thinking about this intuitively, if the source colour's alpha = 1, then none of the destination colour is shown, and you effectively get the same as GL_ONE GL_ZERO. If source colour's alpha = 0, then you're fully transparent, and you see the destination colour in full as you would expect. Fractional values in the source colour's alpha will make the source colour more or less transparent. All of the blendFunc names are pretty named very well so you can work out what they do by plugging them into the first formula I gave. The last important piece of information is that the final colour that's calculated is the destination colour for the next shader stage. Hopefully that's clear enough. I'm writing this at work so my post isn't as detailed as I'd like it to be, but I think it's enough to go on. Let me know if you need any more explanation and I'll try my best EDIT: Didn't read your post properly, so I missed a point. The colour buffer is the "texture" that gets drawn to your screen. However, you won't see the results of your calculations until it gets "presented" to the display. This way, you can overwrite/blend/clear existing colour pixels without you seeing any of the intermediate results. EDIT2: I've been wanting to write a simple WebGL application that lets you play with blend functions in a web browser, but have never gotten around to doing it. It would be great if someone could do this as seeing how the blend functions works in action can make understanding a lot easier. Boothand, AshuraDX, eezstreet and 2 others like this
Boothand Posted March 5, 2015 Author Posted March 5, 2015 I've been trying to write this post for soon one and a half hour, and I'm nearly psyched out. I'm trying to think of the logical way to have one texture scroll and then be hidden/filtered by the same texture's alpha channel.My crumbling logic: Stage 1 must draw nothing but the alpha channel, because if you draw the full color there will be no blendFunc in the second stage, in the destination part, to subtract again. So you will just end up with more and more.But the most logical thing for me would be to somehow draw the full color and do scroll and stuff on that - and then in the second stage take the texture's alpha channel and subtract everything else. But I feel like you can't do that. Stage 1:map etc/textureWithAlphaChannel Draw the alpha channel of the texture (GL_SRC_ALPHA) and add nothing more (GL_ZERO).(1 * x) + (1 * 0) = x. (Second stage's destination value). So we have the alpha channel, but haven't drawn the full color anywhere. Stage 2:map etc/textureWithAlphaChannel Draw the full color (GL_ONE) but also add.. add? I want less, not more. zxfdkjfk, I can't.. do it.Draw nothing again (GL_ZERO) but add stage 1 (GL_ONE) = no change. I need an example, and another explanation
redsaurus Posted March 5, 2015 Posted March 5, 2015 I started trying to write more about blendFuncs but it wasn't particularly coherent, but here's something that *might* do what you want. Untested, tcmod scroll values will need adjusting. textures/boothand/foggy_lamp { qer_editorimage textures/boothand/fog qer_trans 0.5 surfaceparm noimpact surfaceparm nomarks surfaceparm nonsolid surfaceparm nonopaque surfaceparm trans q3map_nolightmap { map textures/boothand/fog alphaGen vertex tcMod scroll 5 5 blendFunc GL_SRC_ALPHA GL_ONE } } textures/boothand/fog would just be some kind of foggy image (no alpha channel!).to get the alpha stuff working properly you could use alphamod volume brushes to force the vertex alpha (as used by alphaGen vertex) to 1 by the lamp and 0 away from it.
Asgarath83 Posted March 5, 2015 Posted March 5, 2015 You want to make a fading light... :\ i cannot help because i never make shaders of fading light...i see a tutorial about the light fading of sun by the windows, but i not know if can help you. models/map_objects/cda/marble2{ qer_editorimage models/map_objects/cda/marble2 surfaceparm nonopaque q3map_material marble q3map_onlyvertexlighting { map $lightmap rgbGen identity } { map models/map_objects/cda/marble2 blendFunc GL_ONE GL_ZERO detail rgbGen identity tcMod scale 2 2 } { map models/map_objects/cda/marble_env blendFunc GL_DST_COLOR GL_ZERO alphaGen const 0.5 tcGen environment tcMod scale 2 2 }} for what i can understand, you need to add the enter value and the exit value...the value make additions...so, for example GL_ONE GL_ZERO is like Texture total rgb value + 0 = Texture total rgb value. i used this for glasses of windows, following the tutorials about shadering of windows here on openjk forummodels/map_objects/cda/stainedglass1{// polygonOffset// this will stop the game from rendering shadows and burnmarks on the decal// q3map_material glass surfaceparm nomarks surfaceparm trans nopicmip q3map_nolightmap q3map_novertexshadows {// This is an optional line of code, that will make the texture more opague// map models/map_objects/cda/stainedglass1 blendFunc GL_DST_COLOR GL_SRC_COLOR alphaGen const 0.7 }} A marble part with enviroment: models/map_objects/cda/marbleparts2c <- shader name{ qer_editorimage models/map_objects/cda/marbleparts2c <- name of shader image used in radiant for apply shader to brush q3map_material marble <- material (affected footstep sounds when you build map with q3map2.) q3map_onlyvertexlighting <- this make better the graphical quality of the shader, also if not know why { map $lightmap rgbGen identity } { map models/map_objects/cda/marbleparts2c <- texture field blendFunc GL_ONE GL_SRC_COLOR <- GL_ONE + GL_SRC_COLOR the color are mixed. detail rgbGen identity } { map models/map_objects/cda/marble_env2 <- enviroment textures blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA <- trans blendfunc alphaGen const 0.05 <- trans value of this texture tcGen environment <- enviroment function }} can we see a screenshot of what you want to do?
Boothand Posted March 5, 2015 Author Posted March 5, 2015 Just to clarify - this thread is dedicated entirely to understanding how blendFunc works The example I used (a fading light) is not what I'm here to get help with, as I could find workarounds for this particular issue using possibly better solutions than a scrolling overlay as well. (On a sidenote, @@redsaurus, alphamod brushes? Are they related to the alpha brushes used for terrain blending? It sounds interesting either way and would want to play around with that). So my goal is to learn how blendFuncs work, especially when there are multiple stages, so that I can make my own shaders using only logic. I would need some kind of example probably and a technical step by step description of each step...! Asgarath83 likes this
Didz Posted March 5, 2015 Posted March 5, 2015 I've been trying to write this post for soon one and a half hour, and I'm nearly psyched out. I'm trying to think of the logical way to have one texture scroll and then be hidden/filtered by the same texture's alpha channel.My crumbling logic: Stage 1 must draw nothing but the alpha channel, because if you draw the full color there will be no blendFunc in the second stage, in the destination part, to subtract again. So you will just end up with more and more.But the most logical thing for me would be to somehow draw the full color and do scroll and stuff on that - and then in the second stage take the texture's alpha channel and subtract everything else. But I feel like you can't do that. Stage 1:map etc/textureWithAlphaChannel Draw the alpha channel of the texture (GL_SRC_ALPHA) and add nothing more (GL_ZERO).(1 * x) + (1 * 0) = x. (Second stage's destination value). So we have the alpha channel, but haven't drawn the full color anywhere. Stage 2:map etc/textureWithAlphaChannel Draw the full color (GL_ONE) but also add.. add? I want less, not more. zxfdkjfk, I can't.. do it.Draw nothing again (GL_ZERO) but add stage 1 (GL_ONE) = no change. I need an example, and another explanation The flaw in understanding here is that GL_SRC_ALPHA means drawing alpha only, that's not what happens. In your stage 1 example, you can use the fomula Xycaleth talked about to understand how blending would work there. FinalColour.RGB = SourceColour.RGB * SourceColour.A + DestinationColour.RGB * 0 ... which simplifies into ... FinalColour.RGB = SourceColour.RGB * SourceColour.A Things to note here:GL_SRC_ALPHA as the source blend func means the source RGB colours (texture RGB) are multiplied by the source Alpha channel (texture Alpha).SourceColour.A is a single number between 0.0 and 1.0, corresponding to the alpha channel of that particular point in the texture.Multiplying by anything that's less than 1.0 means that the RGB colours will be darkened, because the resulting values will be less than the original.Where the alpha is 0.0 in your texture, the final colour will be black. Where the alpha is 1.0 in your texture, the final colour will be the original RGB colours.Your stage 1 will basically result in a fully opaque surface whose colours will blend between black and their original colours depending on the alpha channel at the particular point on the texture. Your stage 2 would be this: FinalColour.RGB = SourceColour.RGB * 1 + DestinationColour.RGB * 0 ... which simplifies into ... FinalColour.RGB = SourceColour.RGB So here, you're completely ignoring the result of the first stage (because you're multiplying destination colour by 0), and instead you're simply using the full RGB colour of the original texture (And it'll still be fully opaque over whatever's behind the surface).So your shader essentially just does the default blending because the second stage is GL_ONE GL_ZERO. I don't understand what technique you're trying to aim at in your post though. You want one stage to have a scrolling texture with RGB, while another stage is staying still and just acting as a sort of transparency mask? Boothand likes this
Boothand Posted March 5, 2015 Author Posted March 5, 2015 Thanks for those clarifications. I think a lot of my confusion comes from trouble in imagining how adding the sources and destinations together looks like. A WebGL app like @@Xycaleth mentioned would be really useful indeed! I don't understand what technique you're trying to aim at in your post though. You want one stage to have a scrolling texture with RGB, while another stage is staying still and just acting as a sort of transparency mask? Yeah. It might not be very useful in this particular case, but I used it as an example of something I can't figure out how to do. I tried to do something similar when helping a friend with a shader, but couldn't figure it out. He had a texture with an alpha channel, and he wanted to see the whole texture and then add another texture scrolling over only the white parts of the alpha channel, as an overlay. I feel it's in the same catecory. Maybe I'll soon post an example shader that already works, and post my version of its logic, and you guys can tell me where it's flawed still
Didz Posted March 5, 2015 Posted March 5, 2015 As far as I'm aware, it's not possible to do that sort of masking in the Quake 3 engine where you have a stage that uses the alpha information of the stage below it to figure out how to blend with the surfaces underneath. Boothand likes this
Didz Posted March 5, 2015 Posted March 5, 2015 (edited) Here's an online demo of the different blending options you have: http://www.andersriggelsen.dk/glblendfunc.php The "Blend equation" option should be kept at GL_FUNC_ADD (Addition), since that's the only blending mode available in Quake 3 (as far as I know; maybe @@Xycaleth knows better).The "Premultiply" checkbox on the page is an advanced topic that concerns texture filtering, it's best to leave that Off as it would involve extra steps when exporting assets for the game. Edited March 5, 2015 by Didz Boothand likes this
Xycaleth Posted March 5, 2015 Posted March 5, 2015 He had a texture with an alpha channel, and he wanted to see the whole texture and then add another texture scrolling over only the white parts of the alpha channel, as an overlay. I feel it's in the same catecory.It's possible to do this, but the solution isn't obvious - you draw them in reverse order. Let's call your 'background texture', texture A, and your scrolling texture, texture B. Stage 1: Draw texture B as usual, with default blendFunc and scrolly fun.Stage 2: Draw texture A, with blendFunc GL_ONE_MINUS_SRC_ALPHA GL_SRC_ALPHA Your scrolling texture get's drawn first, and is the destination texture for stage 2.In stage 2, you multiply texture A's RGB values by (1 - alpha of texture A). So where the alpha is white (1), you get texture A RGB * 0, so none of texture A is used, but then you add on texture B RGB * 1 (which is the full colour of texture B ). When the alpha is black (0), the opposite happens. You get the full colour of A, and none of B. It just takes experience and some creativity to figure out what to do with your blendFuncs but if you understand the basic concepts of how the blending works, then you should get there eventually Tempust85, Asgarath83 and Boothand like this
Boothand Posted March 6, 2015 Author Posted March 6, 2015 Thanks! I'll see where this gets me and try to keep these concepts in mind and gain some experience
redsaurus Posted March 6, 2015 Posted March 6, 2015 (On a sidenote, @@redsaurus, alphamod brushes? Are they related to the alpha brushes used for terrain blending? It sounds interesting either way and would want to play around with that).Yes, they're just the alpha brushes you use for terrain blending.
Bad Dancer Posted January 21, 2019 Posted January 21, 2019 It's possible to do this, but the solution isn't obvious - you draw them in reverse order. Let's call your 'background texture', texture A, and your scrolling texture, texture B. Stage 1: Draw texture B as usual, with default blendFunc and scrolly fun.Stage 2: Draw texture A, with blendFunc GL_ONE_MINUS_SRC_ALPHA GL_SRC_ALPHA Your scrolling texture get's drawn first, and is the destination texture for stage 2.In stage 2, you multiply texture A's RGB values by (1 - alpha of texture A). So where the alpha is white (1), you get texture A RGB * 0, so none of texture A is used, but then you add on texture B RGB * 1 (which is the full colour of texture B ). When the alpha is black (0), the opposite happens. You get the full colour of A, and none of B. It just takes experience and some creativity to figure out what to do with your blendFuncs but if you understand the basic concepts of how the blending works, then you should get there eventually Hi Xycaleth.Please write an example of this shader. (Two textures, one of which is an alpha mask).(The first texture should scroll, and the alpha channel of the second texture should make the first texture transparent or invisible near the edges, (depending on the alpha channel).) I need to get the following result:Texture1 (which will scroll).Texture2 Alpha Channel - (which will not scroll).Result.
AshuraDX Posted January 21, 2019 Posted January 21, 2019 Hi Xycaleth.Please write an example of this shader. (Two textures, one of which is an alpha mask).(The first texture should scroll, and the alpha channel of the second texture should make the first texture transparent or invisible near the edges, (depending on the alpha channel).) I need to get the following result:Texture1 (which will scroll).Texture2 Alpha Channel - (which will not scroll).Result.so you want to render only the white parts of the first texture with the alpha channel of the second texture?
Bad Dancer Posted January 22, 2019 Posted January 22, 2019 so you want to render only the white parts of the first texture with the alpha channel of the second texture?AshuraDX, Yes. I would like to get the result as on the third picture, (+ scrolling). If there are several ways to get a similar result, please write.(One texture moves, and the other texture does not move and makes that texture transparent or invisible in the right places.)For example, such a shader:The first texture. (Scroll, rotate ...) Has an image and an alpha channel. The light and dark parts of the image are displayed. The alpha channel of the first texture makes some places of the texture transparent or invisible.The second texture. (Does not scroll.) Has an alpha channel that makes the first texture transparent or invisible in some places.Texture1. Texture1-Alpha. Texture2-Alpha. Result.
AshuraDX Posted January 22, 2019 Posted January 22, 2019 @@Bad Dancer the first one is definitely possible, not sure about the second one. Here's a possible solution for the first shader: textures/example/texture{ { map textures/example/texture2 alphaFunc GE128 blendFunc GL_ONE GL_ONE depthWrite rgbGen identity } { map textures/example/texture1 alphaFunc GE128 blendFunc GL_ONE GL_ONE depthFunc equal tcMod scroll 0.25 0 }} For this to work your texture2 is expected to have all black RGB channels with your black and white alpha in the alpha channel. Texture1 does not need any alpha, it will appear transparent based on brightness. I did not have the time to try that shader yet, but it should work.
Bad Dancer Posted January 23, 2019 Posted January 23, 2019 @@Bad Dancer the first one is definitely possible, not sure about the second one. Here's a possible solution for the first shader: textures/example/texture{{map textures/example/texture2alphaFunc GE128blendFunc GL_ONE GL_ONEdepthWritergbGen identity}{map textures/example/texture1alphaFunc GE128blendFunc GL_ONE GL_ONEdepthFunc equaltcMod scroll 0.25 0}} For this to work your texture2 is expected to have all black RGB channels with your black and white alpha in the alpha channel. Texture1 does not need any alpha, it will appear transparent based on brightness. I did not have the time to try that shader yet, but it should work.Thank you! It really works. But there are two problems:1 - Very sharp edges of the Alpha Channel. (There is no smooth transition from white to black.)2 - Transparency of other effects. (Explosions, fire ...) When I look through this effect to other effects, they become transparent in those places where this effect should be transparent. I am very interested in solving these problems. Especially solving problem number 2.Can you help me with this?
AshuraDX Posted January 23, 2019 Posted January 23, 2019 In theory there is another method to achieve this that'd actually solve the issues you have with the current version.The problem is that it doesn't work on most graphics cards in the vanilla version of the game. I'm also not 100% sure if you can actually get the same visual result with this alteration. I'll dig into it later. Bad Dancer likes this
Bad Dancer Posted January 24, 2019 Posted January 24, 2019 Thank you, AshuraDX.I create some effects for the game, and this shader will help me a lot.My "Blood Sparks" effects. (This shader was not needed here, but for the other effects, I really need it.) https://youtu.be/Qp5AhBJeSDkhttps://youtu.be/XF5H1XBi9oQ https://youtu.be/ypd14OKgn-shttps://youtu.be/zo_SXnhhPu8 swegmaster, minilogoguy18, Psyk0Sith and 2 others like this
Bad Dancer Posted January 26, 2019 Posted January 26, 2019 In theory there is another method to achieve this that'd actually solve the issues you have with the current version.The problem is that it doesn't work on most graphics cards in the vanilla version of the game. I'm also not 100% sure if you can actually get the same visual result with this alteration. I'll dig into it later.I got some idea about this ... Maybe this idea is silly, but I dared to ask ... Maybe we need to add a texture 3 to this shader, with some settings? Then the alpha channel will only affect texture 2, and will not affect the transparency of other effects? P.S. This is my mercenary model.I create this model for Jedi Academy with Rend2 (GL2).I create weapons for this mercenary. For the effects of his weapon will also need that shader. Langerd likes this
RebelChum Posted January 26, 2019 Posted January 26, 2019 I seem to be having trouble with this lately as well. If I am trying to make a text decal, like a sign that says ARENA or something on a wall, that has an alpha transparent background, which blendfunc should I use that doesn't make the text like full bright? Maybe it's an issue with the lightmap function I have in my shader? textures/mapname/sign { qer_editorimage textures/mapname/sign polygonOffset q3map_nolightmap q3map_onlyvertexlighting { map textures/mapname/sign blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA } }
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now