Thorsten wrote in Mon Jan 11, 2016 12:50 pm:I am however starting to get the impression that some parts/operations in common to many shaders that could be shifted out of this and into FGLight::update() and encoded directly into the GL light source settings.
The function called is indeed the same for many shaders and all pixels, but the values in the function call are different for every pixel.
The reason I put light computations to the shader in the first place is that doing it on the CPU is insufficient.
That's true. But do all mathematical lighting operations -absolutely all- need to be per pixel per frame? Surely some base computational operations do not need to be run at this frequency. Have you considered shifting anything in the ALS framework from the shader into a much lower frequency updated CPU operation? For example calculating the moon lighting intensity once per second is perfectly fine - this looks very smooth in sim. Hence my current code does this on the CPU in non-FPS limiting code paths, and not GPU (also allowing this to be shared with the default renderer and Rembrandt, once I hook it up). Though this may become noticeable when I start modelling moonrises and moonsets when the sun zenith > 115 deg.
Is ALS not in any way already bound by the GL light source, which is updated - position and settings - once a second?
It is, and watching the terminator during a sunrise in the tropics where the sun moves fast, you see it.
I have the following in my ~/.bashrc file:
- Code: Select all
alias fgfs_tropical_sunset="fgfs --aircraft=ufo --altitude=100 --lat=0 --lon=0 --timeofday=dusk"
Do you mean the gradient lines in the sky that move and tick like clockwork? I thought about it but I haven't seen a way to send an OpenGL light source on a smooth trajectory.
All rendering pipelines should aim to follow the real life illumination models, so there will be many common illumination concepts.
I guess I disagree. I'm not attached to any particular illumination model but to what looks most realistic. For instance, it by and large makes no sense to render a specular channel for our terrain, because while the triangles are nominally flat, the real terrain they're supposed to represent is not. Allowing a specular channel gives you bad results then. It makes no sense to render much directional light on trees, because while the quads are flat, the tree they're supposed to represent is a complex arrangement of leaves pointing in all directions and being partially translucent. So whether a surface of the quad is nominally shaded is a bad proxy for whether the tree would be shaded.
If 'the usual way' doesn't work for me, I do it differently. The whole point of programmable shaders is to allow this freedom and go away from operations and model assumptions hard coded by the GPU manufacturer.
I'm not disagreeing with your general approach here, but I strongly suspect the directional moonlight needs a custom job in ALS shader by shader to mesh with the rest.
Which still is worth doing I think.
I know that we will need to customise the shaders one-by-one, and ALS will be rather special. However I do intend to set ambient, diffuse and specular values on the GL light source number 0 for the moonlight and have this updated on the CPU once per second. This can then be used as needed in the shaders. It will remove the need for reading the value of "/environment/moonlight", and I suspect that pulling it out of gl_LightSource[0].ambient, gl_LightSource[0].diffuse, and gl_LightSource[0].specular will be much quicker that accessing the property tree. I also intend to shift the following repetitive shader operation onto the CPU side:
- Code: Select all
vec3 moonLightColor = vec3 (0.095, 0.095, 0.15) * moonlight;
The value of moonlight is updated via "/environment/moonlight" once per second, so the vector operation can benefit from also running at this non-FPS critical frequency. The resultant vector can be encoded into gl_LightSource[0].ambient for the shader to read. I still have a lot to investigate. For example gl_LightSource[0].ambient is used in some ALS shaders. But this value is multipled by _fog_color in the FG Viewer. But _fog_color is multiplied by the square of sky_brightness. But at night, sky_brightness in $FG_ROOT/Lighting/specular is zero for sun zenith angles > 115 degrees. I have to look at all these algorithms and what is in the end used in the default and ALS shaders. There are a few ALS shaders which appear to use the resultant ambient light value:
- Code: Select all
[edward@localhost Shaders (directional_moonlight)]$
BRANCH: directional_moonlight (cce6c58) / 3 uncommitted changes
$ grep "gl_LightSource\[0].ambient" *ALS*
building-model-ALS-ultra.vert: * (gl_LightModel.ambient + gl_LightSource[0].ambient);
model-ALS-ultra.frag: //vec4 ambient = gl_LightModel.ambient + gl_LightSource[0].ambient;
model-ALS-ultra.vert: * (gl_LightModel.ambient + gl_LightSource[0].ambient);
model-ALS-wingflex-organic.vert: * (gl_LightModel.ambient + gl_LightSource[0].ambient);
space-ALS-ultra.vert: * (gl_LightModel.ambient + gl_LightSource[0].ambient);
In any case, the inconsistencies between all the shaders means that this will take a long time to properly integrate. I'm starting to wonder if I should make FGLight::update() ALS-aware so that the fog-handling can be made rendering pipeline specific.
Regards,
Edward