您可以使用模板緩衝區來做到這一點。
我還沒有編譯的代碼,它會需要修改,但是這是總體思路:
glDisable(GL_STENCIL_TEST);
<Render rest of scene (everything other than the spheres and cylinder)>
// Render the larger sphere into the stencil buffer, setting stencil bits to 1
glEnable(GL_STENCIL_TEST);
glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Don't render into the color buffer
glDepthMask(GL_FALSE); // Don't render into the depth buffer
glStencilMask(0xff); // Enable writing to stencil buffer
glStencilFunc(GL_ALWAYS, 1, 0xff); // Write 1s into stencil buffer
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // Overwrite for every fragment that passes depth test (and stencil <- GL_ALWAYS)
<Render big sphere>
// Render the smaller sphere into the stencil buffer, setting stencil bits to 0 (it carves out the big sphere)
glStencilFunc(GL_ALWAYS, 0, 0xff); // Write 0s into stencil buffer
<Render small sphere>
// Render the cylinder into the color buffer, only where the stencil bits are 1
glStencilMask(0); // Don't need to write to stencil buffer
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Render into the color buffer
glStencilFunc(GL_EQUAL, 1, 0xff); // Only render where there are 1s in the stencil buffer
<Render cylinder>
glDisable(GL_STENCIL_TEST);
// Now render the translucent big sphere using alpha blending
<Render big sphere>
我有一個問題:我認爲有些事情稍微偏離與您建議的代碼。讓我解釋一下我對代碼的理解,並讓我知道這是否是一種不正確的理解: – brohan322
因此,您首先清除緩衝區並在任何地方寫入1。然後覆蓋通過深度測試的地方並替換這些值(順便說一句,用什麼替代?)。然後你爲第二個球體寫0。然後在任何有1秒的地方,圓柱體被拉出,對嗎? – brohan322
我將您的代碼從GL_REPLACE更改爲GL_ZERO。這不是更有意義嗎?如果深度測試通過(在我的情況下,如果一個片段通過深度測試,它將位於大球體之外),並且模板測試通過(它總是這樣做),我不應該使這些值0在緩衝區中? – brohan322