请听我详细讲解“深入浅出掌握Unity ShaderLab语法基础”的完整攻略。
一、ShaderLab语法基础概述
ShaderLab是Unity中用于编写着色器的语言,它基于CG语言编写,同时又封装了一些常用的函数和数据结构,使得着色器开发变得容易而高效。在使用ShaderLab编写着色器时,需要定义一个合法的Shader程序,并且指定使用哪种渲染方式。Shader程序的主要结构框架如下:
Shader "Shader名称"{
Properties{ }
SubShader{
Tags { }
Pass{
CGPROGRAM
//顶点着色器程序
#pragma vertex VertexFunctionName
//片元着色器程序
#pragma fragment FragmentFunctionName
END CGPROGRAM
}
}
}
- Shader名称:指定Shader的名称,可以在Material中进行选择
- Properties:定义Shader所需要用到的参数,可以在Material中进行修改
- Tags:用于指定Shader的渲染方式、渲染队列等信息
- Pass:用于指定渲染管线(Pipeline)中各个阶段的状态
二、ShaderLab语法基础细节
1. Properties
在ShaderLab中,Properties用于定义Shader需要用到的参数,可以在Material中进行修改和调整。定义一个参数的基本语法如下:
Properties{
参数名称("_参数名称",类型)="默认值"{
}
}
例如,我们需要在Shader中添加一个颜色参数,可以这样定义:
Properties{
Color("_MainColor",Color)=(1,1,1,1){
}
}
上述代码中,参数名称为“_MainColor”,类型为“Color”,默认值为白色。
2. SubShader
SubShader用于定义一个合法的着色器程序,一般包括至少一个Pass块。每一个SubShader都必须包含一个顶点着色器(即顶点着色器程序)和一个片元着色器(即片元着色器程序)。
SubShader
{
Tags { }//标签
Pass
{
//CG Program
}
}
3. Tags
Tags用来指定如下几个信息:
- RenderType:指定要渲染的几何体类型
- Queue:用于指定渲染队列的优先级,渲染队列决定了渲染的顺序
- Name:指定SubShader名称
- DisableBatching:如果设置为True,则关闭批处理(Render Batching)
Tags{
"名字1"="值1"
"名字2"="值2"
}
例如,我们需要指定一个名为“CustomFragmentShader”的Shader程序,并且设置渲染类型(RenderType)为“Transparent”,优先级为“Transparent+1000”,可以这样写:
Tags{
"RenderType"="Transparent"
"Queue"="Transparent+1000"
"Name"="CustomFragmentShader"
}
4. Pass
Pass块用于定义渲染管线中各个阶段的状态。在Pass块中需要定义“顶点着色器”和“片元着色器”程序。
Pass
{
//一些标签信息
CGPROGRAM
#pragma vertex VertexFunctionName
#pragma fragment FragmentFunctionName
//定义变量
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float3 worldPos : TEXCOORD0;
float3 worldNormal : TEXCOORD1;
float4 vertex : SV_POSITION;
};
//函数定义
v2f Vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
fixed4 Frag(v2f i) : SV_Target
{
//颜色计算
return fixed4(1, 0, 0, 1);
}
ENDCG
}
在上述代码中,vert和Frag分别为顶点着色器程序和片元着色器程序。
三、示例1
下面我们来看一个材质实例,它使用一个着色器实现了对纹理的灰度变换。
Shader "Custom/GrayTextureShader"
{
Properties
{
_MainTex("Main Texture", 2D) = "white" {}
_Brightness("Brightness", Range(0, 2)) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Geometry" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//定义材质参数
sampler2D _MainTex;
float _Brightness;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
//计算颜色值
fixed4 color = tex2D(_MainTex, i.uv);
float gray = dot(color.rgb, float3(0.299, 0.587, 0.114));
color.rgb = lerp(float3(gray, gray, gray),
color.rgb, _Brightness);
return color;
}
ENDCG
}
}
}
上述代码实现了对纹理进行灰度处理,同时提供了一个Brightness参数,可以控制灰度强度。
四、示例2
下面我们来看一个材质实例,它使用一个着色器实现了对模型的UV纹理动态处理。
Shader "Custom/UVTextureShader"
{
Properties
{
_MainTex("Main Texture", 2D) = "white" {}
_Speed("Speed", Range(0, 1)) = 0.1
_Offset("Offset", Range(0, 1)) = 0.5
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Geometry" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//定义材质参数
sampler2D _MainTex;
float _Speed;
float _Offset;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv + float2(_Offset, _Offset) +
float2(sin(_Speed * _Time.y), cos(_Speed * _Time.y));
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return tex2D(_MainTex, i.uv);
}
ENDCG
}
}
}
上述代码实现了对模型UV纹理的动态处理,其中提供了Speed和Offset参数,可以控制纹理的移动和偏移。
以上是关于深入浅出掌握Unity ShaderLab语法基础的攻略讲解,希望能对你的开发工作有所帮助!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入浅出掌握Unity ShaderLab语法基础 - Python技术站