首页 > 其他分享 >【Unity3D】顶点和片元着色器

【Unity3D】顶点和片元着色器

时间:2023-03-21 09:55:59浏览次数:62  
标签:Unity3D MainTex Shader 片元 vertexPos 顶点 data 着色器

1 前言

​ 上文介绍了渲染管线、固定管线着色器和表面着色器,如下:

​ 固定管线着色器通过命令方式实现光照和贴图等效果,表面着色器通过给 SurfaceOutput 赋值实现光照、贴图和法线贴图等效果,它们都不用关注光照算法是如何实现的,只需要传值就行。

​ 顶点和片元着色器给用户提供了更灵活的用法,但使用也更困难。另外,顶点着色器可以通过控制 MVP 矩阵变换实现对模型位置和姿态的控制。

2 固定颜色

​ 在 Assets 窗口右键,依次选择【Create→Shader→Standard Surface Shader】创建 Shader 脚本,实现固定颜色 Shader 代码如下:

​ VFShader.shader

Shader "MyShader/VFShaderTest" {
	Properties
	{
		// 属性名 ("面板显示名称", 类型) = 默认值
		_MainColor ("显示颜色", Color) = (1, 0, 0, 1)
	}
 
	SubShader
	{
		Pass
		{
			CGPROGRAM // CG语言的开始
			// 编译指令 着色器名称 函数名称
			#pragma vertex vert // 顶点着色器, 每个顶点执行一次
			#pragma fragment frag // 片段着色器, 每个像素执行一次
			// 导入头文件
			#include "UnityCG.cginc"
 
			// 声明属性变量, 必须与外部属性变量名称一致
			fixed4 _MainColor;
 
			// 顶点着色器
			half4 vert(half4 vertexPos: POSITION): SV_POSITION
			{
				// 将局部坐标系下坐标转换为裁剪坐标系下坐标
				return UnityObjectToClipPos(vertexPos); // 等价于: mul(UNITY_MATRIX_MVP, vertexPos)
			}
 
			// 片元着色器
			fixed4 frag(): COLOR
			{
				return _MainColor;
			}
 
			ENDCG // CG语言的结束
		}
	}
 
	FallBack "Diffuse"
}

​ 创建一个 Material,并将 ShaderTest 绑定到该 Material 上,如下:

img

​ 将该 Material 拖拽到一个 Cube 和 Sphere 游戏对象上。选中绑定的 Material,在 Inspector 窗口调整 Shader 中固定颜色,显示效果如下:

img

3 光照

​ VFShader.shader

Shader "MyShader/VFShaderTest" {
	Properties
	{
		// 属性名 ("面板显示名称", 类型) = 默认值
		_DiffuseColor ("漫反射颜色", Color) = (1, 0, 0, 1)
	}
 
	SubShader
	{
		Pass
		{
			Tags {"LightMode"="ForwardBase"}
			CGPROGRAM // CG语言的开始
			// 编译指令 着色器名称 函数名称
			#pragma vertex vert // 顶点着色器, 每个顶点执行一次
			#pragma fragment frag // 片段着色器, 每个像素执行一次
 
			// 导入头文件
			#include "UnityCG.cginc"
 
			// 声明属性变量, 必须与外部属性变量名称一致
			fixed4 _DiffuseColor;
 
			struct appdata // 顶点着色器输入结构体
			{
				half4 vertexPos: POSITION; // 局部坐标系下顶点坐标
				half3 vertexNormal: NORMAL; // 局部坐标系下顶点法线向量
			};
 
			struct v2f // 顶点着色器输出结构体
			{
				half4 clipPos: SV_POSITION; // 裁剪坐标系下顶点坐标
				half3 worldNormal: Normal; // 裁剪坐标系下顶点法线向量
                half3 worldLightDir : TEXCOORD0; // 光照方向
			};
 
			// 顶点着色器
			v2f vert(appdata data)
			{
				v2f o;
				o.clipPos = UnityObjectToClipPos(data.vertexPos); // 等价于: mul(UNITY_MATRIX_MVP, data.vertexPos)
                o.worldNormal = UnityObjectToWorldNormal(data.vertexNormal); // 将局部坐标系下法线转换为世界坐标系下法线
                o.worldLightDir = UnityWorldSpaceLightDir(data.vertexPos); // 计算世界坐标系下顶点指向光源的向量
				return o;
			}
 
			// 片元着色器
			fixed4 frag(v2f input): COLOR
			{
				half factor = dot(input.worldNormal, input.worldLightDir);
				//return _DiffuseColor * factor + UNITY_LIGHTMODEL_AMBIENT; // Lambert光照模型
				return _DiffuseColor * (0.5 * factor + 0.5) + UNITY_LIGHTMODEL_AMBIENT; // 半Lambert光照模型
			}
 
			ENDCG // CG语言的结束
		}
	}
 
	FallBack "Diffuse"
}

​ 选中绑定的 Material,在 Inspector 窗口调整 Shader 中光照颜色,显示效果如下:

img

4 贴图

​ VFShader.shader

Shader "MyShader/VFShaderTest" {
	Properties
	{
		// 属性名 ("面板显示名称", 类型) = 默认值
		_MainTex ("2阶贴图", 2D) = "white" {}
	}
 
	SubShader
	{
		Pass
		{
			Tags {"LightMode"="ForwardBase"}
			CGPROGRAM // CG语言的开始
			// 编译指令 着色器名称 函数名称
			#pragma vertex vert // 顶点着色器, 每个顶点执行一次
			#pragma fragment frag // 片段着色器, 每个像素执行一次
 
			// 导入头文件
			#include "UnityCG.cginc"
 
			// 声明属性变量, 必须与外部属性变量名称一致
			sampler2D _MainTex;
 
			struct appdata // 顶点着色器输入结构体
			{
				half4 vertexPos: POSITION; // 顶点坐标
				half2 uv_MainTex: TEXCOORD0; // 纹理uv坐标
			};
 
			struct v2f // 顶点着色器输出结构体
			{
				half4 clipPos: SV_POSITION; // 屏幕坐标
				half2 uv_MainTex: TEXCOORD0; // 纹理uv坐标
			};
 
			// 顶点着色器
			v2f vert(appdata data)
			{
				v2f o;
				o.clipPos = UnityObjectToClipPos(data.vertexPos); // 等价于: mul(UNITY_MATRIX_MVP, data.vertexPos)
				o.uv_MainTex = data.uv_MainTex;
				return o;
			}
 
			// 片元着色器
			fixed4 frag(v2f input): COLOR
			{
				return tex2D(_MainTex, input.uv_MainTex);
			}
 
			ENDCG // CG语言的结束
		}
	}
 
	FallBack "Diffuse"
}

​ 选中绑定的 Material,在 Inspector 窗口选择贴图图片,显示效果如下:

img

​ 声明:本文转自【Unity3D】顶点和片元着色器

标签:Unity3D,MainTex,Shader,片元,vertexPos,顶点,data,着色器
From: https://www.cnblogs.com/zhyan8/p/17237932.html

相关文章

  • 【Unity3D】表面着色器
    1前言​固定管线着色器一、固定管线着色器二中介绍了ShaderLib的基本用法,本文将接着讲解表面着色器(SurfaceShader)的用法。固定管线着色器基于ShaderLib命令实......
  • 【Unity3D】AudioSource组件
    1简介​1)AudioSource与AudioListener简介​AudioSource(音频源)组件用于控制播放AudioClip(音频片段),能够控制2D和3D(距离越远,声音越小)声音播放,它一般挂在产......
  • 【Unity3D】场景切换、全屏_恢复切换、退出游戏、截屏
    1前言​1)场景切换​场景切换可以使用SceneManager的LoadScene和LoadSceneAsync方法,如下:publicstaticvoidLoadScene(stringsceneName)publicstatic......
  • 【Unity3D】GUI控件
    1前言​Unity3D提供了GUI、NGUI、UGUI等图形系统,以增强玩家与游戏的交互性。GUI在编译时不能可视化,在运行时才能可视化。GUI代码需要在OnGUI函数中调用才能......
  • 【Unity3D】相机跟随
    1前言​相机跟随是相机指始终跟随特定游戏对象,有以下2种跟随效果:位置跟随:相机指向目标游戏对象的向量始终不变位置和姿态跟随:相机在目标游戏对象的坐标系下的坐......
  • 【Unity3D】UGUI之Text
    1Text简介​UGUI概述中介绍了Canvas渲染模式、RectTransform组件、锚点(Anchor)等,本文将介绍UGUI中的Text控件。​在Hierarchy窗口右键,选择UI列表里......
  • 【Unity3D】UGUI概述
    1UGUI与GUI区别​GUI控件在编译时不能可视化,并且界面不太美观,在实际应用中使用的较少。UGUI在编译时可视化,界面美观,实际应用较广泛。2Canvas渲染模式(Render......
  • 【Unity3D】UGUI之Button
    1Button属性面板​在Hierarchy窗口右键,选择UI列表里的Button控件,即可创建Button控件,选中创建的Button控件,按键盘【T】键,可以调整Button控件的大小和位置......
  • 【Unity3D】UGUI之Image和RawImage
    1纹理(Texture)​Image控件和RawImage控件都是承载渲染图片的控件,都需要指定一个纹理(Texture)图片。在Assets窗口选中一张图片,在Inspector窗口的参数设置面板可......
  • 【Unity3D】UGUI之Slider
    1Slider属性面板​在Hierarchy窗口右键,选择UI列表里的Slider控件,即可创建Slider控件,选中创建的Slider控件,按键盘【T】键,可以调整Slider控件的大小和位置......