17.CG语法Swizzle操作符

17.CG-Swizzle操作符


17.1 知识点

什么是Swizzle操作符

在上一节课中,我们学习了向量,但并没有讲解如何获取向量中的元素。本节课将要学习的Swizzle操作符就是用于获取向量中元素的工具。

Swizzle操作符通常以点号(.)的形式使用,后面跟着所需的分量顺序。对于四维向量来说,我们可以通过向量 .xyzw.rgba 两种分量的写法来表示向量中的四个值。其中 xyzwrgba 分别代表四维向量中的四个元素。这在向量中常用于表示坐标和颜色。

如何使用Swizzle操作符

  1. 利用它来提取分量。
  2. 利用它来重新排列分量。
  3. 利用它来创建新向量。
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;

总结

  1. 向量获取元素可以利用Swizzle操作符获取。
  2. 矩阵获取元素和二维数组获取方式一样。
  3. Swizzle操作符可以让我们对向量进行方便的操作。
  4. 向量和矩阵在声明和获取时可以配合使用
  5. 高维向量或矩阵可以用低维容器装载,可以利用这个特点将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

×

喜欢就点赞,疼爱就打赏