当前位置: 移动技术网 > IT编程>开发语言>c# > unity实现贴图矩阵运算(旋转平移缩放)

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

2020年08月17日  | 移动技术网IT编程  | 我要评论
我们在shader中对贴图处理时,有时候会有一些比较复杂的运算,比方说三角函数,开方等,一般情况下,如果可以在越上层做运算,性能会越高。c#> vertex > fragment因此,考虑

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

感兴趣的可以自己试一试

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网