Unity中从顶点着色器输出到片段着色器中间的顶点变换
上图来自《shader入门精要》,是渲染流水线中顶点的完整空间变换过程。
在顶点着色器中,主要完成了前三个阶段,即顶点坐标乘以MVP矩阵,把顶点变换到了裁剪空间中,然后作为顶点着色器的输出。
在顶点着色器到片元着色器中间,也就是裁剪空间到屏幕空间,是Unity自动帮我们完成的,但是这个过程不只有一个阶段。
变换到NDC空间
首先要把顶点变换到NDC空间,裁剪空间中,各个顶点的x,y,z分量的范围是【-w,+w】,因此首先进行了透视除法,把各个顶点从裁剪空间变换到了NDC空间,这时各个分量的取值范围为【-1,1】。
视口变换
之后,需要进行视口变换,把各个分量先乘以1/2,再加上1/2,这时各个分量的取值范围就变成了【0,1】,这里就是视口空间的坐标。
屏幕空间
把各个顶点的x,y值分别乘以屏幕的宽和高,就得到了顶点最终在屏幕空间的位置。
因此整个过程就是裁剪空间坐标=>NDC空间坐标=>视口空间坐标=>屏幕空间坐标
Unity Shader中的ComputeScreenPos
Shader中这个函数的输入是裁剪空间中的某个顶点坐标,但是输出的并不是视口空间中的坐标,视口空间坐标的范围是【0,1】,但是这个函数输出的范围是【0,w】,因此,在除以w之后,把范围映射到了【0,1】才得到了视口空间的坐标。
上图同样来自《shader入门精要》,注意除法要在片元着色器中进行。
Unity之所以不自动执行这个除法,首先是因为在顶点着色器中进行这个除法会影响插值,投影空间不是线性空间,在顶点着色器中计算x/w和y/w,顶点着色器到片元着色器中的插值就会影响这个结果,而保留x,y,w,经过插值之后再计算,结果就正确了。
另外一个原因是Unity希望你把该坐标值用作tex2Dproj指令的参数值,tex2Dproj会在对纹理采样前除以w分量。
这两种方法是等价的
tex2Dproj(_Tex, projCoord) == tex2D(_Tex, projCoord.xy / projCoord.w)
当我们需要采样某张屏幕空间的投影图时(深度图),后面是手动进行除法,效率没有前面的方法高。
标签:Unity,视口,坐标,空间,顶点,着色器 From: https://www.cnblogs.com/luoxiaozhu1998/p/17084624.html