GLSL gl_FragCoord.z计算和设置gl_FragDepth

时间:2012-04-22 03:21:52

标签: opengl glsl shader

所以,我有一个冒名顶替者(真正的几何体是一个立方体,可能被修剪,冒名顶的几何体是Menger海绵),我需要计算它的深度。

我可以相当容易地计算出在世界空间中偏移的数量。不幸的是,我花了好几个小时没有用它来扰乱深度。

我可以获得的唯一正确结果是我去的时候:

gl_FragDepth = gl_FragCoord.z

基本上,我需要知道如何计算gl_FragCoord.z以便我可以:

  • 从gl_FragCoord.z到眼睛空间的逆变换
  • 添加深度扰动
  • 将此扰动深度转换回与原始gl_FragCoord.z相同的空间。
如果这似乎是一个重复的问题,我道歉;这里有很多其他帖子可以解决类似问题。但是,在实现所有这些之后,没有一个正常工作。而不是试图选择一个来获得帮助,此时,我要求完整的代码来完成它。它应该只是几行。

2 个答案:

答案 0 :(得分:29)

以供参考,密码为:

float far=gl_DepthRange.far; float near=gl_DepthRange.near;

vec4 eye_space_pos = gl_ModelViewMatrix * /*something*/
vec4 clip_space_pos = gl_ProjectionMatrix * eye_space_pos;

float ndc_depth = clip_space_pos.z / clip_space_pos.w;

float depth = (((far-near) * ndc_depth) + near + far) / 2.0;
gl_FragDepth = depth;

答案 1 :(得分:5)

对于将来的另一个参考,这是与imallett给出的相同的公式,它在OpenGL 4.0应用程序中为我工作:

vec4 v_clip_coord = modelview_projection * vec4(v_position, 1.0);
float f_ndc_depth = v_clip_coord.z / v_clip_coord.w;
gl_FragDepth = (1.0 - 0.0) * 0.5 * f_ndc_depth + (1.0 + 0.0) * 0.5;

此处,modelview_projection是4x4模型视图 - 投影矩阵,v_position是正在渲染的像素的对象空间位置(在我的情况下由raymarcher计算)。

该等式来自window coordinatesthis manual部分。请注意,在我的代码中,附近是0.0,远是1.0,这是gl_DepthRange的默认值。请注意,gl_DepthRange perspective projection matrix公式中的近/远距离相同!唯一的诀窍就是使用0.01.0(或gl_DepthRange以防万一你确实需要更改它),我已经在另一个深度范围内挣扎了一个小时 - 但是那个已经在我的(透视)投影矩阵中“烘焙”了。

请注意,这样,等式实际上只包含一个乘以常数((far - near) / 2)和另一个常量((far + near) / 2)的相加。将它与imallett代码中所需的乘法,加法和除法(可能由优化编译器转换为乘法)进行比较。