I am making a program which renders terrain in two separate passes, with an intermediate clearing of depth in between (there is no way to change this requirement). In the first pass I render the skybox and terrain really far away using depth testing. I clear the depth buffer bits to 1.0. Then, I render all my close terrain with depth testing as well. So the code looks something like this:
// My State
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
glClearColor(0, 0, 0, 0);
glClearDepth(1.0);
// Pass 1
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawSkybox();
DrawFarTerrain();
// Pass 2
glClear(GL_DEPTH_BUFFER_BIT);
DrawNearTerrain(); // IMPORTANT: All done in one draw command
The following images show the color values and depth (white = 1.0) at the end of each pass:
Pass 1
Pass 2

As you can see, within that single draw command for the second pass, the pixel values are being written in the depth buffer, but the color buffer is only partially written. The white area causes some weird problem.
According to GDebugger, this was my state during that draw command:
Can anyone tell me what is going on? I feel like the GPU is gaslighting me.
EDIT:
Well, I talked to someone who encountered an error like this and I resolved the problem in the process.
It turns out that everything in the white part at the end of the first pass is not white, but NaN in reality. GDEBugger displays the values as (255, 255, 255, 255) because it must not have support for displaying any other texture formats. It just says: "NaN, you must mean white :P".
Well, why does NaN matter if we are doing pixel replacement - glBlendFunc(GL_ONE, GL_ZERO). It's because operations on NaN still result in NaN the whole way down through the pipeline. The GL implemention still performs the "Result = SourceFactor * Source + DestFactor * Dest" - no optimizations are performed.
In regards to the fix... it turns out that performing "outFragColor = clamp(outFragColor , vec4(0.0), vec4(3000000000000.0))" in the fragment stage (outFragColor is the pixel return value) will not result in a NaN even though outFragColor contains NaNs. Go figure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With