美文网首页
Unity3D Shaders中Loacl、World、Came

Unity3D Shaders中Loacl、World、Came

作者: 雄关漫道从头越 | 来源:发表于2019-07-24 00:18 被阅读0次

TRANSFORMATIONS BETWEEN LOCAL, WORLD
AND CAMERA SPACES IN UNITY3D SHADERS

PDF版 百度云盘 提取码:98k2

Local, World and Camera spaces 是Unity3D渲染过程(或者其他任何游戏引擎)的关键概念之一。了解不同坐标系及它们之间的关系,这些知识是能成功开发 shader 的关键。

要决定如何,在哪里以及应该在屏幕上渲染哪些元素,Unity会将这些元素的坐标从Local space(也称Model space,Object space)转换到World space,然后再从World space 转换到 Camera sapce(也称Eye sapce,或者View space),最后再从Camera space转换到 Projection space(投影空间)。所以,实际上对我们来说总共有5种非常重要的不同坐标系:

· Local space(Model space,Object space)
· World space
· View space(Camera space,Eye space)
· Clip space
· Screen space

附注:搞这么多名字,不被搞晕才怪了。

下面的图片代表了一系列坐标系转换的流程。

空间转换流程图
矩阵转换链可以实现上述的转换,如果想了解更多关于这些矩阵的信息,可以查看learnopengl.com

不过让我们继续讨论Unity,当你使用standard sahders 和materials,甚至创建自己的surface shader,你不需要担心关于矩阵的描述。Unity 为我们做了所有的“苦活”,但是,理解渲染管道能让你创建更多有趣的视觉效果和设计各种动画和相机相关的shaders。

Unity3d中的转换矩阵

你可能知道,Unity3d引擎为shader开发提供了一组内置全局变量(built-in global variables),包括当前对象的转换矩阵,Unity3d在Unity Engine 5.4 版本中提供了9个 float4x4 的矩阵:

name value
UNITY_MATRIX_MVP Current model * view * projection matrix.
UNITY_MATRIX_MV Current model * view matrix.
UNITY_MATRIX_V Current view matrix.
UNITY_MATRIX_P Current projection matrix.
UNITY_MATRIX_VP Current view * projection matrix.
UNITY_MATRIX_T_MV Transpose of model * view matrix.
UNITY_MATRIX_IT_MV Inverse transpose of model * view matrix.
_Object2World Current model matrix.
_World2Object Inverse of current world matrix.
shader中不同空间的切换

在不同坐标系之间,所有这些内置矩阵都允许你转换点和/或方向坐标。对于简单的shaders,你仅仅需要 UNITY_MATRIX_MVP 矩阵将每个顶点的坐标从本地空间(Local space)直接转换到裁剪空间(Clip space),不过,你也可以轻松的使用_Object2World 从本地空间转换到世界空间,使用_World2Object从世界空间转换到本地空间。
你也可以轻松的使用UNITY_MATRIX_MV 矩阵从本地空间转换到相机空间(Camera space/Eye space),但是如果你需要对shader中的顶点做相机空间相关的转换,该怎么办?哪里可以获取UNITY_MATRIX_VM 矩阵?

首先,正如你记得的一样,UNITY_MATRIX_T_MV 矩阵不是 UNITY_MATRIX_MV的逆。这通常意味着,
UNITY_MATRIX_T_MV * UNITY_MATRIX_MV 不等于Matrix.Identity(单位矩阵)。然而,要将坐标从相机空间转换到本地空间还有一些工作要做。这个技巧就是矩阵乘以向量的顺序。理解如何使用矩阵相乘和mul(matrix, vector) != mul(vector, matrix) 非常重要。记住什么是矩阵的转置和逆,显然,UNITY_MATRIX_IT_MV 矩阵才是我们转换的关键!

现在,可以总结一下shaders 中提供的矩阵在不同的空间中的转换信息:

From To How to transform
Local Space World Space mul(_Object2World, currentPos)
Local Space Camera Space mul(UNITY_MATRIX_MV, currentPos)
Local Space Clip Space mul(UNITY_MATRIX_MVP, currentPos)
World Space Local Space mul(_World2Object, currentPos)
World Space Camera Space mul(UNITY_MATRIX_V, currentPos)
World Space Clip Space mul(UNITY_MATRIX_VP, currentPos)
Camera Space Local Space mul(currentPos, UNITY_MATRIX_IT_MV)
Camera Space Clip Space mul(UNITY_MATRIX_P, currentPos)

请注意,这些操作对顶点坐标是正确的,但是对于法线相关的转换是不正确的。
法线的转换可以参考笔者的另外一篇文章法线从object space到eye space的转换(normal matrix)
另外,我们没有讨论更多关于转换到实际屏幕坐标的内容,这是另一篇文章的好主题。

屏幕空间着色

现在我们可以使用所有这些信息来创建一些效果比较有趣的着色器。第一个例子,让我们创建一个基于屏幕旋转相关会改变颜色的shader。
为了达到这个效果,我们必须指定一个基本方向(在View space 坐标中),将其转换到对象的本地空间中,并将转换到本地空间的方向归一化后作为当前的颜色。

Shader "101DummyShaders/1/ScreenSpaceColor"
{
    Properties
    {
        _Direction("Screen Space Direction (x, y, z)", Vector) = (1, 0, 0)
        _Glossiness("Smoothness", Range(0,1)) = 0.5
        _Metallic("Metallic", Range(0,1)) = 0.0
    } 

    SubShader
    {
      Tags { "RenderType" = "Opaque" }
      LOD 200
      CGPROGRAM
      #pragma surface surf Standard vertex:vert fullforwardshadows
      #pragma target 3.0
      struct Input
      {
        fixed3 dirColor;
      };
      half _Glossiness;
      half _Metallic;
      fixed3 _Direction;
      void vert(inout appdata_full v, out Input o)
      {
          fixed3 localSpaceDir = mul(_Direction, (float3x3)UNITY_MATRIX_IT_MV);
          UNITY_INITIALIZE_OUTPUT(Input, o);
          o.dirColor = normalize(localSpaceDir);
      } 
      void surf (Input IN, inout SurfaceOutputStandard o)
      {
          o.Albedo = IN.dirColor;
          o.Metallic = _Metallic;
          o.Smoothness = _Glossiness;
          o.Alpha = 1;
      }
      ENDCG
      } 
      FallBack "Diffuse"
}

非常有趣的效果,不是吗?例如,用这个shader 作一些小的修改就能非常容易的实现在一些第一人称射击游戏中,突出敌人弱点的高亮的效果。

但是更高级的东西呢,比如顶点变形?使用同样的技术达到视图相关的缩放看起来是显而易见的,等等。
不过这里我先卖个关子,我将在下一篇文章中讲述这些问题了。

第一次尝试翻译,英文比较烂,不要介意,原英文可以在文章的开头获取。

相关文章

网友评论

      本文标题:Unity3D Shaders中Loacl、World、Came

      本文链接:https://www.haomeiwen.com/subject/vmfalctx.html