当前位置:   article > 正文

UnityShader原理与基础数学问题_shader 原理

shader 原理

UnityShader原理与基础数学问题


目录

UnityShader原理与基础数学问题

一、Shaer原理

1、GPU流水线

2、Draw Call

3、固定函数的流水线

4、SubShader、状态、标签、Pass

二、基础数序问题

1、笛卡尔坐标系

2、矢量计算

3、矩阵

4、坐标空间变换

5、法线变换

6、观察空间->模型空间(顶点或矢量)

7、(顶点或矢量)从观察空间到模型空间

8、矩阵乘法注意(代码)


一、Shaer原理

1、GPU流水线

  • 顶点着色器(Vertex Shader)是完全可编程的,它通常用于实现顶点的空间变换、顶点着色、逐顶点光照等功能。
  • 曲面细分着色器(Tessellation Shader)是一可选的着色器,它用于细分图元。
  • 几何着色器(Geometry Shader)同样是可选的着色器,它可以被用于执行逐图元(Per-Printitive)的着色操作,或者被用于产生更多的图元。
  • 裁剪阶段是可配置的。例如,我们可以使用自定义的裁剪平面来配置裁剪区域,也可以通过指令控制裁剪三角图元的正面还是背面。
  • 屏幕映射(Screen Mapping)阶段是不可配置和编程的,它负责把每个图元的坐标转换到屏幕坐标系中。
  • 三角形设置(Triangle Setup)和三角形遍历(Triangle 'Traversal)阶段也都是固定函数(Fixed-Function)的阶段。
  • 片元着色器(Fragment Shader),则是完全可编程的,它用于实现逐片元(Per-Fragment)的着色操作,重要功能:纹理采样。
  • 逐片元操作(Per-FragmentOperations)阶段负责执行很多重要的操作,例如修改颜色、深度缓冲、深度测试、模板测试、进行混合等,它不是可编程的,但具有可配置性。
     

2、Draw Call

应用阶段CPU调用图像编程接口向GPU发送渲染命令,DrawCall多了会影响帧率,因为GPU的处理速度往往大于CPU提交命令的速度。

减少DrawCall:使用批处理(Batching)。将多个小的DrawCall合并为一个大的DrawCAll,适用于静态物体。

避免使用大量很小的网络;避免使用过多材质,尽量在不同网格之间使用同一个材质。

 

3、固定函数的流水线

固定函数的流水线(Fixed-Function Pipeline),也简称为固定管线,通常是指在较旧的 GPU上实现的渲染流水线。这种流水线只给开发者提供一些配置操作,但开发者没有对流水线阶段的完全控制权。

基本不用了。

4、SubShader、状态、标签、Pass

SubShader 中定义了一系列 Pass 以及可选的状态([RenderSetup])和标签([Tags])设置。每个Pass定义了一次完整的渲染流程,但如果 Pass的数目过多,往往会造成渲染性能的下降。因此,我们应尽量使用最小数目的Pass。状态和标签同样可以在 Pass声明。不同的是,SubShader中的一些标签设置是特定的。也就是说,这些标签设置和Pass中使用的标签是不一样的。而对于状态设置来说,其使用的语法是相同的。但是,如果我们在SubShader进行了这些设置,那么将会用于所有的Pass。

常见的渲染状态设置选项

状态名称设置指令解释
CullCull Back | Front | Off设置剔除模式:剔除背面/正面/关闭剔除
ZTestZTest Less Greater  LEqual | GEqual | Equal | NotEqual |Always设置深度测试时使用的函数
ZWriteZWrite On  Off开启/关闭深度写入
BlendBlend SrcFactor DstFactor开启并设置混合模式



 

 

 

 

 

Subshader标签

Pass

二、基础数序问题

1、笛卡尔坐标系

2、矢量计算

点积 dot(a,b)  :计算投影长度

叉积 cross(a,b) :计算与a,b向量垂直的向量

叉积的方向与坐标系有光

3、矩阵

对角矩阵:如果一个矩阵除了对角元素外的所有元素都为0,那么这个矩阵就叫做对角矩阵。

单位矩阵:对角线数值都为1的特殊的对角矩阵。用I表示。

逆矩阵

正交矩阵:单位坐标系就是正交矩阵,及标准正交积。

性质:

注意:

(1)Untiy经常把矢量放在矩阵右侧,即矢量为列向量,变换矩阵为三个行向量组成

(2)unity中等价于

(3)我们约定的变换顺序为:缩放,旋转,平移

4、坐标空间变换

(1)把子坐标空间下表示的点或矢量A转换到父坐标空间下的表示A。

(2)把父坐标空间下表示的点或矢量B,转换到子坐标空间下的表示B。

其中,Mc-p表示的是从子坐标空间变换到父坐标空间的变换矩阵,而 Mp-c是其逆矩阵(即反向变换)。我们只需要解出两者之一即可,另一个矩阵可以通过求逆矩阵的方式来得到。

p(父)坐标轴中一点(a,b,c)

p坐标轴中子坐标轴原点Oc,三个坐标轴Xc,Yc,Zc.  (这里Xc,Yc,Zc不要求为单位矢量)


可以通过变换矩阵获得子坐标系的原点和三个轴向(这里需要归一化)

(3)对于方向矢量的变换矩阵(不需要考虑平移变换) 

Shader中,我们常常会看到截取变换矩阵的前3行前3列来对法线方向、光照方向来进行空间变换。
 

(4)unity的空间

a.模型空间(model Space) 

b.世界空间(world Space)  模型变换(模型空间到世界空间)变换顺序:缩放,旋转,平移

c.观察空间(view Space),也称为摄像机空间(Camera Space)右手坐标系  观察变换(世界空间到观察空间)   

d.裁剪空间(clip Space)这里用于变换的矩阵称为裁剪矩阵(clip matrix)或投影矩阵(projecrtion matrix)   

裁剪空间在视锥体(View frustum)内;

正交投影(Orthographic projection)透视投影(Perspective projection)

e.屏幕空间

5、法线变换

一般来说,点和绝大部分方向矢量都可以使用同一个4×4或3×3的变换矩阵Ma-b;把其从坐标空间A变换到坐标空间B中。但在变换法线的时候,如果使用同一个变换矩阵,可能就无法确保维持法线的垂直性。

求原变换矩阵的逆转置矩阵。

(1)使用UNITY_MATRIX_IT_MV  (MV的逆转置矩阵)可以将法线从模型空间变换到观察空间

(2)从观察空间到模型空间

float4 modelPos = mul(transpose(UNITY_MATRIX_IT_MV),viewpos);

或使用行矩阵乘法

float4 modelPos = mul(viewpos,UNITY_MATRIX_IT_MV);

(3)unityshader 内置函数UnityObjectToWorldNormal(normal)可以将法线从模型空间变换到世界空间

fixed3 worldNormal=UnityObjectToWorldNormal(v.normal);

6、观察空间->模型空间(顶点或矢量)

 前提:对于方向矢量(没有平移需求),只存在统一缩放和旋转,可以截取UNITY_MATRIX_T_MV的前三行前三列作为变换矩阵。(使用前矢量进行归一化,消除统一缩放的影响。)

此时UNITY_MATRIX_T_MV为一个正交矩阵,矩阵的逆等于转置。

7、(顶点或矢量)从观察空间到模型空间

float4 modelPos = mul(transpose(UNITY_MATRIX_IT_MV),viewpos);

或使用行矩阵乘法

float4 modelPos = mul(viewpos,UNITY_MATRIX_IT_MV);

8、矩阵乘法注意(代码)

shader中不用在意输出的是行矩阵还是列矩阵,最后结果一样即可。

CG使用的是行优先,填充时是一行一行的。

9、unity屏幕坐标ComputeScreenPos/VPOS/WPOS

后续更新

来自《Unity Shader入门精要》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/107895
推荐阅读
相关标签
  

闽ICP备14008679号