# 组织结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Shader "Name"{
Properties{
//开放到材质面板的属性
}
SubShader{
//顶点-片段着色器
//或者表面着色器
//或者固定函数着色器
}
SubShader{
//更加精简的版本
//为了能在旧的图形设备商运行
}
...
Fallback "Name"
}

# 数值类型属性

1
2
name("display name",Float) = number
name("display name",Range(min,max)) = number

# 颜色向量类属性

1
2
name("display name",Color) = (number,number,number,number)
name("display name",Vector) = (number1,number2,number3,number4)

# 纹理贴图类属性

1
2
3
name("display name",2D) = "defaulttexture" {}
name("display name",Cube) = "defaulttexture" {}
name("display name",3D) = "defaulttexture" {}

漫反射贴图,法线贴图都属于 2D 类型 Cube 简称 Cube map texture 立方体纹理,如 skybox 和 reflection prob 3D 纹理只能代码创建

# SubShader - Tags

每个 SubShader 都可以设置一个或多个 Tags (标签) 或者渲染状态 (States), 然后至少定义一个 Pass
每个 Pass 都会进行一次渲染,多个 Pass 的情况下尽量少出现

# Tags

# Queue

Queue 标签确定物体的渲染顺序

  • Background - 最先执行渲染,一般用来渲染天空盒 (Skybox) 或者背景 1000
  • Geometry - 非透明的几何体通常使用这个队列,当没有声明渲染队列的时候,Unity 会默认使用这个队列 2000
  • AlphaTest - Alpha 测试的几何体会使用这个队列,之所以从 Geometry 队列单独拆分出来,是因为当所有实体都绘制完之后再绘制 Alpha 测试会更高效. 2450
  • Transparent - 在这个队列的几何体按由远及近的顺序进行绘制,所有进行 Alpha 混合的几何体都应该使用这个队列,例如玻璃材质、粒子特效等 3000
  • Overlay - 用来叠加渲染的效果,例如镜头光晕等,放在最后渲染 4000

当然,也可以自己定义渲染队列,比如:

1
Tags {"Queue" = "Geometry+1"}

这个非常有用,比如透明水一般会在所有不透明几何体之后,透明几何体之前绘制,所以透明水的渲染队列一般会使用 "Queue" = "Transparent-1"

# RenderType (渲染类型)

可以将 Shader 划分为不同的类别,用于后期进行 Shader 替换或者产生摄像机的深度纹理.

  • Opaque
  • Transparent
  • TransparentCutout
  • Background
  • Overlay
  • TreeOpaque
  • TreeTransparentCutout
  • TreeBillboard
  • Grass
  • GrassBillboard

# DisableBatching

当使用批处理 (Batching) 的时候,几何体会被变换到世界空间,模型空间会被丢弃。这会导致某些使用模型空间顶点数据的 shader 最终无法实现所希望的效果

  • “DisableBatching” = “True”
  • “DisableBatching” = “False”
  • “DisableBatching” = “LODFading”

# ForceNoShadowCasting

该物体不会对别的物体产生投影

True/False

# IgnoreProjector

是否希望物体受到 Projector (投影机) 的投射.

# Pass 的渲染状态

如果想要某些 Pass 的渲染状态不影响到其他 Pass

  • Cull(Cull Back Front Off)
  • ZTest(LessGreaterLEqualGEqualEqualNotEqualAlways)
  • ZWrite(ZWrite OnOff)
  • Blend(Blend sourceBlendMode destBlendMode)
  • ColorMask (RGBA0 或 RGBA 的任意组合)

# Fallback

# 顶点函数和片段函数中支持的数据类型

  • fixed,fixed2,fixed3,fixed4 (低精度浮点值) 数值区间为 [-2.0,2.0]
  • half,half2,half3,half4 中精度浮点值,使用 16 位精度进行存储,数值区间为 [-60000,60000]
  • float,float2,float3,float4 高精度浮点值,使用 32 为精度进行存储,用于存储顶点坐标,为标准化的向量,纹理坐标等
  • struct 结构体,可以将多个变量整体进行打包

# 语义

顶点着色器输入语义

  • POSITION : 顶点的坐标信息,通肠胃 float3 或 float4 类型
  • NORMAL : 顶点的发现信息,通肠胃 float3 类型
  • TEXCOORD0 : 模型的第一套 UV 坐标,通常为 float2、float3 或 fixed4 类型,TEXCOORD0 到 TEXCOORD3 分别对应第一到第四套坐标
  • TANGENT : 顶点的切向量,通肠胃 float4 类型
  • COLOR : 顶点的颜色信息,通常为 float4 类型

顶点着色器输出和片段着色器输入语义

  • SV_POSITION : 顶点在裁切空间中的,float4 类型
  • TEXCOORD0、TEXCOORD1 等:用于声明任意高精度数据,例如纹理坐标、向量等
  • COLOR0、COLOR1 等:用于声明任意低精度的数据,例如顶点颜色、数值区间 [0,1] 的变量

# 开放属性与 CG 属性变量的对应关系

Float,Range : 浮点和范围类型的属性,根据精度可以使用 float,half 或 fixed 声明
Color,Vector : 颜色和向量类的属性,可以使用 float4,half4 或 fixed4 声明,其中颜色使用低精度的 fixed4 声明可以减少性能消耗 2D : 2D 纹理贴图,使用 sample2D 声明
Cube : 立方体贴图属性,使用 samplerCube 声明
3D : 3D 纹理贴图属性,使用 sampler3D 声明

# UV 坐标

纹理坐标的计算公式 texcoord = uv*{TextureName}.xy + {TextureName}.zw 必须先缩放再偏移 tex2D () 函数是采样函数,从主纹理坐标上对 texcoord 采样,最终返回采样后的结果,然后乘上 MainColor

# 在 Shader 中使用立方体贴图

立方体采样使用的函数是: texCUBE (Cube,r) 顶点坐标变换到世界坐标:

1
worldPos = mul(unity_ObjectToWorld,vertex)

发现向量转换到世界坐标:

1
worldNormal = mul(normal,(float3x3)unity_WorldToObject)

先记住这个结论,为了避免非统一缩放 (即 x,y,z) 不统一缩放,故需要使用法线向量右乘逆矩阵的方法对其进行空间变换

# Shader 中内置变量摘记

_Time: 关卡从开始到现在所运行的时间,4 个分量分别为 t/20,t,t*2,t*3 _SinTime: 将 t/8,t/4,t/2,t 输入到正弦函数中 _CosTime unity_DeltaTime: 每一帧的递增时间,4 个分量分别为 dt,1/dt,smoothDt,1/smoothDt