ComputeScreenPos,裁剪空间齐次坐标转换到屏幕空间的齐次坐标

作用:

把裁剪空间齐次坐标转换到屏幕空间的齐次坐标

原理:

裁剪空间下的齐次坐标,x和y的取值范围是[-w, w], w=-z。

而屏幕空间下的齐次坐标取值范围是[0, w], w=-z。所以核心代码就是 float2 screenPos = (clipPos.xy + clipPos.w) / 2;

最后通过透视除法之后xy的取值范围就是[0, 1]了。一般用来提取屏幕纹理

源码:

其中在DirectX下屏幕坐标的原点在左上角,所以需要翻转Y坐标,此时_ProjectParams.x变量为-1。另外,在使用Direct3D9时,它会注意纹理对齐。在进行单遍立体渲染时,还需要特殊的逻辑。

用法:

在顶点着色器或者片元着色器调用:float4 screenPos = ComputeScreenPos(ClipPos);

在片元着色器用来提取纹理像素:

tex2D(_ScreenTex, float2(screenPos.xy / screenPos.w))

或者

tex2Dproj(_ScreenTex, screenPos); // 该函数会自动把screenPos通过齐次除法(透视除法)转换成普通坐标之后再对纹理进行采样

用ComputeScreenPos的结果,进行透视除法后,再乘以_ScreenParams.xy(xy分别是宽、高)后(即(screenPos.xy / screenPos.w) * _ScreenParams.xy),则可以得到真正的屏幕坐标

需要注意的是screenPos透视除法这一步不能在顶点着色器中使用,透视除法之后会导致片元函数中插值结果错误。

如下图:

时候先看一下正确的情况:

现有顶点a和b,齐次裁剪坐标(clipPos),在光栅化线性插值之后,在片元着色器得到一簇片元即ab线段上的所有片元,然后进行透视除法,则得到cb线段上的投影点,此时的z值对应的,则是db曲线,。即a点对应c点,a下面的点对应c右边的点。这是正确的

若在顶点着色器进行透视除法

现有顶点a和b,在顶点着色器进行透视除法,则得到c点和b点,然后通过线性插值,在片元着色器中的到cb上的所有片元,此时得到的z值则对应db直线,即a点对应c点,a下面的点对应c右边的点,这是错误的,正确的点应该更靠近c一点。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值