GLSL从相机获取像素特定的距离?

时间:2021-03-28 00:12:57

标签: rendering webgl linear-algebra

我试图在顶点着色器中获取绘制到画布的每个像素的距离。顶点着色器代码如下:

attribute vec4 modelVertexPosition;

// cameraMatrix is strictly used as a ref to the camera's position in this case
// and does not contribute to the screen projection position calculation
uniform mat4 cameraMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;

varying float cameraDistance;

void main(void) {
  // calc world position of vertex
  vec4 vertexPosition = modelMatrix * modelVertexPosition;
  // calc frustum position of vertex
  vec4 projVertexPosition = projectionMatrix * vertexPosition;
  gl_Position = projVertexPosition;
  // set cameraDistance varying for fragment shader
  cameraDistance = distance(cameraMatrix[3].xyz, (modelMatrix * scaledModelVertexPosition).xyz);
}

这适用于严格在所绘制三角形顶点上的所有点,但很明显 glsl 正在相对于它们的顶点线性插入三角形内点的距离。这通常不是什么大问题,但是当相机比顶点更靠近三角形的中间时,它会特别明显。

为了演示这个问题,我设置了片段着色器以将形状的亮度设置为该点与相机的距离的函数,越暗越近。我设置了一个暴露实现方法缺陷的情况如下所示: https://github.com/versatica/mediasoup-demo

所以这就引出了一个问题,有没有办法获得每个像素距离相机的位置?

2 个答案:

答案 0 :(得分:0)

免责声明:我对 OpenGL 框架还是很陌生,实际上我只是在试验 WebGL 的淡化版本,所以对我的解决方案持保留态度。另外,如果有人有更好的方法,我会全神贯注。

无论如何,我发现只有片段着色器能够进行单个像素计算。相反,顶点着色器通过计算每个顶点的着色器的所有输出,然后使用插值来估计顶点之间的所有像素的输出,从而假设顶点之间的所有像素。

考虑到这一点,只需移动计算从相机到片段着色器距离的代码,就可以在每个像素的基础上完成计算,这就是我在这种情况下想要的效果。但是我假设这种方法效率要低得多,所以这种方法应该只在绝对必要时使用(据我估计)。

同样,如果有人对这个话题有更深入的了解,请加入。我们非常欢迎批评。

答案 1 :(得分:0)

片段与相机的距离与其在深度缓冲区中的深度有关。您可以按如下方式在片段着色器中计算深度:

float depth = gl_Position.z / gl_Position.w;

可见片段的深度从 0 到 1 不等,0 表示近剪裁平面,1 表示远剪裁平面。您可以使用以下公式计算与相机的距离:

depth = (1/camera_distance - 1/near)/(1/far - 1/near)

请注意,深度和相机距离不是线性相关的。相反,深度与 1/camera_distance 线性相关。 OpenGL 等使用相机距离的倒数来定义“深度”,因此硬件可以对屏幕空间中的三角形进行“深度”的线性插值,以快速确定透视图中每个像素处可见的三角形。 >

相关问题