17.CG-Swizzle操作符
17.1 知识点
什么是Swizzle操作符
在上一节课中,我们学习了向量,但并没有讲解如何获取向量中的元素。本节课将要学习的Swizzle操作符就是用于获取向量中元素的工具。
Swizzle操作符通常以点号(.)的形式使用,后面跟着所需的分量顺序。对于四维向量来说,我们可以通过向量 .xyzw
或 .rgba
两种分量的写法来表示向量中的四个值。其中 xyzw
和 rgba
分别代表四维向量中的四个元素。这在向量中常用于表示坐标和颜色。
如何使用Swizzle操作符
- 利用它来提取分量。
- 利用它来重新排列分量。
- 利用它来创建新向量。
v2f vert(appdata v)
{
v2f o;
// 1.利用swizzle来提取分量
fixed4 f4 = fixed4(1, 2, 3, 4); // 创建一个包含四个固定点数的向量
fixed f = f4.w; //xyzw f=4
f = f4.a; //rgba f=4
// 2.利用它来重新排列分量
f4 = f4.yzxw; // 将f4的分量重新排列为yzxw
f4 = f4.abgr; // 将f4的分量重新排列为abgr
// 3.利用它来创建新的向量
fixed3 f3 = f4.xyz; // 包含f4的前三个分量
fixed2 f2 = f3.xz; // 包含f3的x和z分量
fixed4 f4_1 = fixed4(f2, 3, 4); // 包含f2一次次,即xz的值加上3和4
fixed4 f4_2 = fixed4(f2, f2); //包含f2两次,即xzxz
f4_2 = fixed4(f3, f); // 包含f3和f,即xyza
return o;
}
向量和矩阵的更多用法
利用向量声明矩阵
// 在声明矩阵时,我们可以配合向量来进行声明。 创建一个4x4的固定点数矩阵
fixed4x4 f4x4 = {
fixed4(1, 2, 3, 4),
fixed4(1, 2, 3, 4),
fixed4(1, 2, 3, 4),
fixed4(1, 2, 3, 4)
};
获取矩阵中的元素
f = f4x4[0][0]; // 访问f4x4的第一行第一列元素,并将结果赋值给f
利用向量获取矩阵中的某一行
f4_2 = f4x4[3]; // 访问f4x4的第四行,并将结果赋值给f4_2
高维转低维
//向量和矩阵都可以用低维存高维,会自动舍去多余元素。
//比如三维向量赋值四维向量,舍弃最后一个元素
fixed3 f3_2 = f4; // 如果不明确写元素,会直接使用前面的对应个数的元素
f2 = f4; // 如果不明确写元素,会直接使用前面的对应个数的元素
// 创建一个3x3的固定点数矩阵,并将f4x4赋值给它,会把前三行和前三列的赋值,第四行和第四列的元素舍弃
fixed3x3 f3x3 = f4x4;
总结
- 向量获取元素可以利用Swizzle操作符获取。
- 矩阵获取元素和二维数组获取方式一样。
- Swizzle操作符可以让我们对向量进行方便的操作。
- 向量和矩阵在声明和获取时可以配合使用
- 高维向量或矩阵可以用低维容器装载,可以利用这个特点将4维变3维,4x4变3x3
17.2 知识点代码
Lesson17_CG_Swizzle操作符
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson17_CG_Swizzle操作符 : MonoBehaviour
{
void Start()
{
#region 知识点一 什么是Swizzle操作符
//上节课我们学习了向量
//但是我们并没有讲解如何获取向量中某元素的相关知识点
//而这节课将要学习的Swizzle操作符就可以用于获取向量中元素
//Swizzle操作符通常以点号(.)的形式使用,后面跟着所需的分量顺序
//对于四维向量来说
//我们可以通过
//向量.xyzw
//或
//向量.rgba
//两种分量的写法来表示向量中的四个值
//其中 xyzw和rgba分别代表四维向量中的四个元素
//在此的意义就是向量一般可以用来表示坐标和颜色
#endregion
#region 知识点二 如何使用Swizzle操作符
//1.利用它来提取分量
//2.利用它来重新排列分量
//3.利用它来创建新向量
#endregion
#region 知识点三 向量和矩阵的更多用法
#region 1.利用向量声明矩阵
//在声明矩阵时,我们可以配合向量来进行声明
#endregion
#region 2.获取矩阵中的元素
//矩阵中元素的获取和二维数组一样
#endregion
#region 3.利用向量获取矩阵中的某一行
//我们可以用向量作为容器存储矩阵中的某一行
#endregion
#region 4.高维转低维
//向量和矩阵都可以用低维存高维,会自动舍去多余元素
#endregion
#endregion
#region 总结
//1.向量获取元素可以利用Swizzle操作符获取
//2.矩阵获取元素和二维数组获取方式一样
//3.Swizzle操作符可以让我们对向量进行方便的操作
//4.向量和矩阵在声明和获取时可以配合使用
//5.高维向量或矩阵可以用低维容器装载,可以利用这个特点将4维变3维,4x4变3x3
#endregion
}
}
Lesson17_NewUnlitShader.shader
Shader "ShaderTeach/Lesson17_NewUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"RenderType"="Opaque"
}
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata v)
{
// 创建一个v2f类型的变量o,用于保存顶点着色器的输出
v2f o;
// 使用UnityObjectToClipPos函数将顶点v的局部坐标转换为裁剪空间坐标,并将结果赋值给o的顶点坐标
o.vertex = UnityObjectToClipPos(v.vertex);
// 使用TRANSFORM_TEX函数将顶点v的纹理坐标进行转换,并将结果赋值给o的纹理坐标
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// 将雾效应的相关信息传递给o
UNITY_TRANSFER_FOG(o, o.vertex);
// 利用swizzle来提取分量
fixed4 f4 = fixed4(1, 2, 3, 4); // 创建一个包含四个固定点数的向量
fixed f = f4.w; //xyzw f=4
f = f4.a; //rgba f=4
// 利用它来重新排列分量
f4 = f4.yzxw; // 将f4的分量重新排列为yzxw
f4 = f4.abgr; // 将f4的分量重新排列为abgr
// 利用它来创建新的向量
fixed3 f3 = f4.xyz; // 创建一个新的固定点数向量,包含f4的前三个分量
fixed2 f2 = f3.xz; // 创建一个新的固定点数向量,包含f3的x和z分量
fixed4 f4_2 = fixed4(f2, f2); // 创建一个新的固定点数向量,包含f2两次
f4_2 = fixed4(f3, f); // 创建一个新的固定点数向量,包含f3和f
// 创建一个4x4的固定点数矩阵
fixed4x4 f4x4 = {
fixed4(1, 2, 3, 4),
fixed4(1, 2, 3, 4),
fixed4(1, 2, 3, 4),
fixed4(1, 2, 3, 4)
};
f = f4x4[0][0]; // 访问f4x4的第一行第一列元素,并将结果赋值给f
f4_2 = f4x4[3]; // 访问f4x4的第四行,并将结果赋值给f4_2
fixed3 f3_2 = f4; //如果不明确写元素,会直接使用前面的对应个数的元素
f2 = f4; // 如果不明确写元素,会直接使用前面的对应个数的元素
// 创建一个3x3的固定点数矩阵,并将f4x4赋值给它 会把前三行和前三列的赋值 第四行和第四列的元素舍弃
fixed3x3 f3x3 = f4x4;
// 创建一个3x3的固定点数矩阵
fixed3x3 f3x3_2 = {
1, 2, 3,
4, 5, 6,
7, 8, 9
};
// 创建一个4x4的固定点数矩阵,并将f3x3_2赋值给它
fixed4x4 f4x4_2 = {
fixed4(f3x3_2[0], 0),
fixed4(f3x3_2[1], 0),
fixed4(f3x3_2[2], 0),
fixed4(0, 0, 0, 1)
};
// 返回顶点着色器的输出
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
17.3 练习题
请用所学知识点,将一个3x3矩阵转换成一个4x4矩阵(自己将第四列和第四行用任意元素补齐)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com