GLSL gl_FragCoord.z计算和设置gl_FragDepth

ima*_*ett 21 opengl shader glsl

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

我可以相当容易地计算出在世界空间中抵消的金额.不幸的是,我花了好几个小时没有用它来扰乱深度.

我能得到的唯一正确结果是我去的时候:

gl_FragDepth = gl_FragCoord.z
Run Code Online (Sandbox Code Playgroud)

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

  • 从gl_FragCoord.z到眼睛空间进行逆变换
  • 添加深度扰动
  • 将这个扰动的深度转换回与原始gl_FragCoord.z相同的空间.

如果这似乎是一个重复的问题,我道歉; 这里有很多其他帖子可以解决类似问题.但是,在实现所有这些之后,没有一个正常工作.而不是试图选择一个来获得帮助,此时,我要求完整的代码来完成它.它应该只是几行.

ima*_*ett 32

供将来参考,关键代码是:

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;
Run Code Online (Sandbox Code Playgroud)


the*_*ine 7

对于将来的另一个参考,这是与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;
Run Code Online (Sandbox Code Playgroud)

这里modelview_projection是4x4模型视图 - 投影矩阵,v_position是被渲染像素的对象空间位置(在我的例子中由raymarcher计算).

该等式来自本手册窗口坐标部分.请注意,在我的代码中,near 和far是,默认值是.请注意,是不是同样的事情在公式中的近/远的距离为透视投影矩阵!唯一的技巧是使用和(或者如果你真的需要改变它),我已经在另一个深度范围内挣扎了一个小时 - 但这已经在我的(透视)投影矩阵中"烘焙"了.0.01.0gl_DepthRangegl_DepthRange0.01.0gl_DepthRange

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