Loading... **ShaderLab 关键点记录** ShaderLab 是 Unity 中用于编写着色器的语言。着色器是运行在 GPU 上的程序,负责处理渲染流水线中的各种图形计算。理解 ShaderLab 的关键概念和技术细节,对于开发高效、复杂的图形效果至关重要。本文将详细记录 ShaderLab 的关键点,帮助开发者深入掌握这门语言。  ### ShaderLab 基础 #### 1. ShaderLab 结构 一个 ShaderLab 文件通常由以下几个部分组成: - **Shader 名称**:定义着色器的名称。 - **Properties**:定义着色器可调节的属性。 - **SubShader**:定义具体的渲染过程。 - **Pass**:定义一个渲染通道。 示例结构: ```csharp Shader "Custom/MyShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Main Color", Color) = (1,1,1,1) } SubShader { Pass { // Shader code here } } FallBack "Diffuse" } ``` #### 2. Properties `Properties` 用于在 Inspector 窗口中暴露变量,方便调节。常见类型包括: - **Color**:颜色。 - **Vector**:向量。 - **Range**:范围值。 - **Float**:浮点数。 - **2D**:2D 纹理。 示例: ```csharp Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Texture", 2D) = "white" {} _Shininess ("Shininess", Range(0.03, 1)) = 0.078125 } ``` #### 3. SubShader 和 Pass `SubShader` 包含一个或多个 `Pass`,每个 `Pass` 代表一个渲染步骤。 - **SubShader**:用于定义多种渲染路径,以适应不同的硬件。 - **Pass**:包含具体的渲染指令。 示例: ```csharp SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // Vertex and fragment shader code ENDCG } } ``` ### CG/HLSL 代码 ShaderLab 中嵌入的 CG 或 HLSL 代码用于编写具体的顶点和片段着色器。 #### 1. 顶点着色器 顶点着色器负责处理顶点属性,如位置、法线等。 示例: ```csharp struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; float3 normal : TEXCOORD0; }; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.normal = v.normal; return o; } ``` #### 2. 片段着色器 片段着色器负责计算每个像素的颜色。 示例: ```csharp float4 frag (v2f i) : SV_Target { return float4(i.normal, 1.0); } ``` ### 常用指令和技巧 #### 1. #pragma 指令 用于控制编译器行为,如定义顶点和片段着色器入口。 - `#pragma vertex vert`:定义顶点着色器入口。 - `#pragma fragment frag`:定义片段着色器入口。 #### 2. 内置变量 Unity 提供了一些内置变量,方便在着色器中使用。 - `UNITY_MATRIX_MVP`:模型视图投影矩阵。 - `unity_ObjectToWorld`:对象到世界坐标的变换矩阵。 #### 3. 纹理采样 使用 `tex2D` 函数进行纹理采样。 示例: ```csharp sampler2D _MainTex; float4 frag (v2f i) : SV_Target { float4 texColor = tex2D(_MainTex, i.uv); return texColor; } ``` #### 4. 多通道渲染 使用多个 `Pass` 进行复杂的多通道渲染。 示例: ```csharp SubShader { Pass { // First pass } Pass { // Second pass } } ``` ### 实用例子:Phong 着色器 一个简单的 Phong 着色器示例,展示了基本的光照计算。 ```csharp Shader "Custom/PhongShader" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color ("Main Color", Color) = (1,1,1,1) _Shininess ("Shininess", Range(0.03, 1)) = 0.078125 } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float3 normal : TEXCOORD0; float2 uv : TEXCOORD1; }; sampler2D _MainTex; float4 _Color; float _Shininess; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.normal = UnityObjectToWorldNormal(v.normal); o.uv = v.uv; return o; } float4 frag (v2f i) : SV_Target { float3 normal = normalize(i.normal); float3 lightDir = normalize(float3(0.0, 0.0, 1.0)); float3 viewDir = normalize(float3(0.0, 0.0, 1.0)); // Diffuse float diff = max(dot(normal, lightDir), 0.0); // Specular float3 reflectDir = reflect(-lightDir, normal); float spec = pow(max(dot(viewDir, reflectDir), 0.0), _Shininess); // Texture and color float4 texColor = tex2D(_MainTex, i.uv); float4 color = _Color * texColor; color.rgb *= diff; color.rgb += spec; return color; } ENDCG } } FallBack "Diffuse" } ``` ### 分析说明表 | 关键点 | 说明 | 示例代码 | | ----------------- | ---------------------------------------------- | ---------------------------------------------- | | ShaderLab 结构 | 定义着色器的基本结构,包括名称、属性和渲染过程 | `Shader "Custom/MyShader"` | | Properties | 定义在 Inspector 中暴露的变量 | `_MainTex ("Texture", 2D) = "white" {}` | | SubShader 和 Pass | 定义具体的渲染步骤 | `SubShader { Pass { CGPROGRAM ... ENDCG } }` | | 顶点着色器 | 处理顶点属性,如位置和法线 | `v2f vert (appdata v)` | | 片段着色器 | 计算每个像素的颜色 | `float4 frag (v2f i) : SV_Target` | | #pragma 指令 | 控制编译器行为,定义着色器入口 | `#pragma vertex vert` | | 内置变量 | Unity 提供的内置变量,方便在着色器中使用 | `UNITY_MATRIX_MVP` | | 纹理采样 | 使用 `tex2D` 函数进行纹理采样 | `float4 texColor = tex2D(_MainTex, i.uv)` | | 多通道渲染 | 使用多个 `Pass` 进行复杂的渲染 | `SubShader { Pass { ... } Pass { ... } }` | ### 总结 ShaderLab 是 Unity 中创建和管理着色器的核心工具。通过理解其基本结构、常用属性和关键技术,开发者可以创建出各种复杂的图形效果。从基础的颜色和纹理处理,到高级的光照和多通道渲染,ShaderLab 提供了强大的功能和灵活性。希望本文记录的关键点能帮助您更好地掌握 ShaderLab,提高图形编程的效率和效果。 最后修改:2024 年 06 月 11 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏