我正在使用WebGL绘制简单的平截头体几何。我试图给正面上色 (较小)和背面(较大)表面为红色,侧面为白色。
这是它的外观。请注意,较小的表面距离眼睛较近,较大的表面距离眼睛较远。不要被这张图片所迷惑。看起来着色器选择为眼睛最靠近的侧面着色,而忽略了正面朝上的脸。
我应该如何使其正常工作?
以下是我的着色器设置: 深度缓冲区在初始化期间被清除,并且从未使用过。
function init(){
// Retrieve <canvas> element
var canvas = document.getElementById('webgl');
// Get the rendering context for WebGL
gl = getWebGLContext(canvas);
if (!gl) {
console.log("lib1.js: init() failed to get WebGL rendering context 'gl'\n");
console.log("from the HTML-5 Canvas object named 'canvas'!\n\n");
return;
}
// Initialize shaders
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('lib1.js: init() failed to intialize shaders.');
return;
}
bufferSetup(gl);
// Set the background-clearing color and enable the depth test
gl.clearColor(0.0, 0.0, 0.0, 1.0); // black!
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE); // draw the back side of triangles
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}
感谢Denis指出这一点!我还尝试打开和关闭gl.CULL_FACE
,并尝试了gl.BACK
和gl.FRONT
。它们都无法正常工作。
gl.disable(gl.CULL_FACE);
// gl.cullFace(gl.BACK)
答案 0 :(得分:0)
我们知道CVV坐标系,未变换的绘图轴 (CVV ==规范视图体积,即我们在屏幕上描绘的+/- 1立方体体积) 坐标为RIGHT-HANDED,原点位于CVV立方体的中心,x向右增加,y向上增加,z向外增加, 对你的眼睛。但是,我们不必将CVV中具有更大,更正Z深度的片段绘制为“更近”,并且在同一屏幕位置将具有更小,更负Z的片段重叠。为什么?
WebGL(以及OpenGL-ES和OpenGL)在3D绘图的其他方法中有一个历史古怪:它将“深度”定义为0.0到1.0之间的计算值,而不仅仅是{{1 }}值在CVV坐标中。
默认情况下,WebGL将深度定义为:
z
)z = +1
)尽管GPU自动计算深度,但正确的结果需要通过3D相机投影矩阵转换的顶点来模仿相机镜头。有时,如果我们未定义或使用投影矩阵,则GPU深度计算将减少为:
z = -1
换句话说,如果没有这个“相机投影”矩阵,GPU将会计算
向后“深度”-顶点depth = 0.5 + 0.5*(gl_position.z / gl.position.w);
应该为1时,深度为0。有关GPU如何计算深度的更多详细信息,请参见:
How does WebGL set values in the depth buffer?
知道这一点,我们可以通过以下任一方法轻松解决此问题:
at z = -1
的符号,如下所示:z
;
然后,我们计算的所有myMatrix.setScale(1,1,-1)
值都将具有反向符号。
(当与复杂的场景图结合使用时,会有些混乱……)。z
的值保持不变,而是告诉WebGL
为使用深度缓冲区应用不同的规则;那是一个更明智的解决方案。尝试添加这些代码行z
向我的教授讲授计算机图形学-John E. Tumblin