Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL Full Depth With Partial Color Write

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 1 Color Pass 1 Depth Pass 2 Pass 2 Color Pass 2 Depth

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:

  • GL_BLEND: TRUE
  • GL_BLEND_EQUATION_ALPHA: GL_FUNC_ADD
  • GL_BLEND_EQUATION: GL_FUNC_ADD
  • GL_BLEND_EQUATION_RGB: GL_FUNC_ADD
  • GL_BLEND_DST: 0
  • GL_BLEND_DST_ALPHA: 0
  • GL_BLEND_DST_RGB: 0
  • GL_BLEND_SRC: 1
  • GL_BLEND_SRC_ALPHA: 1
  • GL_BLEND_SRC_RGB: 1
  • GL_DEPTH_FUNC: GL_LESS
  • GL_DEPTH_TEST: TRUE
  • GL_STENCIL_FUNC: GL_ALWAYS
  • GL_STENCIL_TEST: FALSE
  • GL_BLEND_COLOR: {0, 0, 0, 0}

Can anyone tell me what is going on? I feel like the GPU is gaslighting me.

EDIT:

  • I currently have one GL Context that is alive.
  • My card is an Intel HD 4000 with the latest drivers running on an Intel i7 with 8 GB RAM.
  • MY FBO's color attachment has an internal format of GL_RGBA16F and the depth attachment is GL_DEPTH_COMPONENT32F.
  • Stencil testing is never used.
like image 703
Darth Zaloj Avatar asked Mar 19 '26 08:03

Darth Zaloj


1 Answers

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.

like image 197
Darth Zaloj Avatar answered Mar 21 '26 23:03

Darth Zaloj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!