赞
踩
紫色:大类概念或简短有力的总结
蓝色:细分概念或重要部分
红色:重要的补充注释
应用阶段(开发者控制阶段)
由开发者全权进行管理,控制场景内摄像机位置,需要用到的模型以及他们的位置.在布置结束后DrawCall进入下一阶段(由CPU发布渲染指令被称为DrawCall)
几何阶段(3D转2D阶段)
由GPU进行管理,将所有3D物体坐标进行变换,输出2D坐标并传输到下一阶段
光栅化阶段(将图像渲染到屏幕上)
由GPU进行管理,根据坐标决定要如何渲染,并将处理好的图像绘制在屏幕上
顶点着色器:将顶点进行空间变换并着色
曲面细分着色器:用于细分图元
几何着色器:产生更多图元或对图元依次着色
裁剪:将不在摄像机范围内的顶点去除掉,并去除一些三角图元的面片
屏幕映射:把每个图元的x和y坐标转换到屏幕坐标系下
三角形设置:计算由几何阶段传过端点而构成的三角形的边的坐标
三角形遍历:检查每个像素是否被三角网格所覆盖
片元着色器:将片元逐一着色
逐片元操作:将片元依次渲染,不可编程但可配置.对片元进行测试通过后可对片元进行各种重要操作.如修改颜色,颜色混合等(若未通过测试则舍弃片元)
模板测试:
读取模板缓冲区该片元的位置,然后和读取到的参考值进行比较
开发者可对比较函数进行配置。如小于参考值时舍弃,或大于等于时舍弃
不管片元有没有通过测试,开发者都可以根据测试结果修改模板缓冲区
常用于实现阴影效果
深度测试:
GPU将该片元的深度和深度缓冲区的数值进行比较,常用于实现透明效果
当一个片元完成了以上测试,就进入了混合(合并)环节
在渲染时,因为物体是逐一被绘制到屏幕上的,而每个像素的颜色都被保存在颜色缓冲区
那么当我们执行下次渲染时,是要直接替换掉之前的颜色,还是和之前的颜色进行一些混合操作?
对于不透明物体,开发者可以关闭混合。这样,由于绘制时会覆盖掉之前的像素,绘制到屏幕上的结果就是不透明的。反之,通过混合操作可以让物体看起来像是透明
阶段与各环节流程
渲染流程的三个阶段.在应用阶段由开发者自由配置
在几何阶段由GPU进行空间转换.将端点坐标计算好来为光栅化阶段做准备
光栅化阶段负责进行最后的渲染,我们在这里通过配置模板测试/深度测试的脚本来修饰片元
最后在混合环节完成最后的整合输出到我们的屏幕上
顶点,片元,图元,像素的关联
顶点是从应用阶段被解析,经过几何阶段的变换与计算来获取图元.图元被光栅化之后变为片元.片元在经过模型/深度测试后变为像素(即呈现在计算机屏幕上的像素点)
什么是DrawCall
当CPU需要GPU进行渲染工作时,向命令缓冲区发送DrawCall指令
由于GPU渲染速度很快,而CPU发布命令速度较慢。因此,发送大批量DrawCall指令比GPU进行一次大规模渲染要慢得多(因为发送命令的间隔GPU就把任务完成了)所以,可以通过批处理来减少DrawCall造成的开销
批处理
批处理有个缺点,因为批处理是合并了很多模型,而合并他们是需要时间的.所以,批处理不适用于动态物体(因为每一帧都要进行合并)
而在unity开发中,网格不建议细分小而多,这样也会增加drawcall的开销
常用RenderSetup
常用Tags
注意:虽然Pass中也允许你设置Tags,但是使用的代码不同.以上是仅适用SubShader的Tags
用Name定义该Pass的名称 如 Name "Aba"
这样,我们可以在其他UnityShader中的SubShader中直接引用这个Pass.如 UsePass "MyShader/ABA"
其中,MyShader是Title中声明的Name.而Pass的Name将在Unity中自动转大写.所以要引用Aba应输入ABA
Pass的标签类型
UsePass:复用其他Unity Shader中的Pass
GrabPass:该Pass负责抓取屏幕并将结果存储在一张纹理中,以用于后续的Pass处理
最简单的实现:在Unity中截图!
表面着色器: Unity中对基本渲染进行了封装的高级形式.封装了片元着色器和顶点着色器.在编译通过后,unity会将表面着色器拆分为片元/顶点着色器.而不需我们再做多余底层工作
顶点/片元着色器: 使用CG/HLSL着色器语言编写的常规着色器.更加复杂,但灵活性更高.而且学会了可以跨平台(因为表面着色器是Unity专用)
UnityShader不是真正意义上的Shader.只是能实现Shader的功能
UnityShader分为三部分:Title(开头),properties(属性) ,subshader(状态).subshader中的Pass块定义渲染流程
Subshader可以有多个Pass.用于从前到后依次检索.会挑选显卡能够呈现的第一个效果
表面着色器是顶点/片元着色器的组合,为unity的高级封装
要描述一个物体的相对位置。使用笛卡尔坐标系(原点起发的三维向量。距离x,y,z轴的距离)
左手坐标系与右手坐标系:
反转一个轴,就得到了一个相反的坐标系(对于坐标系来说,这相当于镜像翻转)
这种操作也能转换左右手坐标系
(理解上图吗?可以看作将左手坐标系向右旋转了90°,然而本来应该是-x的方向变为了+x。x轴被反转了,所以转变为右手坐标系)
同时,左右手法则的旋正方向也不同
在Unity的世界空间中,使用的是左手坐标系.而观察空间使用的是右手坐标系
点:平平无奇的坐落在坐标系上的一个点
向量:表达一个方向,以及终点距离原点的距离.向量是空间中的一个箭头
向量的本质是将x帽和y帽的路径整合
根据此观点,我们知道了。[1,2]+[3,4]向量相加的本质
其实就是[1+3,2+4]=[4,6]
同样的,向量相乘。[2,3]*[3,4]=[2*3,3*4]
在图形学中向量通常用于描述位置偏移(简称位移)。因此,我们可以利用向量的加法和减法来计算一点相对于另一点的位移。
不关心矢量的模(距离),将矢量的距离视为1。单位矢量也被称为被归一化的矢量。对任何给定的非零矢量,把它转换成单位矢量的过程就被称为归一化
这样的向量在上面加一个倒v表示,读帽。如x帽就是距离为1的向量
在正常法线方向,光源方向运算时,矢量不一定是归一化矢量。我们要先进行归一化再进行运算
点积:两个相同维度的矩阵每个向量相乘后相加
可以理解为一个向量投影到其他向量,然后将向量相乘
所以,当方向基本相同时,结果为正
方向相反时,结果为负
垂直时结果为正
点积满足交换律
X积:本质上是两个向量之间构成的平行四边形的面积
叉积不满足交换律
当顺时针计算时,叉积结果为正。逆时针计算时,叉积结果为负
求结果计算行列式即可
首先。要明白矩阵的本质是矢量组成的坐标系
例:有这样一个矩阵:
实际上,他是三个向量(1,2,3)(4,5,6)(7,8,9)描绘的坐标系
矩阵运算的过程,其实是空间变换的过程。这个过程叫线性变换
当一个a*b大小的矩阵和一个b*c大小的矩阵相乘时.最后矩阵大小为a*c
(如果行数相等,可以把其中一个行矩阵转为列矩阵)
当行列不相等时.如2*4矩阵和3*6大小矩阵无法进行运算
结果矩阵为依次遍历.如c11为[a11,a12]与[b11,b12]进行运算
运算公式为c11=a11*b11+a12*b12
一般shader中的矩阵为4x4
在shader中最常用的变换就是线性变换
矩阵可以抽象为坐标轴,而线性变换是以矩阵运算。所以,线性变换的运算就是空间变换的过程
什么是线性变换?
将一个空间通过一定的运算,得到另一个空间
如f(x)=2x,这是一个缩放线性变换
此外,比较常用的还有平移变换
仿射变换(将三维矢量转到四维来进行线性变换和平移变换)
如何将三维矢量转为齐次坐标(四维矢量)?
对于点:将w轴设为1
对于向量:将w轴设为0
仿射变换下的变换矩阵
移动矩阵:
注:向量没有位置属性,所以不受平移矩阵影响
缩放矩阵
旋转矩阵(绕轴旋转)
最后:复合变换的顺序是缩放,旋转,平移
Unity的内置矩阵
shader最重要的数学知识是矩阵和线性变换
矩阵实际上是向量/点的抽象
矩阵变换的计算方法
不同的坐标系空间不可以相互进行运算,需要转换到相同坐标系
(如父物体的子物体中的坐标系是相对父物体而言的)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。