//U3D用的shader语言叫ShaderLab,基础语法官方文档地址
//https://docs.unity3d.com/Manual/SL-Shader.html
//开头指明名字,可以在别的shader中通过名字调用该shader的Pass什么的
//UsePass "ShaderName/PassName"
Shader "ShaderName"
{
//属性定义
Properties
{
[DisplayType]_Name("Display Name", type) = defaultValue {options}
[DisplayType]_Name("Display Name", type) = defaultValue {options}
//改Shader暴露的参数,在需要使用的Pass的CG代码段里需要重新声明一次
//type包括
// Color 一种颜色,由RGBA四个量来定义
// 2D 一张2的阶数大小(256,512之类)的贴图。
// Rect 一个非2阶数大小的贴图
// Cube 即Cube map texture(立方体纹理)
// Float 任意一个浮点数
// Vector 一个四维数
// Range(min, max) 一个介于最小值和最大值之间的浮点数
//defaultValue
//color 的是 (0,0,0,0)
//Rrct 的是 "white" {}
//{option}: 它只对2D,Rect或者Cube贴图有关,最少一对什么都不含的空白的{},
// 选项(多个选项,可以使用空白分隔): ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal中的一个
//DisplayType可选,告诉编辑器如何显示这个属性,常见的类型
// [Toggle] Display as a toggle
// [Enum(One,1,SrcAlpha,5)] 展示位枚举
// 共有两种自定义界面的方式,详细见自定义编辑界面笔记
//在自定义函数部分中可以用[name]的方式使用 比如 Blend [_SrcBlend] [_DstBlend]
//Properties块定义的参数是给材质球用的,用代码的方式可以有更多类型的参数,但不能被保存下来
}
//子着色器,可以包含多个,根据不同的条件选择一个执行(硬件条件之类的)
//从上到下; SubShader的标签、Pass的标签;SubShader是否和当前的GPU兼容
SubShader
{
//硬件将通过判定这些标签来决定什么时候调用该着色器
//可选可以啥都不写全部走默认值
Tags {
"Queue"="Transparent+10"
//Queue 渲染顺序,从小到大调用,可以用加减法微调,预定义的Queue有
//Background 1000 - 最早被调用的渲染,用来渲染天空盒或者背景
//Geometry 2000 - 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
//AlphaTest 2450 - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
//Transparent 3000 - 以从后往前的顺序渲染透明物体
//Overlay 4000 - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
"RenderType"="Transparent"
//Unity可以运行时替换符合特定RenderType的所有Shader,与Camera.RenderWithShader或Camera.SetReplacementShader配合使用
//Unity内置的RenderType包括:
//Opaque: 不透明的物
//Transparent: 透明着色器
//Background: 天空盒都
//Overlay: GUI、镜头光晕等
//可以自定义替换标签 "Distort"="On"
//其他常用
"IgnoreProjector"="True" //不接受Projector组件的投影
"ForceNoShadowCasting"="True" //不产生阴影
}
//剔除规则 默认剔除背面
Cull Back | Front | Off
//是否写入深度缓存 默认写入
ZWrite On | Off
//深度检查 默认小于等于
ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
//深度偏移 用来解决z-fighting现象 比如 Offset 3, 0
Offset Factor, Units
//混合模式指令 也可以放在Pass中 详见Blending笔记
Blend SrcAlpha OneMinusSrcAlpha
//Blend Off 关闭混合,默认值
//Blend SrcFactor DstFactor 最终值=原值*SrcFactor + 屏幕值*DstFactor
//Level of Detail, Quality Settings中设定 MaximumLOD level,从上到下选择第一个起效的SubShader
//代码用 Shader.globalMaximumLOD 控制
//一个SubShader一个LOD值 不支持Pass级的控制
LOD 200 //默认值为200
//支持多pass 多次绘制
Pass
{
//可选 模板缓冲 每个像素有一个8位(0-255)的模板值
//目标测试位于深度检测之前,额外的一个条件决定 片元shader是否调用
stencil
{
Ref referenceValue //参考值,这个值将用来与模板缓冲中的值进行比较
ReadMask readMask //读遮罩,读取是按位与(&)操作,默认值255
WriteMask writeMask //写遮罩,默认值255
Comp comparisonFunction //比较方式 默认 always
//参考值&readMask Comp 当前缓冲值&readMask
//[Greater, GEqual, Less, LEqual, Equal, NotEqual, Always, Never]
Pass stencilOperation //通过模板测试和深度测试时的处理方式 默认值:keep
Fail stencilOperation //模板测试失败时 默认值:keep
ZFail stencilOperation //模板测试通过 深度测试失败 默认值:keep
//处理方式
//Keep 保留当前缓冲中的内容,即stencilBufferValue不变。
//Zero 将0写入缓冲,即stencilBufferValue值变为0。
//Replace 将参考值写入缓冲,即将referenceValue赋值给stencilBufferValue。
//IncrSat stencilBufferValue加1,如果stencilBufferValue超过255了,那么保留为255,即不大于255。
//DecrSat stencilBufferValue减1,如果stencilBufferValue超过为0,那么保留为0,即不小于0。
//Invert 将当前模板缓冲值(stencilBufferValue)按位取反
//IncrWrap 当前缓冲的值加1,如果缓冲值超过255了,那么变成0,(然后继续自增)
//DecrWrap 当前缓冲的值减1,如果缓冲值已经为0,那么变成255,(然后继续自减)
}
//可选,用于Pass的重用
Name "PassName"
//可选 Pass的Tags有和SubShader公用的也有专用的
Tags {
"LightMode"="ForwardBase"
//最重要的一个tag 指定用哪一种渲染路径,保证U3D的光照变量能被正确赋值
//ForwardBase 前向渲染,会计算环境光,最重要的平行光,逐顶点光源和Lightmaps
//ForwardAdd 前向渲染,会计算额外的逐像素光源,一个Pass对应一个光源
//Always 永远都渲染,但不处理光照
//Deferred 延迟渲染,会计算G-buffer
//ShadowCaster 把物体渲染到阴影映射纹理或一张深度纹理中
}
//可以改变改pass的一些参数 不使用subshader的参数
//比如 Cull Zwrite Ztest 等
//标记CG代码开始
CGPROGRAM
//#pragma 编译指令段 详见 https://docs.unity3d.com/Manual/SL-ShaderPrograms.html
//指明顶点Shader和片元shader的函数名字
#pragma vertex vert
#pragma fragment frag
//编译目标model版本
#pragma target name
//2.5(默认) 数字越高,要求越高
//多版本Shader 会生成多个版本的Shader 详见multiple shader笔记
#pragma multi_compile ...
//or
#pragma shader_feature ...
//指定渲染平台
#pragma only_renderers gles gles3
#pragma exclude_renderers d3d9 d3d11 opengl
//常见手游平台
//gles - OpenGL ES 2.0
//gles3 - OpenGL ES 3.x
//metal - iOS/Mac Metal
//cginc包,支持自定义,但是要写明路径,默认路径为Shader所在目录
#include "UnityCG.cginc"
#include "../Lib/MyTools.cginc"
//数据类型声明
//基础精确
//float:32位高精度浮点数。
//half: 16位中精度浮点数。范围是[-6万, +6万],能精确到十进制的小数点后 3.3 位。
//fixed:11位低精度浮点数。范围是[-2, 2],精度是 1/256 ≈ 0.004
//都何以组合为向量或是矩阵比如 half3 fixed4 float4x4 等
//颜色和单位向量,使用fixed 其他情况,尽量使用half;否则才使用float。
//材质类型需要一条额外参数配置
sampler2D _XXXX;
float4 _XXXX_ST;
//uniform 在UnityShader中可以省略
uniform fixed3 XX;
fixed XXX;
//程序传给定点着色器的数据
struct a2v
{
//类型 名字 : 绑定的语义(从哪里读取数据,把数据输出到哪里)
//常见语义如下
float4 vertex : POSITION; //顶点的位置
float4 normal : NORMAL; //顶点的法线方向
float4 tangent : TANGENT; //顶点的切线方向
fixed4 color : COLOR; //顶点的颜色
float2 uvn : TEXCOORDn; //n从0开始,第n+1套纹理坐标
};
//定点着色器给片元着色器的数据
//经由顶点着色器的输出进行插值运算得出
struct v2f
{
float4 vertex : SV_POSITION; //必须有,有固定含义,表名裁剪空间的定点坐标
float4 custom : TEXCOORDn; //n:0~7 无固定含义 用来做一些自定义数据的传递
};
v2f vert (a2v v)
{
v2f o;
... ...
return o;
}
//SV_Target 即 SystemValue_RenderTarget
fixed4 frag (v2f i) : SV_Target
{
... ...
//最终的结果是一个颜色 带一个alpha值
return fixed4(baseCol, alpha);
}
ENDCG
}
}
//可选 备用shader
FallBack "Diffuse"
//当本Shader的所有SubShader都不支持当前显卡,就会使用FallBack语句指定的另一个Shader。
//FallBack最好指定Unity自己预制的Shader实现,因其一般能够在当前所有显卡运行。
// FallBack Off //将关闭FallBack
//可选 自定义编辑器
CustomEditor "CustomShaderGUI类名"
}