Unity Shader 基础
创建shader, unity 5.x中有4种模板可以选择
1 Standard Surface Shader
会产生一个包含标准光照模型(使用了Unity 5中新添加的基于物理的渲染方法)的表面着色器模板
2 Unlit Shader
会产生一个不包含光照(但包含雾效)的基本顶点/片元着色器
3 Image Effect Shader
为我们实现各种屏幕后处理效果提供了一个基本模板
4 Compute Shader
会产生一种特殊的Shader文件,这类Shader旨在利用GPU的并行性来进行一些与常规渲染流水线无关的计算。
Unity Shader 基础:Shaderlab
Shaderlab 是Unity提供的一种专门为Unity Shader 服务的语言。
一个Unity Shader的基础结构:
Shader "ShaderNamer" {
Properties {
//属性
}
SubShader {
//显卡A使用的子着色器
}
SubShader {
//显卡B使用的子着色器
}
Fallback "VertexLit"
Properties {
//属性
}
SubShader {
//显卡A使用的子着色器
}
SubShader {
//显卡B使用的子着色器
}
Fallback "VertexLit"
Unity Shader 的结构
每个Shader文件的第一行都需要给定该Shader 的名字
Shader "Custom/ThisShaderName" { }
Properties 语义快中包含了一系列属性,这些属性将会出现在材质面板中
Properties {Name("dispaly name",PropertyType ) = DefaultValue
Name("dispaly name",PropertyType ) = DefaultValue
//更多属性
}
开发者声明这些属性是为了在材质面板中能够方便地调整各种材质属性。如果需要在shader中访问它们,需要使用每个属性的名字
Name(通常由一个下划线开始)。
dispaly name 是出现在材质面板的名字。
PropertyType 指定每个属性的属性类型。
DefaultValue指定一个默认值,将shader赋给某个材质球时,材质面板上就显示的就是这个默认值。
常见的一些属性:
_Int("Int",Int) = 2
_Float("Float",Float) = 1.5
_Range("Range",Range(0.0,5.0)) = 3.0
_Color ("Color", Color) = (1,1,1,1)
_Vector("Vector",Vector) = (2,3,6,1)
_2D("2D",2D) =""{}
_Float("Float",Float) = 1.5
_Range("Range",Range(0.0,5.0)) = 3.0
_Color ("Color", Color) = (1,1,1,1)
_Vector("Vector",Vector) = (2,3,6,1)
_2D("2D",2D) =""{}
_3D("3D",3D) ="black"{}
对于2D,Cube,3D 这类纹理类型,默认值的定义稍微复杂,它们的默认值是通过一个字符串后跟一个花括号来指定的。
重量级成员:SubShader
每个Unity Shader可以包含多个subshader语义快,为了提供对各个显卡的支持。如果没有则使用fallback。
SubShader{
//可选
[Tags]
// 可选
[RenderSetup] //状态设置
Pass
{
}
//other passes
}
[Tags] 是一个字符串类型的键值对,结构:
Tags{"TagName1" = "Value1"}
Pass
{
[Name]
[Tags]
[RenderSetup]
//other code
}
UsePass: 使用该命令来复用其他Shader的Pass;
Name "MyPassName" //定义该Pass的名称
UsePass "MyShader/MYPASSNAME" // 使用这个名字复用 名称要大写
Fallback
可以解释为:如果上面的subshader在这块显卡上都不能运行,那就使用这个最低级的shader吧!
语义:
Fallback "name"
//或者
Fallback Off
Unity的宠儿:表面着色器
表面着色器是Unity自己创造的一种着色器代码类型。它需要很少,带渲染代价很大。它存在的价值在于,
Unity为我们处理了很多光照细节,使得我们不需要在操心烦人的事儿。
示例代码:
Shader "Custom/NewSurfaceShader" {
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
o.Alpha = 1;
}
ENDCG
}
FallBack "Diffuse"
}
表面着色器被定义在CGPROGRAM和ENDCG之间,代码是使用CG/HLSL编写的。
Name "MyPassName" //定义该Pass的名称
UsePass "MyShader/MYPASSNAME" // 使用这个名字复用 名称要大写
Fallback
可以解释为:如果上面的subshader在这块显卡上都不能运行,那就使用这个最低级的shader吧!
语义:
Fallback "name"
//或者
Fallback Off
Unity的宠儿:表面着色器
表面着色器是Unity自己创造的一种着色器代码类型。它需要很少,带渲染代价很大。它存在的价值在于,
Unity为我们处理了很多光照细节,使得我们不需要在操心烦人的事儿。
示例代码:
Shader "Custom/NewSurfaceShader" {
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
o.Alpha = 1;
}
ENDCG
}
FallBack "Diffuse"
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
o.Alpha = 1;
}
ENDCG
}
FallBack "Diffuse"
}
最聪明的孩子:顶点/片元着色器。
在Unity中我们使用CG/HLSL语言来编写顶点/片元着色器。
Shader "Custom/NewSurfaceShader" {
SubShader {
Pass{
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma vertex vert
#pragma fragment frag
float4 vert(float4 v :POSITION) : SV_POSITION {
return mul (UNITY_MATRIX_MVP, V);
}
float4 frag() : SV_Target {
return fixed4 1.0,0.0,0.0,1.0);
}
ENDCG
SubShader {
Pass{
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma vertex vert
#pragma fragment frag
float4 vert(float4 v :POSITION) : SV_POSITION {
return mul (UNITY_MATRIX_MVP, V);
}
float4 frag() : SV_Target {
return fixed4 1.0,0.0,0.0,1.0);
}
ENDCG
}
}
}
}