Unity Shader 数学与几何变换 深入理解渲染管线中的坐标系转换:从模型空间到屏幕空间的完整变换链

张开发
2026/5/3 3:53:23 15 分钟阅读

分享文章

Unity Shader 数学与几何变换 深入理解渲染管线中的坐标系转换:从模型空间到屏幕空间的完整变换链
变换链概览理解渲染管线中顶点数据的完整变换过程在 Unity Shader 中顶点从模型数据到最终显示在屏幕上需要经过一系列坐标系转换。这个过程被称为顶点变换管线是理解 3D 渲染的核心基础。为什么需要这么多坐标系每个坐标系都有其特定的用途模型空间方便建模世界空间用于场景管理观察空间简化投影计算裁剪空间用于视锥体裁剪屏幕空间对应最终像素位置。模型空间 (Model Space)顶点数据的原始坐标系以模型自身为参考定义与特性局部坐标系每个模型都有自己的坐标系原点通常位于模型的几何中心或底部中心。建模坐标系3D 建模软件如 Blender、Maya中创建模型时使用的坐标系。顶点属性顶点位置、法线、切线等数据在模型空间中定义存储在 Mesh 中。实际应用在 Unity Shader 中模型空间顶点数据通过顶点着色器输入获取struct appdata { float4 vertex : POSITION; // 模型空间顶点位置 float3 normal : NORMAL; // 模型空间法线 float2 uv : TEXCOORD0; // 纹理坐标 };03世界空间 (World Space)场景的统一坐标系所有模型的公共参考系模型到世界的变换其中Mmodel是模型变换矩阵由平移、旋转、缩放组合而成// Unity 内置矩阵unity_ObjectToWorld float4 worldPos mul(unity_ObjectToWorld, vertex); // 或者使用 TransformObjectToWorld 函数 float3 worldPos TransformObjectToWorld(vertex.xyz);⚠️注意法线变换法线需要使用逆转置矩阵进行变换以保证在非标量缩放时保持正确worldNormal normalize(mul((float3x3)unity_WorldToObject, normal))观察空间 (View Space)以摄像机为原点的坐标系简化投影计算观察空间特性摄像机坐标系原点位于摄像机位置Z轴指向摄像机朝向的反方向观察方向。右手坐标系Unity 使用右手坐标系X 向右Y 向上Z 向后远离摄像机。视图变换将世界空间转换为以摄像机为中心的局部空间。观察矩阵推导观察矩阵是摄像机变换矩阵的逆矩阵包含两个步骤平移将世界原点移动到摄像机位置旋转对齐坐标轴到摄像机朝向Shader 实现// 方法1使用内置矩阵 unity_MatrixV float4 viewPos mul(unity_MatrixV, worldPos); // 方法2使用 UNITY_MATRIX_V 宏 float4 viewPos mul(UNITY_MATRIX_V, worldPos); // 方法3URP/HDRP 中的变换函数 float3 viewPos TransformWorldToView(worldPos.xyz);裁剪空间 (Clip Space)投影变换后的齐次裁剪坐标系投影变换裁剪空间是顶点着色器的输出空间通过投影矩阵将观察空间转换为裁剪空间。这个变换同时处理透视除法前的齐次坐标。投影类型特点应用场景透视投影近大远小符合人眼视觉3D 游戏、真实感渲染正交投影平行线保持平行无透视变形2D 游戏、UI、工程制图// 顶点着色器输出裁剪空间位置 float4 vert (appdata v) : SV_POSITION { float4 worldPos mul(unity_ObjectToWorld, v.vertex); float4 viewPos mul(UNITY_MATRIX_V, worldPos); float4 clipPos mul(UNITY_MATRIX_P, viewPos); return clipPos; } // 或者使用 MVP 矩阵一次性变换 return mul(UNITY_MATRIX_MVP, v.vertex);屏幕空间 (Screen Space)最终的像素坐标系对应显示器上的实际位置屏幕空间坐标获取// 片段着色器中获取屏幕坐标 float4 frag (float4 pos : SV_POSITION) : SV_Target { // pos.xy 已经是屏幕空间坐标 (像素位置) float2 screenUV pos.xy / _ScreenParams.xy; // 或者使用内置宏 float2 screenUV ComputeScreenPos(pos).xy; return float4(screenUV, 0, 1); }总结与速查表坐标系转换的核心要点回顾坐标系范围变换矩阵/函数用途模型空间模型局部顶点输入数据存储顶点原始位置世界空间场景全局unity_ObjectToWorld光照计算、物理模拟观察空间摄像机局部UNITY_MATRIX_V视锥体剔除、投影准备裁剪空间齐次坐标UNITY_MATRIX_P顶点着色器输出NDC[-1, 1]³透视除法 (w 除法)硬件裁剪屏幕空间[0, W]×[0, H]视口变换像素位置、后处理学习建议理解这些坐标系转换是掌握 Shader 编程的基础。建议通过实际编写 Shader 来加深理解尝试在顶点着色器中输出不同空间的坐标作为颜色观察变换效果。

更多文章