【图形学】TA之路-基于Unity Shader编程之初体验

学习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基础功能

cs 复制代码
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 Lambert
        struct 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

相关推荐
aerror4 分钟前
如何正确的用Trae 打开 Unity 3D 项目
3d·unity·游戏引擎
步、步、为营2 小时前
.NET 的IOC框架Unity代码示例
unity·游戏引擎·.net
Magnum Lehar2 小时前
wpf游戏引擎的script实现
游戏引擎·wpf
留待舞人归6 小时前
【Unity优化】提高热更新和打包速度
游戏·unity·游戏引擎·unity3d·优化
tealcwu6 小时前
【Unity踩坑】Unity 6在Mac平台编译运行时去除‘trial version‘
macos·unity·游戏引擎
为你写首诗ge7 小时前
【热更新知识】学习一 Lua语法学习
unity·lua
为你写首诗ge8 小时前
【热更新知识】学习三 XLua学习
unity·lua
程序员小刘10 小时前
如何开始HarmonyOS 5与Godot引擎融合开发?
华为·游戏引擎·godot·harmonyos
T.D.C18 小时前
【动画】Unity2D骨骼动画-Animation2D
unity·动画
AgilityBaby18 小时前
Unity实现不倒翁
笔记·unity·c#·游戏引擎