unity实现贴图矩阵运算(旋转平移缩放)

作者:bommy游戏 时间:2022-07-27 13:53:41 

我们在shader中对贴图处理时,有时候会有一些比较复杂的运算,比方说三角函数,开方等,一般情况下,如果可以在越上层做运算,性能会越高。C# > Vertex > fragment

因此,考虑到贴图的旋转用到的三角函数,可以使用在C#中传入旋转矩阵得到,然后使用uv直接乘以矩阵就可以了。

封装了vmatrix4x4,分享一下:


using UnityEngine;

namespace D11.Skin
{
public class VMatrix
{
 public float[,] m;

public VMatrix()
 {
  m = new float[4, 4];
  m[0, 0] = 0.0f; m[0, 1] = 0.0f; m[0, 2] = 0.0f; m[0, 3] = 0.0f;
  m[1, 0] = 0.0f; m[1, 1] = 0.0f; m[1, 2] = 0.0f; m[1, 3] = 0.0f;
  m[2, 0] = 0.0f; m[2, 1] = 0.0f; m[2, 2] = 0.0f; m[2, 3] = 0.0f;
  m[3, 0] = 0.0f; m[3, 1] = 0.0f; m[3, 2] = 0.0f; m[3, 3] = 0.0f;
 }

public static void MatrixSetIdentity(VMatrix matrix)
 {
  matrix.m[0,0] = 1.0f; matrix.m[0,1] = 0.0f; matrix.m[0,2] = 0.0f; matrix.m[0,3] = 0.0f;
  matrix.m[1,0] = 0.0f; matrix.m[1,1] = 1.0f; matrix.m[1,2] = 0.0f; matrix.m[1,3] = 0.0f;
  matrix.m[2,0] = 0.0f; matrix.m[2,1] = 0.0f; matrix.m[2,2] = 1.0f; matrix.m[2,3] = 0.0f;
  matrix.m[3,0] = 0.0f; matrix.m[3,1] = 0.0f; matrix.m[3,2] = 0.0f; matrix.m[3,3] = 1.0f;
 }

public static void MatrixBuildTranslation(VMatrix matrix, float x, float y, float z)
 {
  MatrixSetIdentity(matrix);
  matrix.m[0,3] = x;
  matrix.m[1,3] = y;
  matrix.m[2,3] = z;
 }

public static void MatrixBuildTranslation(VMatrix matrix, Vector3 vec)
 {
  MatrixSetIdentity(matrix);
  matrix.m[0, 3] = vec.x;
  matrix.m[1, 3] = vec.y;
  matrix.m[2, 3] = vec.z;
 }

public static void MatrixBuildScale(VMatrix matrix, float x, float y, float z)
 {
  matrix.m[0, 0] = x; matrix.m[0, 1] = 0.0f; matrix.m[0, 2] = 0.0f; matrix.m[0, 3] = 0.0f;
  matrix.m[1, 0] = 0.0f; matrix.m[1, 1] = y; matrix.m[1, 2] = 0.0f; matrix.m[1, 3] = 0.0f;
  matrix.m[2, 0] = 0.0f; matrix.m[2, 1] = 0.0f; matrix.m[2, 2] = z; matrix.m[2, 3] = 0.0f;
  matrix.m[3, 0] = 0.0f; matrix.m[3, 1] = 0.0f; matrix.m[3, 2] = 0.0f; matrix.m[3, 3] = 1.0f;
 }

public static void MatrixBuildScale(VMatrix matrix, Vector3 scale)
 {
  MatrixBuildScale(matrix, scale.x, scale.y, scale.z);
 }

public static void MatrixBuildRotate(VMatrix matrix, float angleDegrees)
 {
  float radians = angleDegrees * (Mathf.PI / 180.0f);

float fSin = Mathf.Sin(radians);
  float fCos = Mathf.Cos(radians);
  matrix.m[0, 0] = fCos; matrix.m[0, 1] = -fSin; matrix.m[0, 2] = 0.0f; matrix.m[0, 3] = 0.0f;
  matrix.m[1, 0] = fSin; matrix.m[1, 1] = fCos; matrix.m[1, 2] = 0.0f; matrix.m[1, 3] = 0.0f;
  matrix.m[2, 0] = 0.0f; matrix.m[2, 1] = 0.0f; matrix.m[2, 2] = 1.0f; matrix.m[2, 3] = 0.0f;
  matrix.m[3, 0] = 0.0f; matrix.m[3, 1] = 0.0f; matrix.m[3, 2] = 0.0f; matrix.m[3, 3] = 1.0f;
 }

public static VMatrix MatrixMultiply(VMatrix src1, VMatrix src2)
 {
  VMatrix dst = new VMatrix();
  dst.m[0,0] = src1.m[0,0] * src2.m[0,0] + src1.m[0,1] * src2.m[1,0] + src1.m[0,2] * src2.m[2,0] + src1.m[0,3] * src2.m[3,0];
  dst.m[0,1] = src1.m[0,0] * src2.m[0,1] + src1.m[0,1] * src2.m[1,1] + src1.m[0,2] * src2.m[2,1] + src1.m[0,3] * src2.m[3,1];
  dst.m[0,2] = src1.m[0,0] * src2.m[0,2] + src1.m[0,1] * src2.m[1,2] + src1.m[0,2] * src2.m[2,2] + src1.m[0,3] * src2.m[3,2];
  dst.m[0,3] = src1.m[0,0] * src2.m[0,3] + src1.m[0,1] * src2.m[1,3] + src1.m[0,2] * src2.m[2,3] + src1.m[0,3] * src2.m[3,3];

dst.m[1,0] = src1.m[1,0] * src2.m[0,0] + src1.m[1,1] * src2.m[1,0] + src1.m[1,2] * src2.m[2,0] + src1.m[1,3] * src2.m[3,0];
  dst.m[1,1] = src1.m[1,0] * src2.m[0,1] + src1.m[1,1] * src2.m[1,1] + src1.m[1,2] * src2.m[2,1] + src1.m[1,3] * src2.m[3,1];
  dst.m[1,2] = src1.m[1,0] * src2.m[0,2] + src1.m[1,1] * src2.m[1,2] + src1.m[1,2] * src2.m[2,2] + src1.m[1,3] * src2.m[3,2];
  dst.m[1,3] = src1.m[1,0] * src2.m[0,3] + src1.m[1,1] * src2.m[1,3] + src1.m[1,2] * src2.m[2,3] + src1.m[1,3] * src2.m[3,3];

dst.m[2,0] = src1.m[2,0] * src2.m[0,0] + src1.m[2,1] * src2.m[1,0] + src1.m[2,2] * src2.m[2,0] + src1.m[2,3] * src2.m[3,0];
  dst.m[2,1] = src1.m[2,0] * src2.m[0,1] + src1.m[2,1] * src2.m[1,1] + src1.m[2,2] * src2.m[2,1] + src1.m[2,3] * src2.m[3,1];
  dst.m[2,2] = src1.m[2,0] * src2.m[0,2] + src1.m[2,1] * src2.m[1,2] + src1.m[2,2] * src2.m[2,2] + src1.m[2,3] * src2.m[3,2];
  dst.m[2,3] = src1.m[2,0] * src2.m[0,3] + src1.m[2,1] * src2.m[1,3] + src1.m[2,2] * src2.m[2,3] + src1.m[2,3] * src2.m[3,3];

dst.m[3,0] = src1.m[3,0] * src2.m[0,0] + src1.m[3,1] * src2.m[1,0] + src1.m[3,2] * src2.m[2,0] + src1.m[3,3] * src2.m[3,0];
  dst.m[3,1] = src1.m[3,0] * src2.m[0,1] + src1.m[3,1] * src2.m[1,1] + src1.m[3,2] * src2.m[2,1] + src1.m[3,3] * src2.m[3,1];
  dst.m[3,2] = src1.m[3,0] * src2.m[0,2] + src1.m[3,1] * src2.m[1,2] + src1.m[3,2] * src2.m[2,2] + src1.m[3,3] * src2.m[3,2];
  dst.m[3,3] = src1.m[3,0] * src2.m[0,3] + src1.m[3,1] * src2.m[1,3] + src1.m[3,2] * src2.m[2,3] + src1.m[3,3] * src2.m[3,3];
  return dst;
 }

public Vector4 MatrixGetCol(int nCol)
 {
  System.Diagnostics.Debug.Assert((nCol >= 0) && (nCol <= 3));

Vector4 vec;
  vec.x = m[0,nCol];
  vec.y = m[1,nCol];
  vec.z = m[2,nCol];
  vec.w = m[3,nCol];
  return vec;
 }

public Vector4 MatrixGetRow(int nRow)
 {
  System.Diagnostics.Debug.Assert((nRow >= 0) && (nRow <= 3));
  Vector4 vec;
  vec.x = m[nRow, 0];
  vec.y = m[nRow, 1];
  vec.z = m[nRow, 2];
  vec.w = m[nRow, 3];
  return vec;
 }

public static VMatrix GetSRTMatrix(Vector2 scale, float rotation, Vector2 center, Vector2 translation)
 {
  VMatrix mat = new VMatrix();
  VMatrix temp = new VMatrix();

MatrixBuildScale(mat, scale.x, scale.y, 1.0f);
  MatrixBuildTranslation(temp, -center);
  mat = MatrixMultiply(temp, mat);
  MatrixBuildRotate(temp, rotation);
  mat = MatrixMultiply(temp, mat);
  MatrixBuildTranslation(temp, center.x + translation.x, center.y - translation.y, 0.0f);
  mat = MatrixMultiply(temp, mat);
  return mat;
 }
}
}

调用方式:


VMatrix matrix = VMatrix.GetSRTMatrix(scale, -m_cur_rotate, center, translation + translationExtra);
m_CRTTexture.material.SetVector("_SRT0", matrix.MatrixGetRow(0));
m_CRTTexture.material.SetVector("_SRT1", matrix.MatrixGetRow(1));

shader使用:


Properties
{
_SRT0("PatternSRT0", Vector) = (1, 1, 1, 1)
_SRT1("PatternSRT1", Vector) = (1, 1, 1, 1)
}

Pass
{
float4 _SRT0;
float4 _SRT1;

float4 get_pattern_color(float2 uv)
{
float2 uv2;
uv2.x = dot(uv, _SRT0.xy) + _SRT0.w;
uv2.y = dot(uv, _SRT1.xy) + _SRT1.w;
return tex2D(_PatternTexture, uv2);
}
}

感兴趣的可以自己试一试

来源:https://blog.csdn.net/qq_17347313/article/details/107405746

标签:unity,矩阵
0
投稿

猜你喜欢

  • java文件输出流写文件的几种方法

    2023-11-08 16:17:30
  • Java日常练习题,每天进步一点点(8)

    2022-04-15 16:40:26
  • 企业级Kubernetes管理平台Wayne功能特性介绍

    2021-11-05 08:58:33
  • 完美解决虚拟按键遮盖底部视图的问题

    2021-11-24 23:48:25
  • mybatis自定义类型处理器TypehHandler示例详解

    2023-10-11 04:30:40
  • Java中new关键字和newInstance方法的区别分享

    2022-12-04 03:12:52
  • MyBatisPlus深入探究映射匹配的兼容性

    2023-01-08 08:57:26
  • C#实现移除字符串末尾指定字符的方法

    2023-02-09 13:32:21
  • Java建造者设计模式详解

    2022-09-19 13:14:11
  • C#程序员统计自己的代码行数

    2021-10-18 05:37:37
  • Android 消息机制详解及实例代码

    2023-07-28 08:37:49
  • 详解C#对XML、JSON等格式的解析

    2022-06-04 22:45:50
  • Android基于Intent实现Activity之间数据传递的方法

    2022-08-01 16:34:04
  • Java计算两个程序运行时间的实例

    2022-01-30 14:49:06
  • 一文详解Java中Stream流的使用

    2021-08-23 11:54:51
  • kotlin java 混合代码 maven 打包实现

    2023-04-09 13:33:41
  • Java之SpringBean生命周期问题理解

    2022-11-16 14:47:35
  • Android实现水波纹效果

    2022-12-11 01:47:16
  • Java数据结构之基于比较的排序算法基本原理及具体实现

    2022-05-16 08:41:53
  • C语言实现双向链表

    2023-05-30 08:02:24
  • asp之家 软件编程 m.aspxhome.com