Shader学习09【Shader内置变量】

我们实际在Unity中使用的是Unity封装好的Shader,好处在于它提供了很多内置的参数,这使得我们不再需要自己手动计算一些值。本篇将给出Unity内置的用于空间变换和摄像机以及屏幕参数的内置变量,这些内置变量可以在UnityShaderVariables.cginc文件定义中找到说明

     UNITY_MATRIX_MVP    模型空间->裁剪空间

     UNITY_MATRIX_MV      模型空间->观察空间

     UNITY_MATRIX_V         世界空间->观察空间

     UNITY_MATRIX_P         观察空间->裁剪空间

     UNITY_MATRIX_VP       世界空间->裁剪空间

     UNITY_MARTIX_T_MV    UNITY_MATRIX_MV 的转置矩阵 

     UNITY_MATRIX_IT_MV     UNITY_MATRIX_MV 的逆转置矩阵,用于将法线从模型空间变换到观察空间,也可用于得到UNITY_MATRIX_MV的逆矩阵

     _Object2World   当前的模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间

     _World2Object   _Object2World的逆矩阵,用于将顶点/方向矢量从世界空间变换到模型空间

这其中有一个矩阵比较特殊,即UNITY_MATRIX_T矩阵,很多对数学不了解的读者不理解这个矩阵有什么用处,如果读者认真看过矩阵的知识,应该会记得一种非常吸引人的矩阵——正交矩阵,对于正交矩阵来说,它的逆矩阵就是转置矩阵,因此,如果UNITY_MATRIX_MV是一个正交矩阵的话,那么UNITY_MATRIX_T_MV就是它的逆矩阵,也就是说,我们可以使用UNITY_MATRIX_T_MV把顶点和方向矢量从观察空间变换到模型空间,那么问题是UNITY_MATRIX_MV什么时候是一个正交矩阵呢,读者可以从4.5节中找到答案,总结一下,如果我们只考虑旋转,平移,缩放这三种变换的话,如果一个模型的变换只包括旋转,那么UNITY_MATRIX_MV就是一个正交矩阵,这个条件似乎有些苛刻,我们可以条件再放宽一些,如果只包括旋转和统一缩放,那么UNITY_MATRIX_MV就几乎是一个正交矩阵了,为什么是几乎呢,因为统一缩放会导致每一行(或每一列)的矢量长度不为1,而是K,这不符合正交矩阵的特性,但我们可以通过除以这个统一缩放系数,来把它变成正交矩阵。在这种情况下,UNITY_MATRIX_MV的逆矩阵就是1/kUNITY_MATRIX_T_MV。而且,如果我们只是对方向矢量进行变换的话,条件可以放的更宽,即不用考虑有没有平移变换,如果我们只是对方向矢量进行变换的话,条件可以放的更宽,既不用考虑有没有平移变换,因为平移对方向矢量没有影响,因此,我们可以截取UNITY_MATRIX_MV的前三行前三列来把方向矢量从观察空间变换到模型空间,对于方向矢量,我们可以在使用前对它们进行归一化处理,来消除统一缩放的影响

      还有一个矩阵需要说明一下,那就是UNITY_MATRIX_IT_MV矩阵,我们在前面的文章中已经知道,发现的变换需要使用原变换颠的逆转置矩阵,因此UNITY_MATRIX_IT_MV可以把法线从模型空间变换到观察空间。但只要我们做一点手脚,它也可以用于直接得到UNITY_MATRIX_MV的逆矩阵——我们只需要对它进行转置就可以了,因此,为了把顶点或方向矢量从观察空间变换到模型空间,我们可以使用类似下面的代码:

     

 

摄像机参数

     Unity提供了一些内置变量来让我们访问当前正在渲染的摄像机的参数信息,这些参数对应了摄像机上的Camera组件中的属性值。表4.3给出了UNITY5.2版本的这些变量

     

 

    _WorldSpaceCameraPos   摄像机在世界空间中的位置

    _ProjectionParams     float4 (1,Near,Far,1+1/Far) 其中Near和Far分别是近裁剪平面和远裁剪平面和摄像机的距离

    _ScreenParams     float4(width,height,1+1/width,1+1/height) 其中Width 和height分别是该摄像机的渲染目标的像素宽度和高度

    _ZBufferParams     float4  (1-Far/Near,Far/Near,z=x/Far,w=y/Far)该变量用于线性化Z缓存中的深度值

    unity_OrthoParams        float4 (x=width,height,z,1)该摄像机是正交摄像机,或W=0.0,z没有定义,其中width和Height分别是正交投影摄像机的宽度和高度

    unity_CameraProjection float4*4 该摄像机的投影矩阵 

    unity_CameraInvProjection float4*4   该摄像机的投影矩阵的逆矩阵

    unity_CameraWorldClipPlanes[6]  float4   该摄像机的6个裁剪平面在世界空间下的等式,按如下顺序:左右下上近远裁剪平面

    

CG中的矢量和矩阵类型

    我们通常在Unity Shader中使用CG作为着色器编程语言,在CG中变量类型有很多种,但在本节我们是想解释如何使用这些类型进行数学运算,因此,我们只以float家族的变量来做说明。

    在CG中,矩阵类型是由float3*3,float4*4等关键词进行声明和定义的,而对于float3,float4等类型的变量,我们既可以把它当成一个矢量,也可以把它当成是一个1*n的行矩阵,或者一个n*1的列矩阵,这取决于运算的种类和他们在运算中的位置,例如,当我们进行点积操作时,两个操作数就会被当成矢量类型

 

      

 

 

     

posted @ 2021-07-20 18:49  专杀小三  阅读(212)  评论(0编辑  收藏  举报