VP矩阵以及GL.GetGPUProjectionMatrix
c#层的VP矩阵
public class VPMatrixTest : MonoBehaviour { void Start() { var mainCam = Camera.main; var viewMatrix = mainCam.worldToCameraMatrix; Debug.Log($"viewMatrix:\n {viewMatrix}"); var projMatrix = mainCam.projectionMatrix; Debug.Log($"projMatrix:\n {projMatrix}"); var projMatrix2 = GL.GetGPUProjectionMatrix(projMatrix, false); Debug.Log($"projMatrix2:\n {projMatrix2}"); var projMatrix3 = GL.GetGPUProjectionMatrix(projMatrix, true); Debug.Log($"projMatrix3:\n {projMatrix3}"); var vpMatrix = projMatrix2 * viewMatrix; Debug.Log($"vpMatrix:\n {vpMatrix}"); } }
GetGPUProjectionMatrix的第二个参数为false(proj2Matrix)和true(proj3Matrix)的差别是m11一个为正,一个为负。
所以第2个参数名叫flipVertical会不会更容易理解?
shader层的VP矩阵
需要用Frame Debug来看(Window -> Analysis -> Frame Debugger)
Shader "My/MVPMatrix/VpMatrix" { SubShader { Tags { "RenderType" = "Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float4 vMatrix : TEXCOORD0; float4 pMatrix : TEXCOORD1; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.vMatrix = mul(UNITY_MATRIX_V, v.vertex); //矩阵乘法结果无意义, 仅仅测试用 o.pMatrix = mul(UNITY_MATRIX_P, v.vertex); return o; } fixed4 frag(v2f i) : SV_Target { return fixed4(1, 1, 1, 1); } ENDCG } } }
所以UNITY_MATRIX_P和projMatrix2相同
UNITY_MATRIX_VP和(projMatrix2 * viewMatrix)的计算结果相同
什么情况下需要c#层把vpMatrix传给shader?直接用UNITY_MATRIX_VP不行吗?
UNITY_MATRIX_VP是针对主相机的,如果需要用到非主相机的vpMatrix时,就需要c#层传入shader
参考
GetGPUProjectionMatrix_wodownload2的博客-CSDN博客
Unity3D 神奇的GetGPUProjectionMatrix函数_liuwumiyuhuiping的博客-CSDN博客
Camera的projectionMatrix的正确使用方式? -- UWA问答 | 游戏开发者互动问答社区 | 侑虎科技 (uwa4d.com)