1. 渲染流水线
三大块:应用阶段,几何阶段,光栅化阶段
渲染图元 顶点信息
GPU流水线
顶点数据=>
顶点着色器;曲面细分着色器;几何着色器;裁剪;屏幕映射=>
三角形设置;三角形遍历;片元着色器;逐片元操作=>
屏幕图像
裁剪:可配置的,摄像机属性
逐片元操作:模板测试,深度测试,混合(不可编程,可以配置)
为了优化,Unity的Ztest是在片元着色器之前;
但是如果使用了clip(值为负数,丢弃像素信息 discard)函数,会关闭提前测试,导致需要处理的片元增加
2. 数学
齐次坐标系,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。
向量为 x,y,z,0 不能平移,没有位置的概念
点 为 x,y,z,1 可以平移,有位置的概念
点乘的几何意义是投影, |a||b|cos夹角
叉乘的几何意义是找和两个向量都垂直的新向量,计算公式是斜着一个一个乘起来
法线的坐标变换是比较特殊的,在非统一缩放时会出问题,U3D封装了接口 XXXXNormal
3. 标准光照模型
4个部分构成:自发光(emissive),高光(specular),漫反射(diffuse),环境光(ambient)
漫反射: 兰伯特模型 漫反射光的光强仅与入射光的方向和反射点处表面法向夹角的余弦成正比。
半兰伯特 0.5*(法线 点乘 光)+0.5
高光: Phong模型 镜面反射光强与反射光线和视线的夹角a相关
Blinn Phong dot(V,R)换成dot(N,H),法线,半角向量(位于视线V和光线L的角平分线方向 H = (L + V) / | L+V |)
渲染队列
背景 1000
几何体 2000 透明度测试 2450
透明图混合(半透) 3000
延后 4000
Unity渲染路径
前向: 两个缓冲区信息:颜色,深度,模板
每个pass逐像素的计算一个光照的影响
分两种pass: ForwardBase(1个) ForwardAdd(n个)
延迟: 缓冲信息比较多:漫反射颜色,高光颜色,平滑度,法线,自发光,深度等信息
两个Pass:第一个写入缓冲,不进行任何光照计算;第二个pass利用Gbuffer中的信息计算光照
阴影
Shadow Map:把摄像机放在和光源重合的位置,光源的阴影就是摄像机看不到的地方
投射 使用LightMode中标签为ShadowCaster的Pass渲染到阴影映射纹理(深度纹理)中
接收 采样阴影纹理,与原本的颜色相乘
SHADOW_COORDS v2f的结构体中声明阴影纹理坐标
TRANSFER_SHADOW vert中计算纹理坐标,把模型空间转到阴影空间,再到纹理坐标空间
SHADOW_ATTENUATION frag中取阴影纹理信息
这些宏使用有别的变量的命名限制
透明度剔除的可以投射阴影,半透明的不行(渲染顺序问题,会变得很复杂)
CubeMap:做反射,折射,菲涅尔反射(模型边界处反射)
Texture2D 可以用代码生成,改动,给材质使用
程序材质 sbsar 后缀名,用Substance Designer在Unity外部生成的
动画:uv动画,顶点位置动画, 就是用时间为参数改uv,顶点位置,顶点法向量什么的
批处理可能会破在模型空间计算的顶点动画效果, 可以用 DisableBatching 标签关闭
投射阴影不能用默认的Pass
屏幕后处理,OnRenderImage函数,用材质球算一次
边缘检测: 用边缘检测算子对图形进行卷积 算子类似 1,0,-1分别检测x和y轴 再取绝对值相加,大的就是边界
高斯模糊: 多次卷积,卷积结果就是像素的值,算子类似 0.05,0.25,0.4,0.25,0.05
Bloom: 高光扩散效果,提取高亮区域,对高亮区域做高斯模糊(需要一个新的RenderTexture),和原图混合
运动模糊: 保存上一帧的渲染结果,叠加到当前帧中或是用深度纹理重建速度来模拟运动模糊
Unity和图像处理类 Graphics类中常用函数
public static void Blit(Texture source, RenderTexture dest); //屏幕后处理用的
public static void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, Matrix4x4[] matrices); //GPU批次绘制Mesh
其他函数
Camera.RenderWithShader(Shader shader, string replacementTag) //该摄像机用某一shader绘制
深度纹理和法线纹理
延迟渲染会自动生成,前向会用着色器替换技术选择渲染队列小于2500的物体生成
深度纹理会直接读取深度缓存,法线贴图需要额外生成
使用噪声
消融,水面抖动等等
动态合批:
顶点属性总之小于900,相同模型材质,Shader支持合批
静态合批
勾上Batching Static就行了,也要求使用相同材质,会使得内存变大,静态合批之后不能再移动,变成一个大的mesh
shader LOD
shader的LOD值大于设定值后将不会被渲染
Shader.maximumLOD 设定,Diffuse为200
surface shader:
表面函数,光照函数,顶点函数,最终颜色修改函数
可以很方便的处理光照