330
edits
No edit summary |
(ALS Landing-Spotlight effects and fragment shader documentation wrapup) |
||
Line 666: | Line 666: | ||
texel color - what is the base color of the pixel fully lit and unfogged | texel color - what is the base color of the pixel fully lit and unfogged | ||
lighting - how is this color changed by the light falling onto that pixel, usually the relation is something like fragColor equals texel | lighting - how is this color changed by the light falling onto that pixel, usually the relation is something like fragColor equals texel * light | ||
fogging - how much is the color hidden by haze, usually the relation is something like gl_FragColor | fogging - how much is the color hidden by haze, usually the relation is something like gl_FragColor equals mix(fragColor, hazeColor, transmission_factor); | ||
what is displayed on the screen in the end is whatever gl_FragColor is set to | what is displayed on the screen in the end is whatever gl_FragColor is set to | ||
But the location where this happens isn't always obvious - often (part) of the light is computed in the vertex shader already, in which case it typically enters the fragment shader as gl_Color. | But the location where this happens isn't always obvious - often (part) of the light is computed in the vertex shader already, in which case it typically enters the fragment shader as gl_Color. | ||
So, the lighting equation in tree-haze.frag is indeed | So, the lighting equation in tree-haze.frag is indeed | ||
vec4 fragColor equals vec4 (gl_Color.xyz,1.0) | vec4 fragColor equals vec4 (gl_Color.xyz,1.0) * texel; | ||
and your change to the light should happen just before that. But you can't do | and your change to the light should happen just before that. But you can't do | ||
gl_Color.rgb equals gl_Color.rgb | gl_Color.rgb equals gl_Color.rgb + my_light; | ||
because gl_Color.rgb is a varying variable type, and you can't assign new values to them inside the shader, so you need to either make a new variable or just do | because gl_Color.rgb is a varying variable type, and you can't assign new values to them inside the shader, so you need to either make a new variable or just do | ||
vec4 fragColor equals vec4 ((gl_Color.rgb | vec4 fragColor equals vec4 ((gl_Color.rgb + my_light),1.0) * texel; | ||
(note that color.rgb is the same as color.xyz, GLSL doesn't really care which convention you use, but I took a few months to learn that, so early code by myself often uses xyz indexing convention for color vectors as well).<ref>{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&t=24226&start=15#p220075 | (note that color.rgb is the same as color.xyz, GLSL doesn't really care which convention you use, but I took a few months to learn that, so early code by myself often uses xyz indexing convention for color vectors as well).<ref>{{cite web |url=http://forum.flightgear.org/viewtopic.php?f=47&t=24226&start=15#p220075 | ||
|title=ALS landing lights | |title=ALS landing lights | ||
Line 713: | Line 713: | ||
{{cquote|So, in old times when rendering textures was slow and complicated, we rendered objects with monochromatic surface colors. Then the (schematic) lighting equation (without specular, and the sum of ambient and diffuse already computed) was | {{cquote|So, in old times when rendering textures was slow and complicated, we rendered objects with monochromatic surface colors. Then the (schematic) lighting equation (without specular, and the sum of ambient and diffuse already computed) was | ||
visibleColor.rgb | visibleColor.rgb equals objectColor.rgb * light.rgb + objectEmissive.rgb | ||
Now, we have textures and so we get | Now, we have textures and so we get | ||
visibleColor.rgb | visibleColor.rgb equals objectColor.rgb * texel.rgb * light.rgb + objectEmissive.rgb + lightMapTexel.rgb | ||
Since we can have the full color information in the texture, objectColor.rgb is usually (1.0,1.0,1.0) because the info is redundant. But if you don't use a texture, of course objectColor.rgb has the actual color value (incidentially, I think we shouldn't texture with monochromatic surfaces at all, it creates a jarring visual impression which can be cured by using even a small texture...) | Since we can have the full color information in the texture, objectColor.rgb is usually (1.0,1.0,1.0) because the info is redundant. But if you don't use a texture, of course objectColor.rgb has the actual color value (incidentially, I think we shouldn't texture with monochromatic surfaces at all, it creates a jarring visual impression which can be cured by using even a small texture...) | ||
But if you do, the rendering pipeline is set up to compute color.rgb | But if you do, the rendering pipeline is set up to compute color.rgb equals objectColor * light.rgb in the vertex shader, so the equation we have in the fragment shader is something like | ||
visibleColor.rgb | visibleColor.rgb equals color.rgb * texel.rgb + objectEmissive.rgb + lightMapTexel.rgb | ||
and if we add a secondary light like | and if we add a secondary light like | ||
visibleColor.rgb | visibleColor.rgb equals (color.rgb + secLight.rgb) * texel.rgb | ||
it of course can never recover the color information, because color.rgb is zero at night since you multiplied the actual color with zero sunlight and the texel doesn't carry information for an untextured object. | it of course can never recover the color information, because color.rgb is zero at night since you multiplied the actual color with zero sunlight and the texel doesn't carry information for an untextured object. |
edits