Unity Shader介绍

1. Shader的基本概念

什么是Shader?

Shader是小型程序,用于在GPU上运行,处理顶点、像素或其他图形处理单元。Unity主要使用以下两种Shader:

  • 顶点Shader(Vertex Shader):处理每个顶点的数据,如位置、颜色和纹理坐标。
  • 片段Shader(Fragment Shader):决定每个像素的颜色。

Unity中的Shader类型

  • 表面Shader(Surface Shader):用于处理标准光照模型的高级Shader,简化了Shader编写过程。
  • 顶点和片段Shader(Vertex and Fragment Shaders):更加灵活但复杂,允许自定义光照模型和效果。
  • 计算Shader(Compute Shader):不直接用于渲染,但用于在GPU上执行通用计算任务。

2. ShaderLab结构

Unity中的Shader是用ShaderLab编写的,它有特定的结构:

 1 Shader "Custom/MyShader"
 2 {
 3     Properties
 4     {
 5         _MainTex ("Base (RGB)", 2D) = "white" {}
 6     }
 7     SubShader
 8     {
 9         Pass
10         {
11             CGPROGRAM
12             // 顶点和片段Shader代码
13             ENDCG
14         }
15     }
16 }
  • Shader:定义Shader的名称。
  • Properties:在Unity编辑器中公开变量,允许用户调整Shader设置。
  • SubShader:包含多个GPU运行的Pass来渲染对象。
  • CGPROGRAM和ENDCG:标记Cg/HLSL代码的开始和结束。

3. 编写基本Shader

一个处理简单漫反射光照的表面Shader:

 1 Shader "Custom/SimpleDiffuse"
 2 {
 3     Properties
 4     {
 5         _Color ("Main Color", Color) = (1,1,1,1)
 6         _MainTex ("Base (RGB)", 2D) = "white" {}
 7     }
 8     SubShader
 9     {
10         Tags { "RenderType"="Opaque" }
11         LOD 200
12 
13         CGPROGRAM
14         #pragma surface surf Lambert
15 
16         struct Input
17         {
18             float2 uv_MainTex;
19         };
20 
21         sampler2D _MainTex;
22         fixed4 _Color;
23 
24         void surf (Input IN, inout SurfaceOutput o)
25         {
26             fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
27             o.Albedo = c.rgb;
28         }
29         ENDCG
30     }
31     FallBack "Diffuse"
32 }

这个Shader定义了一个颜色和一个纹理,然后在surt函数中组合它们以生成最终颜色。

一个使用顶点和片段Shader的详细示例:

 1 Shader "Custom/VertexFragment"
 2 {
 3     Properties
 4     {
 5         _MainTex ("Base (RGB)", 2D) = "white" {}
 6     }
 7     SubShader
 8     {
 9         Pass
10         {
11             CGPROGRAM
12             #pragma vertex vert
13             #pragma fragment frag
14             #include "UnityCG.cginc"
15 
16             struct appdata
17             {
18                 float4 vertex : POSITION;
19                 float2 uv : TEXCOORD0;
20             };
21 
22             struct v2f
23             {
24                 float2 uv : TEXCOORD0;
25                 float4 pos : SV_POSITION;
26             };
27 
28             sampler2D _MainTex;
29 
30             v2f vert (appdata v)
31             {
32                 v2f o;
33                 o.pos = UnityObjectToClipPos(v.vertex);
34                 o.uv = v.uv;
35                 return o;
36             }
37 
38             fixed4 frag (v2f i) : SV_Target
39             {
40                 return tex2D(_MainTex, i.uv);
41             }
42             ENDCG
43         }
44     }
45 }

这个Shader接收顶点,进行转换,然后在片段Shader中应用纹理。

4. 高级主题

Shader变体和关键字

  • Shader变体:通过不同的#pragma指令或关键字编译的Shader版本,用于优化Shader以适应不同的硬件。
  • 关键字:在运行时启用或禁用Shader特性。例如,#pragma multi_compile生成具有不同特性集的多个Shader版本。

计算Shader

  • 计算Shader:用于在GPU上执行通用计算任务(GPGPU)。不直接用于渲染,但可以执行物理计算、粒子模拟等任务。

Shader性能

  • 优化Shader:尤其在移动设备上,性能优化非常重要。技术包括最小化纹理获取、减少复杂计算和使用适当的LOD设置。

 

 

posted @ 2024-05-24 21:10  Jet清远  阅读(136)  评论(0编辑  收藏  举报