当前位置: 首页 > news >正文

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

文章目录

  • 前言
  • 一、旋转矩阵的原理
    • 1、我们以原点为中心,旋转坐标轴θ度
    • 2、求 P~2x~:
    • 3、求P~2y~:
    • 4、最后得到 P~2~点 的点阵
    • 5、该点阵可以拆分为以下两个矩阵相乘的结果
  • 二、在Shader中,使用该旋转矩阵实现围绕 z 轴旋转
    • 1、在属性面板定义 float 变量作为旋转的角度θ
    • 2、在常量缓冲区申明该变量
    • 3、在 顶点着色器 定义旋转矩阵
    • 4、用旋转矩阵乘以顶点的 xy 实现围绕z轴旋转
    • 5、效果
    • `围绕x轴旋转 和 围绕y轴旋转,我们可以修改 .xy 来实现。` ![请添加图片描述](https://img-blog.csdnimg.cn/direct/db2057e3d34c46b691e8525e213c7c34.gif)
  • 三、测试代码


前言

在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_ENDVarying 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}}
}
http://www.lryc.cn/news/264685.html

相关文章:

  • 前端面试题(计算机网络):options请求方法及使用场景
  • 使用docker-compose管理docker服务
  • Python_Tkinter和OpenCV模拟行星凌日传输光度测定
  • 【安全】使用auparse解析auditd审计日志
  • flink watermark 实例分析
  • 系列十二(面试)、Java中的GC回收类型有哪些?
  • 华为数通方向HCIP-DataCom H12-831题库(多选题:201-220)
  • NLP论文阅读记录 - | 使用GPT对大型文档集合进行抽象总结
  • 华为全屋wifi6蜂鸟套装标准
  • 系列二十八、如何在Oracle官网下载JDK的api文档
  • STM32-ADC模数转换器
  • 谷歌手机安装证书到根目录
  • 代码随想录 322. 零钱兑换
  • 【图的应用二:最短路径】- 用 C 语言实现迪杰斯特拉算法和弗洛伊德算法
  • Qt之判断一个点是否在多边形内部(射线法)
  • 压力测试过程中内存溢出(堆溢出、栈溢出、持久代溢出)情况如何解决
  • 【工业智能】音频信号相关场景
  • (PC+WAP)装修设计公司网站模板 家装公司网站源码下载
  • 使用opencv实现图像中几何图形检测
  • 补题与周总结:leetcode第 376 场周赛
  • js指纹库,可跟踪用户唯一性
  • Shell三剑客:awk(内部变量)
  • JVM中的虚拟机栈的动态链接部分存放到底是什么
  • Leetcode 55 跳跃游戏
  • 构建陪诊预约系统:技术实战指南
  • windows和linux将文件删除至回收站【C++】【Go】语言实现
  • 10 Vue3中v-html指令的用法
  • 华为数通方向HCIP-DataCom H12-831题库(多选题:181-200)
  • DC-磁盘管理
  • 使用Docker运行镜像文件与设置端口