当前位置: 首页 > 编程笔记 >

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

徐子石
2023-03-14
本文向大家介绍unity实现贴图矩阵运算(旋转平移缩放),包括了unity实现贴图矩阵运算(旋转平移缩放)的使用技巧和注意事项,需要的朋友参考一下

我们在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);
 }
}

感兴趣的可以自己试一试

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 基本上,我想做的过程描述在这里(特别是看到图像接近尾声),但从一个已知的相机模型和姿态开始。 是否有一个直接的函数调用来获取相机的内部和外部参数,并计算透视矩阵以用于? 在对图像调用之后,我将调用。 原则上,在指定约束之后,我可以通过求解opencv摄像机校准文档顶部定义的方程组来导出解决方案,但我认为必须有一个罐装例程来允许我正射校正我的测试图像。 在我的搜索中,我发现很难通过所有的立体声校准结

  • 在用CV::SolvePnPransac估计摄像机姿态时,输入是objectPoints和ImagePoints。输出是旋转和平移矩阵,加上内点数 利用遗传算法生成一个新的旋转平移矩阵。我喜欢用我的新的旋转和平移来计算内点的数目。 谢谢你的支持

  • 假设我使用大小为8的字符数组来表示图像的碰撞掩码。字符的每一位代表一个像素。实际上,对于64x64矩阵,我将使用长[64]阵列。 因此,框将显示为: 45度的示例输出应该是这样的,尽管旋转可以是任何角度。这个形状对于45度旋转可能不准确,因为我是用手做的。 另一个例子是向右旋转10度?这些值可能是错误的,因为从数学上讲,我不知道它将如何精确旋转,但我认为可以安全地假设,如果每个位的覆盖率超过旧形状

  • 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。 示例 1: 输入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] 输出: [1,2,3,6,9,8,7,4,5] 示例 2: 输入: [ [1, 2, 3, 4], [5, 6, 7, 8], [9,10,11,12] ] 输出: [1,

  • 通过前7节课的学习,我相信你已经对Threejs几何体内部顶点构成有了一定了解。 几何体Geometry对象有一系列的顶点属性,也封装了一系列的方法,通过.scale()、.translate()、.rotateX()等方法可以对几何体本身进行缩放、平移、旋转等几何变换。通过.scale()、.translate()、.rotateX()这些方法对几何体进行变换,注意本质上都是改变结合体顶点位置坐

  • 本文向大家介绍C++实现矩阵原地转置算法,包括了C++实现矩阵原地转置算法的使用技巧和注意事项,需要的朋友参考一下 本文实例描述了C++实现矩阵原地转置算法,是一个非常经典的算法,相信对于学习C++算法的朋友有很大的帮助。具体如下: 一、问题描述 微软面试题:将一个MxN的矩阵存储在一个一维数组中,编程实现矩阵的转置。 要求:空间复杂度为O(1) 二、思路分析 下面以一个4x2的矩阵A={1,2,

  • 给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。 示例: 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 解法如下: /** * @param {number} n * @return {number[][]} */ var generateMatrix = f

  • 点模型Points、线模型Line、网格网格模型Mesh等模型对象的基类都是Object3D,如果想对这些模型进行旋转、缩放、平移等操作,如何实现,可以查询Threejs文档Object3D对相关属性和方法的介绍。 缩放 网格模型Mesh的属性.scale表示模型对象的缩放比例,默认值是THREE.Vector3(1.0,1.0,1.0),.scale的属性值是一个三维向量对象Vector3,查看