Unity中Shader旋转矩阵(二维旋转矩阵)

文章目录


前言

在Shader中,我们经常对顶点进行旋转变换。我们在这篇文章中了解一下旋转使用的旋转矩阵。


一、旋转矩阵的原理

我们先在2D平面下,了解2D原理

1、我们以原点为中心,旋转坐标轴θ度

我们需要求的就是坐标系旋转后,P点在旋转后坐标系中的位置。

因为,我们旋转物体时,我们是围绕着一个轴旋转。

旋转后,我们需要求的就是物体顶点围绕该轴旋转后的坐标位置。

这里我们的 P 点就像 模型的顶点一样,得到P点的位置,就相当于得到了模型顶点在旋转后的位置。

  • 旋转前 P1(2,3)
  • 旋转后 P2 (?,?)

2、求 P2x

  • 求 P2x 可以化为求 OB + BC

  • 求OB:

  • 求BC:

  • P2x = OB + BC

    P2x = OB + BC = cos(θ)P1x + sin(θ)P1y

3、求P2y:

  • 求P2y可以化为求 OC - AC
  • 求OC:
  • 求AC:
  • P2y = OC - AC
    P2y = OC - AC = cos(θ)P1y - sin(θ)P1x

4、最后得到 P2点 的点阵

这个点阵就是我们旋转矩阵的核心

  • P2x = OB + BC = cos(θ)P1x + sin(θ)P1y
  • P2y = OC - AC = cos(θ)P1y - sin(θ)P1x

5、该点阵可以拆分为以下两个矩阵相乘的结果

因为,我们该点阵目前是在二维平面旋转。所以,可以认为我们是围绕 z 轴在旋转。

  • Mrotate就是我们的旋转矩阵
  • P1 就是我们旋转前的点

二、在Shader中,使用该旋转矩阵实现围绕 z 轴旋转

1、在属性面板定义 float 变量作为旋转的角度θ

_Angle("Angle",Float) = 0

2、在常量缓冲区申明该变量

CBUFFER_START(UnityPerMaterial)

float _Angle;

CBUFFER_END

3、在 顶点着色器 定义旋转矩阵

float2x2 M_rotate = float2x2

(

cos(_Angle),sin(_Angle),

-sin(_Angle),cos(_Angle)

);

4、用旋转矩阵乘以顶点的 xy 实现围绕z轴旋转

v.vertexOS.xy = mul(M_rotate,v.vertexOS.xy);

5、效果

围绕x轴旋转 和 围绕y轴旋转,我们可以修改 .xy 来实现。


三、测试代码

复制代码
//平移变换
//缩放变换
//旋转变换
Shader "MyShader/URP/P3_5_5"
{
    Properties
    {
        _Translate("Translate(XYZ)",Vector) = (0,0,0,0)
        _Scale("Scale(XYZ)",Vector)= (1,1,1,1)
        _Angle("Angle",Float) = 0
    }
    SubShader
    {
        Tags
        {
            "PenderPipeline"="UniversalPipeline"
            "RenderType"="Opaque"
            "Queue"="Geometry"
        }
        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            struct Attribute
            {
                float4 vertexOS : POSITION;
            };

            struct Varying
            {
                float4 vertexCS : SV_POSITION;
            };

            CBUFFER_START(UnityPerMaterial)
            float4 _Translate;
            float4 _Scale;
            float _Angle;
            CBUFFER_END
            Varying vert (Attribute v)
            {
                Varying o;
                //平移变换
                float4x4 M_Translate = float4x4
                    (
                    1,0,0,_Translate.x,
                    0,1,0,_Translate.y,
                    0,0,1,_Translate.z,
                    0,0,0,1
                    );
                v.vertexOS = mul(M_Translate,v.vertexOS);
                //缩放交换
                float4x4 M_Scale = float4x4
                    (
                    _Scale.x,0,0,0,
                    0,_Scale.y,0,0,
                    0,0,_Scale.z,0,
                    0,0,0,1
                    );
                v.vertexOS = mul(M_Scale,v.vertexOS);
                //旋转变换
                float2x2 M_rotate = float2x2
                    (
                    cos(_Angle),sin(_Angle),
                    -sin(_Angle),cos(_Angle)
                    );
                v.vertexOS.xy = mul(M_rotate,v.vertexOS.xy);
                o.vertexCS = TransformObjectToHClip(v.vertexOS.xyz);
                return o;
            }

            half4 frag (Varying i) : SV_Target
            {
                return 1;
            }
            ENDHLSL
        }
    }
}
相关推荐
有梦想的骇客7 小时前
书籍将正方形矩阵顺时针转动90°(8)0605
线性代数·算法·矩阵
有梦想的骇客7 小时前
书籍“之“字形打印矩阵(8)0609
java·算法·矩阵
记得早睡~13 小时前
leetcode73-矩阵置零
数据结构·leetcode·矩阵
XR-AI-JK14 小时前
Unity VR/MR开发-开发环境准备
unity·vr·mr
音程15 小时前
矩阵和向量范数的区别分析
人工智能·线性代数·矩阵
T.D.C19 小时前
【渲染】Unity-分析URP的延迟渲染-DeferredShading
unity·游戏引擎
XR-AI-JK2 天前
Unity VR/MR开发-VR/开发SDK选型对比分析
unity·vr·mr
aichitang20242 天前
矩阵详解:从基础概念到实际应用
线性代数·算法·矩阵
心之所向,自强不息2 天前
【Unity Shader编程】之让画面动起来
unity·游戏引擎
雷达学弱狗2 天前
word操作(持续更新)
矩阵