unityShader简单示例——利用shader实现3d图像平移、缩放、旋转

该博客分享了如何使用Unity Shader分别实现物体的平移、缩放和旋转,并通过 shader 代码将三种变换结合在一起。作者提供了两段 shader 代码,第一段展示了独立的平移、缩放和旋转矩阵计算,而第二段代码则将这些变换融合在一个TRS Blend矩阵中,实现了更高效的操作。博客内容适合对Unity图形编程感兴趣的读者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作为shader编写的一段练习题我将物体的平移、缩放和旋转分别利用shader实现,此处代码仅作为参考,尽量不要在shader代码中利用if语句判断。
效果如下:
物体位移
shader代码如下:

Shader "Unlit/CustomChange"
{
	Properties
	{
		//显示一个下拉菜单
		[Enum(Translational,0,Scale,1,Rotation,2)]_Transform("Transform",float) = 0
		_Translational("Translational",vector) = (0.0,0.0,0.0,0.0)
		_Scale("Scale",vector) = (1.0,1.0,1.0,1.0)
		_Rotation("Rotation",vector) = (0.0,0.0,0.0,1.0)
	}
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			uniform float _Transform;
			uniform float4 _Translational;
			uniform float4 _Scale;
			uniform float4 _Rotation;

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
				float4 color:COLOR;
                float4 vertex : SV_POSITION;
            };
			//平移矩阵
			float4x4 Translational(float4 translational)
			{
				return float4x4(1.0, 0.0, 0.0, translational.x,
					0.0, 1.0, 0.0, translational.y,
					0.0, 0.0, 1.0, translational.z,
					0.0, 0.0, 0.0, 1.0);
			}
			//缩放矩阵
			float4x4 Scale(float4 scale)
			{
				return float4x4(scale.x, 0.0, 0.0, 0.0,
					0.0, scale.y, 0.0, 0.0,
					0.0, 0.0, scale.z, 0.0,
					0.0, 0.0, 0.0, 1.0);
			}
			//旋转矩阵
			float4x4 Rotation(float4 rotation)
			{
				float radX = radians(rotation.x);
				float radY = radians(rotation.y);
				float radZ = radians(rotation.z);
				float sinX = sin(radX);
				float cosX = cos(radX);
				float sinY = sin(radY);
				float cosY = cos(radY);
				float sinZ = sin(radZ);
				float cosZ = cos(radZ);
				return float4x4(cosY*cosZ, -cosY * sinZ, sinY, 0.0,
					cosX*sinZ + sinX * sinY*cosZ, cosX*cosZ - sinX * sinY*sinZ, -sinX * cosY, 0.0,
					sinX*sinZ - cosX * sinY*cosZ, sinX*cosZ + cosX * sinY*sinZ, cosX*cosY, 0.0,
					0.0, 0.0, 0.0, 1.0);
			}

            v2f vert (appdata v)
            {
                v2f o;
				//在模型空间计算,坐标和矩阵相乘
				if (_Transform == 0)
				{
					v.vertex = mul(Translational(_Translational), v.vertex);
				}
				else if (_Transform == 1)
				{
					v.vertex = mul(Scale(_Scale), v.vertex);
				}
				else
				{
					v.vertex = mul(Rotation(_Rotation), v.vertex);
				}
                o.vertex = UnityObjectToClipPos(v.vertex);//将坐标从模型空间转到裁切空间
				o.color = float4(1, 0, 0, 1);
                return o;
            }

            fixed4 frag (v2f i) : COLOR
            {                
                return i.color;
            }
            ENDCG
        }
    }
}

详细内容解释可以看链接:Unity Shader中的平移、缩放、旋转

为了更加方便使用我将三种变换形式合在一起又重新写了一份,感兴趣的可以看一下,
效果如下:
物体位移Blend
shader代码如下:

Shader "Unlit/CustomChange(Blend)"
{
	Properties
	{
		_Translational("Translational",vector) = (0.0,0.0,0.0,0.0)
		_Scale("Scale",vector) = (1.0,1.0,1.0,1.0)
		_Rotation("Rotation",vector) = (0.0,0.0,0.0,1.0)
	}
		SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			//uniform float _Transform;
			uniform float4 _Translational;
			uniform float4 _Scale;
			uniform float4 _Rotation;

			struct appdata
			{
				float4 vertex : POSITION;
			};

			struct v2f
			{
				float4 color:COLOR;
				float4 vertex : SV_POSITION;
			};
			//平移矩阵
			float4x4 Translational(float4 translational)
			{
				return float4x4(1.0, 0.0, 0.0, translational.x,
					0.0, 1.0, 0.0, translational.y,
					0.0, 0.0, 1.0, translational.z,
					0.0, 0.0, 0.0, 1.0);
			}
			//缩放矩阵
			float4x4 Scale(float4 scale)
			{
				return float4x4(scale.x, 0.0, 0.0, 0.0,
					0.0, scale.y, 0.0, 0.0,
					0.0, 0.0, scale.z, 0.0,
					0.0, 0.0, 0.0, 1.0);
			}
			//旋转矩阵
			float4x4 TRSBlend(float4 rotation)
			{
				float radX = radians(rotation.x);
				float radY = radians(rotation.y);
				float radZ = radians(rotation.z);
				float sinX = sin(radX);
				float cosX = cos(radX);
				float sinY = sin(radY);
				float cosY = cos(radY);
				float sinZ = sin(radZ);
				float cosZ = cos(radZ);
				float4x4 r= float4x4(cosY*cosZ, -cosY * sinZ, sinY, 0.0,
					cosX*sinZ + sinX * sinY*cosZ, cosX*cosZ - sinX * sinY*sinZ, -sinX * cosY, 0.0,
					sinX*sinZ - cosX * sinY*cosZ, sinX*cosZ + cosX * sinY*sinZ, cosX*cosY, 0.0,
					0.0, 0.0, 0.0, 1.0);
				float4x4 tr = mul(Translational(_Translational), r);
				return mul(tr, Scale(_Scale));
			}

			v2f vert(appdata v)
			{
				v2f o;
				//在模型空间计算
				v.vertex = mul(TRSBlend(_Rotation), v.vertex);
				o.vertex = UnityObjectToClipPos(v.vertex);//将坐标从模型空间转到裁切空间
				o.color = float4(1, 0, 0, 1);
				return o;
			}

			fixed4 frag(v2f i) : COLOR
			{
				return i.color;
			}
			ENDCG
		}
	}
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值