1

如果您将不同的视图空间位置从顶点着色器传递给片段着色器,那么片段着色器可以知道片段相对于相机的位置(0,0,0在视图空间中)。这对于每像素照明等很有用。例如:

precision mediump float;
attribute vec3 vertex;
uniform mat4 pMatrix, mvMatrix;
varying vec4 pos;
void main() {
    pos = (mvMatrix * vec4(vertex,1.0));
    gl_Position = pMatrix * pos;
}

但是,如果您在顶点着色器中进行渲染gl_POINTS和设置gl_PointSize,片段着色器如何确定每个片段的位置(因为在pos上面的示例中传递的将是精灵的中心点)?

4

1 回答 1

2

简单的答案:停止使用点精灵。真的,他们太可怕了。

不太简单的答案:完全停止将视图空间位置传递给片段着色器。相反,用于gl_FragCoord根据视口数据等计算视图空间位置。甚至还有它的示例 GLSL 代码:

vec4 ndcPos;
ndcPos.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) /
    (gl_DepthRange.far - gl_DepthRange.near);
ndcPos.w = 1.0;

vec4 clipPos = ndcPos / gl_FragCoord.w;
vec4 eyePos = invPersMatrix * clipPos;

您需要为片段着色器提供viewportinvPersMatrix值。gl_DepthRange是内置的。eyePos就是你要找的。

可能有一种更快的方法可以利用您正在绘制屏幕对齐的四边形这一事实。这将涉及点大小和使用gl_PointCoord.

于 2013-02-22T03:59:30.313 回答