使用着色器在opengl中绘制深度值

时间:2011-06-20 08:57:20

标签: opengl shader

我想在片段着色器中绘制深度缓冲区,我这样做:

顶点着色器:

varying vec4 position_;

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
position_ = gl_ModelViewProjectionMatrix * gl_Vertex;

片段着色器:

float depth = ((position_.z / position_.w) + 1.0) * 0.5;

gl_FragColor = vec4(depth, depth, depth, 1.0);

但我打印的都是白色的,我做错了什么?

2 个答案:

答案 0 :(得分:22)

你想在什么空间画出深度?如果要绘制窗口空间深度,可以执行以下操作:

gl_FragColor = vec4(gl_FragCoord.z);

但是,这不会特别有用,因为大多数数字都非常接近1.0。只能看到非常近的物体。这是使用标准透视投影的深度缓冲区深度值分布的性质。

或者,换句话说,这就是你变白的原因。

如果您想在线性空间中使用这些值,则需要执行以下操作:

float ndcDepth = ndcPos.z =
    (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) /
    (gl_DepthRange.far - gl_DepthRange.near);
float clipDepth = ndcDepth / gl_FragCoord.w;
gl_FragColor = vec4((clipDepth * 0.5) + 0.5); 

答案 1 :(得分:12)

实际上,片段的“深度”值可以从剪辑空间中的 z 值中读取(即,在所有矩阵变换之后)。这很正确。

但是,您的问题在于ww分区称为透视分割。是的,透视投影必须正常工作。

<强>然而即可。在这种情况下,w除以“汇总”所有值(如您所见),非常接近1.0。这有一个很好的理由:perspective projectionw= (some multiplier) *z。也就是说,您将z值(无论计算出来的是什么)除以原始z的(某个因子)。难怪你总是得到接近1.0的值。你几乎把z分开了。

作为一个非常简单的解决方法,请尝试将z除以farPlane,然后将其作为深度发送到片段着色器。

顶点着色器

varying float DEPTH ;

uniform float FARPLANE ;  // send this in as a uniform to the shader

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
DEPTH = gl_Position.z / FARPLANE ; // do not divide by w

片段着色器:

varying float DEPTH ;
// far things appear white, near things black
gl_Color.rgb=vec3(DEPTH,DEPTH,DEPTH) ;

结果是一种不坏的,非常线性的淡化。

enter image description here