【图形学】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

相关推荐
Sitarrrr40 分钟前
【Unity】ScriptableObject的应用和3D物体跟随鼠标移动:鼠标放置物体在场景中
3d·unity
极梦网络无忧43 分钟前
Unity中IK动画与布偶死亡动画切换的实现
unity·游戏引擎·lucene
逐·風9 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
_oP_i10 小时前
Unity Addressables 系统处理 WebGL 打包本地资源的一种高效方式
unity·游戏引擎·webgl
代码盗圣14 小时前
GODOT 4 不用scons编译cpp扩展的方法
游戏引擎·godot
Leoysq19 小时前
【UGUI】实现点击注册按钮跳转游戏场景
游戏·unity·游戏引擎·ugui
PandaQue21 小时前
《潜行者2切尔诺贝利之心》游戏引擎介绍
游戏引擎
_oP_i1 天前
unity中 骨骼、纹理和材质关系
unity·游戏引擎·材质
Padid1 天前
Unity SRP学习笔记(二)
笔记·学习·unity·游戏引擎·图形渲染·着色器
Tp_jh1 天前
推荐一款非常好用的C/C++在线编译器
linux·c语言·c++·ide·单片机·unity·云原生