- 1.渲染流水线, 模型投影, 定点着色;
2.shader一般主要有: 固定管线着色器, 顶点片元着色器, 表面着色器;
固定管线着色器(慢慢会被淘汰);
顶点shader: 干预模型形态的shader;
像素shader: 干预像素着色的shader;
3.模型定点运算的时候,可以加入顶点shader来干预顶点的位置;
顶点着色的时候,加入像素shader来干预像素的上色;
4.Unity使用ShaderLab来进行着色程序的编写,对不同的平台进行编译,重点支持Cg语言;
- 定义一个Shader,每一个着色程序都要有一个Shader
Shader “name” { // name 为shader的名字
// 定义的一些属性,定义在这里的会在属性查看器里面显示;
[Propeties]
// 子着色器列表,一个Shader必须至少有一个子着色器;
Subshaders: {…}
// 如果子着色器显卡不支持,就会降级,即Fallback操作;
[Fallback]
}
-
Propeties定义
1:name(“display name”, type) = 值;
name指的是属性的名字,Unity中用下划线开始_Name;
display name是在属性检查器的名字;
type: 这个属性的类型
值: 只这个属性的默认值;
2: 类型type:
Float, Int
Color(num, num, num, num)(0 ~ 1)
Vector(4维向量)
Range(start, end)
2D: 2D纹理属性
Rect: 矩形纹理属性
Cube: 立方体纹理属性
3D: 3D纹理属性;name(“displayname”, 2D) = “name” {options}
3: Options: 纹理属性选项
TexGen:纹理生成模式,纹理自动生成纹理坐标的模式;顶点shader将会忽略这个选项;
ObjectLinear, EyeLinear, SphereMap, CubeReflect CubeNormal
LightmapMod: 光照贴图模式如果设置这个选项,纹理会被渲染器的光线贴图所影响。
4:
_Range (“range value”, Range(0, 1)) = 0.3; // 定义一个范围
_Color(“color”, Color) = (1, 1, 1, 1); // 定义一个颜色
_FloatValue(“float value”, Float) = 1 // 定义一个浮点
_MainTex (“Albedo”, Cube) = “skybox” {TexGen CubeReflect} // 定义一个立方贴图纹理属性;
-
- SubShader
1: SubShader {[Tags], [CommonState], Pass {} }
子着色器由 标签(Tags),通用状态,通道列表组成,它定义了一个渲染通道列表,并可选为所有通道初始化需要的通用状态;
2: SubShader渲染的时候,将优先渲染一个被每个通道所定义的对象。
3: 通道的类型: RegularPass, UsePass, GrabPass,
4: 在通道中定义状态同时对整个子着色器可见,那么所有的通道可以共享状态;
5:
SubShader {
Tags {“Queue”, “Transparent” }
Pass {
Lighting Off // 关闭光照
…
}
}
- Tags
1: Tags {“标签1” = “value1” “key2” = “value2”}
2: 标签的类型:
Queue tag 队列标签;
RenderType tag 渲染类型标签;
DisableBatching tag 禁用批处理标签;
ForceNoShadowCasting Tag 强制不投阴影标签;
IgnoreProjecttor 忽略投影标签;
CanUseSpriteAtlas Tag,使用精灵图集标签;
PreviewType Tag预览类型标签;
- Pass
1: subshader 包装了一个渲染方案,这些方案由一个个通道(Pass)来执行的,SubShader可以包括很多通道块,每个Pass都能使几何体渲染一次;
2: Pass基本语法:
Pass { [Name and Tags] [RenderSetup] [Texture Setup]}
Pass块的Name引用此Pass,可以在其它着色器的Pass块中引用它,减少重复操作,Name命令必须打大写;
- RegularPass渲染设置
1: Lighting 光照: 开启关闭定点光照 On/Off
2: Material{材质块}: 材质,定义一个使用定点光照管线的材质;
3:ColorMaterial: 颜色集 计算定点光照的时使用顶点颜色;
4: SeparateSpecular: 开光状态 开启或关闭顶点光照相关的镜面高光颜色,On/Off;
5: Color 设置定点光照关闭时的所使用的颜色;
6: Fog{雾块}: 设置雾参数;
7: AlphaTest: Alpha测试
8: ZTest: 深度测试模式;
9: ZWrite: 深度写模式;
10: Blend: 混合模式 SourceBlendMode, DestBlendMode, AlphaSourcesBlendMode, AlphaDstBlendMode;
11: ColorMask 颜色遮罩: 设置颜色遮罩,颜色值可以由RGB或A或0或R,G,B,A的组合,设置为0关闭所有颜色通道渲染;
12: Offset偏移因子: 设置深度偏移;
- 特殊通道Pass
1: UsePass: 插入所有来自其它着色器的给定名字的通道;
UsePass ”Shader/Nmae”, Name为着色器通道;
UsePass “Specular/BASE” // 插入Specular中为Bass的通道;
2: GrabPass {}: 一种特殊通道类型,他会捕获物体所在的位置的屏幕的内容,并写入一个纹理中,这个纹理能被用于后续通道中完成一些高级图像特效,后续通道可以使用
_GrabTexture进行访问;
3: GrabPass{“纹理名称”} 捕获屏幕内容到指定纹理中,后续通道可以通过纹理名称来访问;
- Fallback
1:降级: 定义在所有子着色器之后,如果没有任何子着色器能运行,则尝试降级;
2: Fallback “着色器名称”;
3: Fallback Off;
没有降级,并且不会打印任何警告;
- Category
1:分类是渲染命令的逻辑组。例如着色器可以有多个子着色器,他们都需要关闭雾效果,和混合
Shader “xxxx” {
Categroy {
Fog { Mode Off }
SubShader {…}
SubShader {…}
}
}
Unity坐标系转换
1: transform.localToWorldMatrix 局部转世界的矩阵;
2: transfrom.worldToLocalMatrix 世界坐标转局部坐标矩阵;
MultiplyPoint, MultiplyPoint3x4 MultiplayVector 来进行坐标变换;
4: shader中 左乘_World2Object矩阵来实现世界坐标转局部坐标变换;
5: shader中左乘_Object2World矩阵来实现局部转世界的转换;
6: UNITY_MATRIX_MV 基本变换矩阵 x 摄像机矩阵;
7: UNITY_MATRIX_MVP 基本变换矩阵x摄像机矩阵x投影矩阵;
8: UNITY_MATRIX_V 摄像机矩阵;
9: UNITY_MATRIX_P 投影矩阵;
10: UNITY_MATRIX_VP摄像机矩阵x投影矩阵;
11: UNITY_MATRIX_T_MV (基本变换矩阵 x 摄像机矩阵) 转置矩阵;
12: UNITY_MATRIX_IT_MV(基本变换矩阵 x 摄像机矩阵) 的逆转置矩阵;
13: UNITY_MATRIX_TEXTURE0 纹理变化矩阵;
顶点片元着色器
1: 控制灵活,但不能参与光照计算;
2: 在着色器中插入Cg代码段,编写在CGPROGRAM 与 ENDCG之间;
3: 编译指令:
#pragma 控制 着色器代码编译;
#pragma vertex name 将名称为name的函数编译为顶点着色器;
#pragma fragment name 将名称为name的函数编译为片元着色器;
4: 参数和返回值有语义修饰
常用语义修饰
1:POSITION : 位置
2:TANGENT : 切线
3: NORMAL: 法线
4: TEXCOORD0: 第一套纹理
5: TEXCOORD1: 第二套纹理
6: TEXCOORD2: 第三套纹理
7: TEXCOORD3: 第四套纹理
8: COLOR: 颜色
Cg
1:语法和C语言类似,有对应的编译器,程序是给显卡运行;
2: 可以从渲染流水线中获得对应的输入;
3: 指定的输出能流入下一个流水线模块;
4: 操作符号和C语言一样,可以使用 +, -, * / <, >, <=, >= 等运算;
5: Cg提供了float half double 浮点类型;
7: Cg 支持定点数 fixed来高效处理 某些小数;
8: Cg使用int来表示整数;
9: bool 数据类型来表示逻辑类型;
10:sampler*,纹理对象的句柄, sampler/1D/2D/3D/CUBE/RECT
11: 内置向量数据类型: float4(float, float, float, float), 向量长度不能超过4;
12: 内置矩阵数据类型: float1x1 float2x3 float4x3 float4x4;不能超过4x4;
13: 数组类型float a[10]; 10个float, float4 b[10], 10个float4;
14: 语义绑定 float4 a : POSITION,返回值也可以语义绑定;
- 结构体 语义
1: struct name {
类型 名字;
// 尽量不要使用;
返回值 函数名称(参数) { // 如果有成员函数,数据成员定义在函数之前;
}
};
2:输入语义与输出语义:
语义: 一个阶段处理数据,然后传输给下一个阶段,那么每个阶段之间的接口, 例如:顶点处理器的输入数据是处于模型空间的顶点数据(位置、法向量),输出的是投影坐标和光照颜色;片段处理器要将光照颜色做为输入;C/C++用指针,而Cg通过语义绑定的形式;
输入语义: 绑定接收参数,从上一个流水线获得参数;
输出语义: 绑定输出参数到下一个流水线模块;
语义: 入口函数上有意义(顶点着色入口,像素着色入口),普通的函数无意义; - 内置标准函数库
1:abs(num)绝对值;
2: 三角函数;
3: cross(a, b) 两个向量的叉积;
4: determinant(M)矩阵的行列式;
5: dot(a, b) 两个向量的点积;
6: floor(x)向下取整;
7: lerp(a, b, f), 在a, b之间线性插值;
8: log2(x) 基于2为底的x的对数;
9: mul(m, n): 矩阵x矩阵, 矩阵x向量, 向量x矩阵;
10: power(x, y) x的y次方;
11: radians(x) 度转弧度;
12: reflect(v, n) v 关于法线n的反射向量;
13: round(x) 靠近取整;
14: tex2D(smapler, x) 二维纹理查找
15: tex3Dproj(smapler, x) 投影三维纹理查找;
16: texCUBE 立方体贴图纹理查找; - Unity内置函数
1: 引用Unity自带的函数库: #include “UnityCG.cginc” Unity–>Edit–>Data–>CGIncludes;
2: TRANSFORM_TEX: 根据顶点的纹理坐标,计算出对应的纹理的真正的UV坐标;
3: 使用属性的变量: 在shader里面需要使用属性变量还需要在shader中定义一下这个变量的类型和名字;
名字要保持一致;
4: 外部修改shader的编辑器上的参数值;