5.ShaderLab-ShaderLab语法规则-Shader的子着色器-基本构成
5.1 知识点
知识回顾
ShaderLab主要由4个部分组成:
- Shader的名字
- Shader的属性
- 1~n个子着色器
- 备用的Shader
第一部分:
Shader "着色器名字"
{
// 第二部分
Properties
{
// 材质面板上可以看到的属性
}
// 第三部分
SubShader
{
// 顶点-片段着色器 或 表面着色器 或 固定函数着色器
}
SubShader
{
// 更加精简的版本
// 目的是适配旧设备
}
// 可以有n个SubShader代码块
// 第四部分
Fallback "备用的Shader"
}
SubShader语句块的作用
- 每一个Shader中都会包含至少一个SubShader。
- 当Unity想要显示一个物体的时候,就会在Shader文件中去检测这些SubShader语句块,然后选择第一个能够在当前显卡运行的SubShader进行执行。
- 因此在一个Shader当中实现一些高级效果时,为了避免在某些设备上无法执行,可能会存在多个SubShader语句块,用于适配这些低端设备。
- SubShader当中包含最终的渲染相关代码,决定了最终的渲染效果。
SubShader的基本构成
SubShader语句块中主要由3部分构成:
- 渲染标签:通过标签来确定什么时候以及如何对物体进行渲染
- 渲染状态:通过状态来确定渲染时的剔除方式、深度测试方式、混合方式等等内容
- 渲染通道:具体实现着色器代码的地方(每个SubShader语句块中至少有一个渲染通道,可以有多个)
第三部分:
SubShader
{
// 渲染标签
Tags { "标签名1" = "标签值1" "标签名2" = "标签值2" .....}
// 渲染状态
.....
// 渲染通道
Pass
{
// 第一个渲染通道
}
Pass
{
// 第二个渲染通道
}
// .............
}
在SubShader中每定义一个渲染通道Pass,就会让物体执行一次渲染。n个Pass,就会有n次渲染,在实现一些复杂渲染效果时需要使用多个Pass进行组合实现。但是我们要尽量减少它的数量,更多的Pass会增加性能消耗。
观察普通顶点着色器的结构
SubShader
{
// 1. 渲染标签
Tags { "RenderType"="Opaque" }
// 2. 渲染状态
LOD 100
// 3. 渲染通道
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
总结
SubShader子着色器基本构成为:
- Tags(渲染标签)
- States(渲染状态)
- Pass(渲染通道1)
- Pass(渲染通道2)
- ….(渲染通道n)
在Shader文件中可以存在多个SubShader语句块。当Unity想要显示一个物体的时候,会在Shader文件中去检测这些SubShader语句块,然后选择第一个能够在当前显卡运行的SubShader进行执行。因此在一个Shader当中实现一些高级效果时,为了避免在某些设备上无法执行,可能会存在多个SubShader语句块,用于适配这些低端设备。
5.2 知识点代码
Lesson05_ShaderLab_ShaderLab语法规则_Shader的子着色器_SubShader基本构成
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson05_ShaderLab_ShaderLab语法规则_Shader的子着色器_SubShader基本构成 : MonoBehaviour
{
void Start()
{
#region 知识回顾
//ShaderLab主要由4个部分组成
//1.Shader的名字
//2.Shader的属性
//3.1~n个子着色器
//4.备用的Shader
//第一部分
//Shader "着色器名字"
//{
// //第二部分
// Properties
// {
// //材质面板上可以看到的属性
// }
// //第三部分
// SubShader
// {
// //顶点-片段着色器 或 表面着色器 或 固定函数着色器
// }
// SubShader
// {
// //更加精简的版本
// //目的是适配旧设备
// }
// .....可以有n个SubShader代码块
// //第四部分
// Fallback "备用的Shader"
//}
#endregion
#region 知识点一 SubShader语句块的作用
//每一个Shader中都会包含至少一个SubShader
//当Unity想要显示一个物体的时候
//就会在Shader文件中去检测这些SubShader语句块
//然后选择第一个能够在当前显卡运行的SubShader进行执行
//因此在一个Shader当中实现一些高级效果时
//为了避免在在某些设备上无法执行
//可能会存在多个SubShader语句块,用于适配这些低端设备
//SubShader当中包含最终的渲染相关代码,决定了最终的渲染效果
#endregion
#region 知识点二 SubShader的基本构成
//SubShader语句块中主要由3部分构成
//1.渲染标签:通过标签来确定什么时候以及如何对物体进行渲染
//2.渲染状态:通过状态来确定渲染时的剔除方式、深度测试方式、混合方式等等内容
//3.渲染通道:具体实现着色器代码的地方(每个SubShader语句块中至少有一个渲染通道,可以有多个)
//第三部分
//SubShader
//{
// 1.渲染标签
// Tags{ "标签名1" = "标签值1" "标签名2" = "标签值2" .....}
//
// 2.渲染状态
// .....
//
// 3.渲染通道
// Pass
// {
// 第一个渲染通道
// }
// Pass
// {
// 第二个渲染通道
// }
// .............
//}
//注意:
//在SubShader中每定义一个渲染通道Pass,就会让物体执行一次渲染
//n个Pass,就会有n次渲染,在实现一些复杂渲染效果时需要使用多个Pass进行组合实现
//但是我们要尽量减少它的数量,更多的Pass会增加性能消耗
#endregion
#region 总结
//SubShader子着色器基本构成为:
// --------Tags(渲染标签)
// |--------States(渲染状态)
//SubShader---|--------Pass(渲染通道1)
// |--------Pass(渲染通道2)
// |--------....(渲染通道n)
//在Shader文件中可以存在多个SubShader语句块
//当Unity想要显示一个物体的时候
//会在Shader文件中去检测这些SubShader语句块
//然后选择第一个能够在当前显卡运行的SubShader进行执行
//因此在一个Shader当中实现一些高级效果时
//为了避免在在某些设备上无法执行
//可能会存在多个SubShader语句块,用于适配这些低端设备
#endregion
}
}
Lesson05_NewUnlitShader.shader
Shader "ShaderTeach/Lesson05_NewUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
// 1.渲染标签
Tags { "RenderType"="Opaque" }
// 2.渲染状态
LOD 100
// 3.渲染通道
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com