目录
1.表面着色器
2.定义入口函数
3.其它可选参数
4.Input 结构附加数据
5.SurfaceOutput 结构体
6.unity坐标系转换
7.LOD
8.渲染队列
9.混合模式
10.Alpha 测试
11.深度测试
12.通道遮罩
13.面剔除
1:表面着色器包括4个函数:
(1): 顶点变换函数;
(2): 表面着色函数;
(3): 光照模型;
(4): 最终颜色修改函数;
2: 表面着色器最终会被编译为一个复杂的顶点着色程序;
1:#pragma surface 入口函数名称 光照模型 [Options]
2: suface 后面跟 表面着色的入口函数 surf(Input IN, inout SurfaceOutput o);
3: 光照模型:
(1)系统内置 Lambert(漫反射光照) BlinnPhong (高光光照)
(2)自定义光照: 名字为Name
half4 Lighting
half4 Lighting
half4 Lighting
4: vertex: name vertex入口函数:
void
half4
5: finalcolor: name 最终颜色修改函数:
void
1:alpha: Alpha 混合模式,用户半透明着色器;
2: alphatest: varirableName Alpha测试模式,用户透明镂空着色器。
3: exclude_path:prepass 使用指定的渲染路径;
4: addshadow: 添加阴影投射器和集合通道;
5: dualforward: 将双重光照贴图用于正向渲染路径中;
6: fullforwardshadows 在正向渲染路径中支持的所有的阴影类型;
7: decal: add 附加印花着色器;
8: decal: blend 附加半透明印花着色器;
9: softvegetation 使用表面着色器,仅在Soft Vegetation 开启时被渲染;
10: noambient 不使用任何光照
11: novertexlights 在正向渲染中不适用球面调和光照或逐点光照;
12: nolightmap 在这个着色器上禁用光照贴图;
13: nodirlightmap 在这个着色器上禁用方向光照贴图;
14: noforwardadd 禁用正向渲染添加通道;
15: approxview: 对于有需要的着色器,逐顶点而不是逐像素计算规范化视线方向。
16: halfasview: 将半方向传递到光照函数中。
Input:包含着色所需要的纹理坐标 uv纹理名字;使用第二张纹理是uv2纹理名字;
附加数据:
1:float3 viewDir 视图方向。
2:float4 color 每个顶点的颜色插值
3: float4 screenPos 屏幕空间中的位置。
4: float3 worldPos 世界坐标空间;
5: float3 worldRef1 世界空间中的反射向量;
6: float3 worldNormal 世界空间中的法线向量;
7: float3 worldRef1; INTERNAL_DATA 世界坐标反射向量, 但必须表面着色写入o.Normal参数;
8: float3 worldNormal; INTERNAL_DATA 世界坐标法线向量, 但必须表面着色写入o.Normal参数;
SurfaceOutput:
1: half3 Albedo: 漫反射的颜色值;
2: half3 Normal: 法线坐标;
3: half3 Emission; 自发光颜色;
4: half Specular; 镜面反射系数;
5: half Gloss; 光泽系数;
6: half Alpha; 透明度系数; SurfaceOutputStandard:
7: half Smoothness; // 0=粗糙, 1=光滑
8: half Metallic; // 0=非金属, 1=金属
SurfaceOutputStandardSpecular:
fixed3 Albedo;
fixed3 Specular;
fixed3 Normal;
half3 Emission;
half Smoothness; // 0=粗糙, 1=光滑
half Occlusion; // 遮挡(默认1)
fixed Alpha;
1: transform.localToWorldMatrix 局部转世界的矩阵;
2: transfrom.worldToLocalMatrix 世界坐标转局部坐标矩阵;
MultiplyPoint, MultiplyPoint3x4 MultiplayVector 来进行坐标变换;
4: shader中 左乘unity_WorldToObject矩阵来实现世界坐标转局部坐标变换;
5: shader中左乘unity_ObjectToWorld矩阵来实现局部转世界的转换;
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 纹理变化矩阵;
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/com_surface"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
//surf:自定义入口函数
//Standard:光照模型
//fullforwardshadows:其它可选参数(阴影类型)
//vertex: vert 顶点变换函数以及函数名称
#pragma surface surf Standard /*fullforwardshadows*/ vertex: vert
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;//uv 纹理名称
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
// 顶点入口
void vert (inout appdata_full v) {
//UnityObjectToClipPos==mul(UNITY_MATRIX_MVP, v.vertex);
v.vertex = UnityObjectToClipPos(v.vertex);
}
//表面着色的入口函数
//Input IN(IN要大写)
//SurfaceOutput 与SurfaceOutputStandard的区别,多了Smoothness,Metallic
//
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
//保底
FallBack "Diffuse"
}
1:LOD Level of Detail, 根据LOD来设置使用不同版本的Shader;
2:着色器中给SubShader一个LOD值,程序来设置这个shader的LOD值,只有第一个小于等于LOD值subShader才会被执行;
3: 每个shader最多只会有一个SubShader被使用;
4: 通过Shader maximumLOD来设置最大的LOD值;
5: 设置全局的LOD值,Shader.globalMaximumLOD;
6: Unity内置着色器分LOD等级:
(1)VertexLit kind of shaders 100
(2) Decal, Reflective VertexLit 150
(3)Diffuse 200
(4)Difuse Detail 250
(5) Bumped, Specular 300
(6) BumpedSpecular 400
(7) Parallax 500
(8) Parallax Specular 600
Shader "Custom/LODShader" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
// 每次只会根据情况来选择一个可执行的SubShader
// 找到第一个<= Shader.maximumLOD 这个subShader执行;
SubShader {
Tags { "RenderType"="Opaque" }
LOD 600 // LOD
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
o.Albedo = fixed3(1.0, 0.0, 0.0);
}
ENDCG
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 500 // LOD
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
o.Albedo = fixed3(0.0, 1.0, 0.0);
}
ENDCG
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 400 // LOD
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
o.Albedo = fixed3(0.0, 0.0, 1.0);
}
ENDCG
}
FallBack "Diffuse"
}
1:渲染队列标签可选值:
(1)Background 背景,对应的值为1000;
(2) Geometry(default) 几何体对应的值为2000, 这个队列是默认的渲染队列,大多数不透明的物体;
(3)AlphaTest Alpha测试,对应值为2450, alpha测试的几何体使用这种队列,它是独立于 Geometry的队列,它可以在所有固体对象绘制后更有效的渲染采用Alpha测试的对象;
(4)Transparent:透明,对应值3000, 这个渲染队列在Geometry被渲染,采用从后向前的次序; 任何有alpha混合的对象都在这个队列里面渲染;
(5) Overlay 覆盖对应值为4000, 这个渲染队列是最后渲染的物体;
2: Unity 渲染模式: 普通物体从前向后, Alpha从后向前;
3:渲染队列的数值决定了Unity在渲染场景物体时的先后顺序,关闭深度测试的情况下;
Shader "Custom/RenderQueue" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
// +左右不能用空格,多个tag,不能用逗号
Tags { "RenderType"="Opaque" "Queue"="Geometry+100" }
LOD 200
ZTest off //改变渲染队列需要关闭深度测试
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
o.Albedo = _Color.rgb;
}
ENDCG
}
FallBack "Diffuse"
}
1:在所有计算完成后,决定当前的计算结果输出到帧缓冲区时,如何混合源和目标,通常用来绘制半透明的物体;
2: Blend Off 关闭混合 3: Blend 源因子,目标因子: 配置并开启混合,产生的颜色和因子相乘,然后两个颜色相加
4: Blend 源因子,目标因子, 源因子A,目标因子A: 源因子与目标因子用户混合颜色值,源因子A,与目标因子A,用于混合alpha
5: BlendOp操作命令: 不是将颜色混合在一起,而是对他们进行操作,主要有: Min, Max, Sub, RevSub
6:混合因子的类型:
One 使用源或目标色完全显示出来; OneMinusSrcColor 阶段值 * (1-源颜色的值)
Zero 删除源颜色或目标颜色; OneMinusSrcAlpha 阶段值 * (1-源颜色的Alpha值)
SrcColor 这个阶段的值*源颜色值; OneMinusDstColor 阶段值 * (1-目标颜色的值);
DstColor 这个阶段的值* 帧缓冲颜色值; OneMinusDstAlha 阶段值 * (1-目标颜色Alpha值)
DstAlpha这个阶段的值 * 帧缓冲源Alpha值 SrcAlpha这个阶段的值 * 源颜色Alpha值
6:一般放在放在Pass通道里面
1:Alpha测试: 阻止片元被写到屏幕的最后机会, 最终渲染出来的颜色计算出来后可通过透明度和最后一个固定值比较,如果通过测试则绘制次片元,否则丢弃此片元;
2: AlphaTest Off/On: 开启/关闭Alpha测试,默认是关闭的;
3:比较测试值的模式: Greater >, GEqual >=, Less <, LEqual <=, Equal ==, NotEqual !=, Always (永远渲染), Never(从不渲染);
4: AlphaTest 条件 [变量] / 常数, 一般放在放在Pass通道里面;
1:为了使近距离的物体挡住远距离的物体,当片元写入到缓冲的时候,需要将片元的深度值与缓冲区的深度值进行比较,测试成功写入帧缓冲区;
2: ZWrite 深度写开关, 控制是否将深度Z的片元写入缓冲区中,如果不绘制透明物体设置为On, 否则的话设置为Off,默认为On;
3: ZTest 深度测试模式: 设置深度测试的执行方式,默认为LEqual,深度测试的模式: Less <, Greater >, LEqual <= , GEqual >=, Equal ==, NotEqual !=, Always 总是绘制,关闭深度测试;
4: ZTest 条件
5: 一般放在放在Pass通道里面;
1:通道遮罩可以是开发人员指定渲染结果输出的通道,而不是通常情况下的RGBA四个通道;
2:可选的是RGBA的任意组合以及0,如果为0意味着不会写入到任何通道;
3: ColorMask RG ... ColorMask 0
1:通过不渲染背对摄像机的几何体的面来提高性能优化错误,所有的几何体都包含正面和反面
2: 面剔除操作,大多数都是封闭的物体,所以不需要绘制背面;
3: 面剔除操作:
Cull Back: 不绘制背对摄像机的面,默认项
Cull Front, 不绘制面向摄像机的面,
Cull Off, 关闭面剔除操作