Cg 顶点着色器的坐标输出
文章此处说:
用 x、y 和 z 除以 w 即可实现此目的。得到的坐标 称为标准化设备坐标。现在所有可见的 几何数据位于立方体中,其位置在<-1,-1,-1>之间。和 <1,1,1>在 OpenGL 中,在 <-1, -1, 0> 之间<1,1,1>在 Direct3D。
这给跨平台着色器带来了一个问题,因为跨平台着色器出于某种特定原因想要测试 Z 坐标。有没有办法让 Z 坐标保持在相同的范围内,而不管平台如何?
The article here says:
Dividing x, y, and z by w accomplishes this. The resulting coordinates
are called normalized device coordinates. Now all the visible
geometric data lies in a cube with positions between <-1, -1, -1> and
<1, 1, 1> in OpenGL, and between <-1, -1, 0> and <1, 1, 1> in
Direct3D.
This raises a problem for cross-platform shaders which want to test the Z coordinate for some specific reason. Is there a way to get a Z coord in the same range, regardless of platform?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有趣的问题,但我怀疑它是否可以实现,因为视口转换仍然是固定功能的。
首先想到的是使用
glDepthRange
(或其可能的 D3D 对应物)将映射从 NDC z 更改为深度。但这是行不通的,因为将 [-1,1] 传递给glDepthRange
只会将其限制为 [0,1],并且您也不能在 D3D 中将其设置为 [0.5,1],因为在此之前,所有内容仍将根据 [0,1] 进行裁剪。但我不认为你经常需要它,因为在片段/像素着色器中你会得到具有标准化 [0,1] 深度的窗口坐标(我希望 Cg 的行为与 GLSL 类似)。在顶点着色器中,您更经常需要世界或视图空间深度,而不是 NDC z。如果您确实需要它,您可以根据着色器中的预处理器定义做出决定。
Interresting question, but I doubt that it's achievable, since the viewport transformation is still fixed-function.
The first thing that comes to mind is to use
glDepthRange
(or its possible D3D counterpart) to change the mapping from NDC z to depth. But this won't work, since passing [-1,1] toglDepthRange
will just clamp it to [0,1] and neither can you set it in D3D to [0.5,1], since before that everything will still be clipped against [0,1].But I don't think you need it too often, since in the fragment/pixel shader you get window coordinates with a normalized [0,1] depth (I expect Cg to behave similar to GLSL here). And in the vertex shader you would more often need the world or view space depth anyway, instead of the NDC z. If you really need it you may just base the decision on a preprocessor definition in the shader.
通常避免使用 NDC 空间的非线性 z/w 值。通常通过附加变量传递绝对顶点 Z 距离来实现此目的。这样东西就可以保持便携。
Using the nonlinear z/w value of NDC space is normally avoided. One normally does this by passing the absolute vertex Z distance by an additional varying. That way things stay portable.
您在哪里进行您想要进行的 Z 测试?
如果您在片段着色器中执行此操作,则不必关心。
gl_FragCoord.z
或任何与此等效的 Cg 都位于窗口空间中。窗口空间Z范围由glDepthRange定义;默认情况下,它从 0 到 1。如果您在顶点着色器中进行此测试,那么您将不得不忍受它。更好的测试可能是在相机空间而不是剪辑空间或 NDC 空间中进行。至少那时,您通常要处理世界范围内的距离。
Where are you doing this testing of Z that you want to do?
If you're doing it in the fragment shader, then you shouldn't care.
gl_FragCoord.z
or whatever Cg's equivalent to this is in window-space. The window-space Z extent is defined byglDepthRange
; by default, it goes from 0 to 1.If you're doing this test in the vertex shader, then you'll just have to live with it. A better test might be one done in camera space, rather than clip-space or NDC space. At least then, you're usually dealing with world-sized distances.