学习shader之前你必须知道的事情:
Unity开发引擎、Direct3D、Shader他们之间的关系
Direct3D 是一个底层图形 API,它直接与 GPU (显卡)交互,提供了访问硬件加速功能的接口。Unity 开发引擎,它封装了很多底层的功能,使开发者可以更方便地进行游戏开发。Unity 支持多种图形 API,Direct3D 就是其中之一。
Unity Shader 是一种高层次的图形着色器,定义了如何渲染对象的外观。Unity 的 Shader 最终会被编译为针对特定图形 API(如 Direct3D、OpenGL、Vulkan 等)的底层指令,以便在 GPU 上执行。因此,在 Windows 平台上,Unity 的 Shader 在运行时会被翻译为 Direct3D 的代码,以利用 Direct3D 提供的图形渲染功能。
执行过程:
当你在 Unity 中编写 Shader 时,Unity 会将这些 Shader 编译为中间语言(如 HLSL),然后在 Windows 平台上将这些中间代码翻译为 Direct3D 能够理解的指令。最终,Direct3D 使用这些指令与 GPU 交互,完成 3D 渲染。
Shader 需要通过材质球呈现
Shader 是一个程序,定义了如何根据输入(如顶点数据、光照、纹理等)计算出输出(如像素颜色)。但是,Shader 本身只是定义了计算的过程,并没有提供具体的输入数据(如具体使用的纹理、颜色值等)。
材质球(Material) 是一个容器,用来实例化 Shader,并为其提供具体的参数值。例如,Shader 中可能定义了一个纹理参数 _MainTex,但具体使用什么纹理,由材质球来指定。
在Unity中创建第一个shader
随便你创建一个shader类型,你会发下他默认已经有一些基础的代码了,为了更好的理解,我决定不这样创建,我们可以直接创建一个文本文件直接命名为"MyShader"。
开启我们的Shader之旅,用VS打开这个时候是一片空白的,写一个shader基础功能
Shader "Myshader"
{Properties //Properties 不区分大小写{_MainTex("我的纹理",2D) = "white"{}_MyInt("我的整数",int)=2_MyRange("范围内调节",range(-1,1))=0_MyClore("调节颜色",color)=(0,0,1,1)_MyVector("设置向量",vector)=(1,1,1,1)}SubShader //SubShader 区分大小写{CGPROGRAM#pragma surface surf Lambertstruct Input{float2 uv_MainTex;};sampler2D _MainTex;int _MyInt;float4 _MyClore;void surf(Input IN,inout SurfaceOutput o){o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb;}ENDCG}
}
Properties块:你可以理解C#中的一个方法,Properties 块定义了可以在 Unity 编辑器中通过 Inspector 面板调整的参数,Properties中是不区分大小写的。
类似我们在unity声明一个变量
SubShader 块:是实际的 Shader 代码执行部分。这里定义了一个简单的 Surface Shader,并使用 Lambert 光照模型,SubShader 区分大小写。
1.CGPROGRAM / ENDCG: 包裹在这两个宏之间的是用 CG/HLSL 编写的 Shader 代码。
2.#pragma surface surf Lambert: 指定了 Surface Shader 的入口函数是 surf,并且使用 Lambert 光照模型。
3.struct Input { float2 uv_MainTex; };: 定义了一个结构体 Input,用于传递给 Surface Shader 的输入数据。在这里,它包含了用于采样纹理的 UV 坐标。
4.sampler2D _MainTex;: 定义了一个纹理采样器,用于采样 _MainTex 纹理。_MainTex比较特殊默认是主纹理,名字不要去改变,不然会出问题。
5.int _MyInt;: 定义了一个整数变量 _MyInt,对应于 Properties 块中的 _MyInt。
6.float4 _MyClore;: 定义了一个 4D 向量 _MyClore,对应于 Properties 块中的 _MyClore,它用于表示颜色。
surf 函数
surf 函数是 Surface Shader 的核心部分,用于计算最终的表面颜色(Albedo)。
tex2D(_MainTex, IN.uv_MainTex): 使用传入的 UV 坐标从 _MainTex 纹理中采样颜色。
o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb;: 将采样到的纹理颜色赋值给输出的 Albedo,这就是最终渲染出来的颜色。
保存后把他放到unity材质球上,给材质赋值,这样就基本完成了一个基础的shader