ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Unity Shader内置矩阵之美

2019-08-20 16:43:37  阅读:457  来源: 互联网

标签:之美 法线 裁剪 矩阵 unity Shader 相机 Unity 空间


原文链接:https://gameinstitute.qq.com/community/detail/127405

mul函数

 

mul函数,Z = mul(M, V)是表示矩阵M和向量V进行点乘,得到一个向量Z,这个向量Z就是对向量V进行矩阵变换后得到的值。

 

特别需要注意的是,例如normal是float3类型的,点乘的矩阵也要转换成float3x3。

float3 normal=mul((float3x3)UNITY_MATRIX_IT_MV,v.normal);  

 

矩阵

 

内置的矩阵(float4x4):

1、这里要特别说明一下UnityObjectToClipPos(v.vertex)) 方法,官方网站上说明,编写着色器脚本时,请始终使用UnityObjectToClipPos(v.vertex)而不是mul(UNITY_MATRIX_MVP,v.vertex),因为所有内建的矩阵名字在Instanced Shader中都是被重定义过的,如果直接使用UNITY_MATRIX_MVP,会引入一个额外的矩阵乘法运算,所以推荐使用UnityObjectToClipPos / UnityObjectToViewPos函数,它们会把这一次额外的矩阵乘法优化为向量-矩阵乘法。

 

2、UNITY_MATRIX_IT_MV的使用场景,专门针对法线进行变换。但是为什么法线的变换和顶点不一样呢?

 

之所以法线不能直接使用UNITY_MATRIX_MV进行变换,是因为法线是向量,具有方向,在进行空间变换的时候,如果发生非等比缩放,方向会发生偏移。为什么呢?举个栗子,我们可以简单的把法线和切线当成三角形的两条边,显然,三角形在空间变换的时候,不管是平移,还是旋转,或者是等比缩放,都不会变形,但是如果非等比缩放,就会发生拉伸。所以法线和切线的夹角也就会发生变化。(而切线在变换前后,方向总是正确的,所以法线方向就不正确了)。下图,T、T'是切线,N、N'是法线

 

经过非等比缩放后

 

3、UnityObjectToWorldDir() 与 UnityObjectToWorldNormal()的区别

 

第一个原图,红色箭头表示法线。第二张图,表示非等比缩放,使用UnityObjectToWorldDir(),把法线从模型空间转换到世界空间,法线也会被压扁并且不再垂直于曲面。第三张图,表示非等比缩放,使用UnityObjectToWorldNormal(),把法线从模型空间转换到世界空间,法线是正确的垂直于曲面的。

 

当等比缩放时,使用UnityObjectToWorldDir()和UnityObjectToWorldNormal()得到的结果是一样的。

渲染流水线中顶点的空间变换过程

 

模型空间——>世界空间——>视角(相机)空间——>裁剪空间——>屏幕空间

 

1. 模型空间:每个模型都有自己独立的坐标空间,当它移动或旋转时,模型空间也会跟着它移动或旋转。

模型空间——>世界空间的变换矩阵:unity_Object2World

 

2. 世界空间:如果一个Transform没有任何父节点,那么这个位置就是在世界空间中的位置。

世界空间——>视角(相机)空间的变换矩阵:UNITY_MATRIX_V

 

3. 视角(相机)空间:摄像机决定了我们渲染游戏所使用的视角。

视角(相机)空间——>裁剪空间的变换矩阵:UNITY_MATRIX_P

 

4. 裁剪空间:目的是能够方便的对渲染图元进行裁剪,完全位于视锥体空间内部的图元被保留,完全位于这块空间外部的图元被剔除,而这块空间边界相交的图元就会被裁剪。视锥体有两种类型:正交投影和透视投影。在使用视锥体进行裁剪时,那么不同的视锥体就需要不同的处理过程。因此,提出了一种通用、方便的方式来裁剪,就是通过一个投影矩阵把顶点转换到一个裁剪空间中。

 

在Unity中,从裁剪空间到屏幕空间的转换是由Unity底层帮我们完成的。

 

5. 屏幕空间:屏幕空间是一个二维空间,因此我们需要把顶点从裁剪空间投影到屏幕空间中,来生成对应的2D坐标。首先,用裁剪空间的x、y、z分量除以w分量,把坐标从裁剪空间转换到归一化的设备坐标(NDC,一个立方体)中。然后,再映射到屏幕空间中,确定顶点在屏幕空间的像素位置。

 

在顶点着色器中,通过UNITY_MATRIX_MVP 这个矩阵,可以把物体的顶点从模型空间转换到裁剪空间。

 

相机

名称 类型 数值
_WorldSpaceCameraPos float3 世界空间相机的位置
_ProjectionParams float4 x = 1.0(或如果当前使用翻转投影矩阵渲染则为-1.0),y是相机的近平面,z是相机的远平面,w是1 / FarPlane
_ScreenParams float4 x是相机的渲染目标在像素里的宽度,y是相机的渲染目标在像素里的高度,z是1.0 + 1.0 /宽度和w是1.0 + 1.0 /高度
_ZBufferParams float4 用于线性化Z缓冲区的值。x(1-far /near),y(far/near)、z(x /far)和w(y /far)
unity_OrthoParams float4 x是正交的相机的宽度,y是正交的相机的高度,z是未使用的,为正交的相机时w为1.0,透视相机时w为0.0
unity_CameraProjection float4x4 摄像机的投影矩阵
unity_CameraInvProjection float4x4 摄像机的投影矩阵的逆矩阵
unity_CameraWorldClipPlanes[6] float4 相机锥平面世界空间方程,按顺序为:左、右、底部、顶部、近、远

 

光照

名称 类型 数值
_LightColor0(Lighting.cginc中声明) fixed4 光照颜色
_worldspacelightpos0 float4 方向光:(世界空间方向,0)。其他光:(世界空间位置,1)
_LightMatrix0(AutoLight.cginc声明) float4x4 world-to-light矩阵。用于样品cookie 和衰减纹理
unity_4LightPosX0、unity_4LightPosY0 unity_4lightposz0 float4 (仅ForwardBase通道)前四个不重要的点光源的世界空间坐标
unity_4lightatten0 float4 (仅ForwardBase通道)前四个不重要的点光源的衰减系数
unity_lightcolor half4[4] (仅ForwardBase通过)前四个不重要的点光源的颜色数组

 

在Shader的光照通道里的延迟着色和延迟光照(在unitydeferredlibrary.cginc):

名称 类型 数值
_LightColor float4 光照颜色
_LightMatrix0 float4x4 world-to-light矩阵。用于样品cookie 和衰减纹理

 

多光源下,最多8个光源在顶点通道,排序为从最亮的开始

名称 类型 数值
unity_LightColor half4[8] 光照颜色数组
unity_LightPosition float4[8] 视图空间光源的位置。方向光源的坐标是(-方向,0);(位置,1)用于点/点指示灯,点光源,聚光灯的坐标是(位置,1)
unity_LightAtten half4[8] 光源衰减的系数。X是cos(spotAngle/2)或非聚光灯为-1;Y为1/COS(spotangle / 4)或非聚光灯为-1;Z是衰减的二次方;W是正方形光源的范围
unity_SpotDirection float4[8] 视图空间聚光灯的位置;(0,0,1,0)则非聚光灯。

 

 

 

 

 

 

标签:之美,法线,裁剪,矩阵,unity,Shader,相机,Unity,空间
来源: https://blog.csdn.net/weixin_44350205/article/details/99856871

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有