我正在尝试相对于对象计算深度。
这是一个很好的解决方案来检索深度相对于< strong>相机:Depth as distance to camera plane in GLSL
varying float distToCamera;
void main()
{
vec4 cs_position = glModelViewMatrix * gl_Vertex;
distToCamera = -cs_position.z;
gl_Position = gl_ProjectionMatrix * cs_position;
}
使用此示例,深度相对于相机。
但我希望获得相对于对象的深度。如果我离物体很近或者我很远,我想要相同的深度和价值。
这是我想要实现的一个例子。在左侧,您可以看到深度相对于相机。在右侧,即使相机从物体向后移动,深度也保持不变,因为它依赖于物体。
答案 0 :(得分:3)
从片段到相机的距离始终依赖到相机的位置。如果价值不是常数,那么就不可能使价值保持不变。
我建议你重新修改你正在开发的内容的要求。你必须自己澄清你需要的深度,它似乎并不依赖于相机的位置。
我建议你考虑引入一个平面,这将是计算深度的参考。指定平面在空间中的位置的参数可以作为制服传递到着色器。
如何计算从点到平原的距离?深度可以计算为从片段垂下的垂直平面的长度。让我们在平面上有一个任意点 p ,在该平面上有一个正常的 n 。 距离是:
d = dot(f,n) - dot(p,n)
其中 f - 片段的位置。
进行此计算的简单着色器如下所示:
uniform vec3 u_point;
uniform vec3 u_normal;
uniform float u_unitLength;
varying vec4 v_worldPosition;
void main( void )
{
float refPoint = dot(u_point, u_normal);
float testPoint = dot(v_worldPosition.xyz, u_normal);
float depth = testPoint - refPoint;
vec3 color = vec3(depth / u_unitLength);
gl_FragColor = vec4( color, 1.0 );
}
您应该知道,您需要将从顶点着色器变为 v_worldPosition 的片段位置传递到片段着色器。我为了演示写了一个简单的example。
可以进行一些优化。您可以不在着色器中执行 dot(p,n),但预先计算它。有关详细信息,请阅读this。
因此,最好以一般形式传递平面方程的系数,而不是以点 - 正规形式传递。优化的着色器将是:
uniform vec4 u_abcd;
uniform float u_unitLength;
varying vec4 v_worldPosition;
void main( void )
{
float depth = dot(u_abcd.xyz, v_worldPosition.xyz) + u_abcd.w;
vec3 color = vec3(depth / u_unitLength);
gl_FragColor = vec4( color, 1.0 );
}
使用优化着色器的example。
您可以使用相机旋转平面,但将其保持与物体相同的距离。有一个example。结果就像您在gif动画中演示的那样。
答案 1 :(得分:2)
我相信你所追求的是相对于物体的深度,而不是相机。要找到距物体原点的眼距Z ...
vec4 esVert = glModelViewMatrix * gl_Vertex;
vec4 esObjOrigin = glModelViewMatrix * vec4(0,0,0,1);
distToCamera = -esVert.z;
distToOrigin = -esObjOrigin.z;
originToVertexZ = distToOrigin - distToCamera;
现在,originToVertexZ
相对于物体的位置而不是相机,因此除非您旋转相机,否则它不会改变。
眼睛空间原点距离esObjOrigin.z
可以预先计算并传入(避免额外的矩阵乘法)。即在应用程序代码中计算-(glModelViewMatrix * vec4(0,0,0,1)).z
并将其作为统一变量传递。
根据应用程序的不同,您可能需要预先计算边界球,为originToVertexZ
提供已知的上限和下限。例如,如果您始终希望示例中显示平滑的零到一转换,请查找bounds=max(length(vertex)) for each vertex in the object
然后normalizedZ = 0.5*originToVertexZ/bounds+0.5
。