1. 程式人生 > 程式設計 >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 z)
  {
   matrix.m[0,0] = x; matrix.m[0,1] = y; matrix.m[1,2] = z; matrix.m[2,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,0] = fSin; matrix.m[1,1] = fCos; matrix.m[1,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,2] * src2.m[2,3] * src2.m[3,0];
   dst.m[0,1] = src1.m[0,1] + src1.m[0,1];
   dst.m[0,2] = src1.m[0,2] + src1.m[0,2];
   dst.m[0,3] = src1.m[0,3] + src1.m[0,3];
 
   dst.m[1,0] = src1.m[1,0] + src1.m[1,0];
   dst.m[1,1] = src1.m[1,1] + src1.m[1,1];
   dst.m[1,2] = src1.m[1,2] + src1.m[1,2];
   dst.m[1,3] = src1.m[1,3] + src1.m[1,3];
 
   dst.m[2,0] = src1.m[2,0] + src1.m[2,0];
   dst.m[2,1] = src1.m[2,1] + src1.m[2,1];
   dst.m[2,2] = src1.m[2,2] + src1.m[2,2];
   dst.m[2,3] = src1.m[2,3] + src1.m[2,3];
 
   dst.m[3,0] = src1.m[3,0] + src1.m[3,0];
   dst.m[3,1] = src1.m[3,1] + src1.m[3,1];
   dst.m[3,2] = src1.m[3,2] + src1.m[3,2];
   dst.m[3,3] = src1.m[3,3] + src1.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,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)
 _SRT1("PatternSRT1",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);
 }
}

感興趣的可以自己試一試

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。