SoFunction
Updated on 2025-03-02

Unity implements map matrix operation (rotate translation and zoom)

When we process maps in shaders, sometimes there are some more complex operations, such as trigonometric functions, square opening, etc. Generally speaking, if we can do operations at the upper level, the higher the performance will be. C# > Vertex > fragment

Therefore, considering the trigonometric function used to rotate the map, you can use the rotation matrix to pass it in C# and then use uv to multiply the matrix directly.

Encapsulated vmatrix4x4, share:

using UnityEngine;
 
namespace 
{
 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)
  {
   [0,0] = 1.0f; [0,1] = 0.0f; [0,2] = 0.0f; [0,3] = 0.0f;
   [1,0] = 0.0f; [1,1] = 1.0f; [1,2] = 0.0f; [1,3] = 0.0f;
   [2,0] = 0.0f; [2,1] = 0.0f; [2,2] = 1.0f; [2,3] = 0.0f;
   [3,0] = 0.0f; [3,1] = 0.0f; [3,2] = 0.0f; [3,3] = 1.0f;
  }
 
  public static void MatrixBuildTranslation(VMatrix matrix, float x, float y, float z)
  {
   MatrixSetIdentity(matrix);
   [0,3] = x;
   [1,3] = y;
   [2,3] = z;
  }
 
  public static void MatrixBuildTranslation(VMatrix matrix, Vector3 vec)
  {
   MatrixSetIdentity(matrix);
   [0, 3] = ;
   [1, 3] = ;
   [2, 3] = ;
  }
 
  public static void MatrixBuildScale(VMatrix matrix, float x, float y, float z)
  {
   [0, 0] = x; [0, 1] = 0.0f; [0, 2] = 0.0f; [0, 3] = 0.0f;
   [1, 0] = 0.0f; [1, 1] = y; [1, 2] = 0.0f; [1, 3] = 0.0f;
   [2, 0] = 0.0f; [2, 1] = 0.0f; [2, 2] = z; [2, 3] = 0.0f;
   [3, 0] = 0.0f; [3, 1] = 0.0f; [3, 2] = 0.0f; [3, 3] = 1.0f;
  }
 
  public static void MatrixBuildScale(VMatrix matrix, Vector3 scale)
  {
   MatrixBuildScale(matrix, , , );
  }
 
  public static void MatrixBuildRotate(VMatrix matrix, float angleDegrees)
  {
   float radians = angleDegrees * ( / 180.0f);
 
   float fSin = (radians);
   float fCos = (radians);
   [0, 0] = fCos; [0, 1] = -fSin; [0, 2] = 0.0f; [0, 3] = 0.0f;
   [1, 0] = fSin; [1, 1] = fCos; [1, 2] = 0.0f; [1, 3] = 0.0f;
   [2, 0] = 0.0f; [2, 1] = 0.0f; [2, 2] = 1.0f; [2, 3] = 0.0f;
   [3, 0] = 0.0f; [3, 1] = 0.0f; [3, 2] = 0.0f; [3, 3] = 1.0f;
  }
 
  public static VMatrix MatrixMultiply(VMatrix src1, VMatrix src2)
  {
   VMatrix dst = new VMatrix();
   [0,0] = [0,0] * [0,0] + [0,1] * [1,0] + [0,2] * [2,0] + [0,3] * [3,0];
   [0,1] = [0,0] * [0,1] + [0,1] * [1,1] + [0,2] * [2,1] + [0,3] * [3,1];
   [0,2] = [0,0] * [0,2] + [0,1] * [1,2] + [0,2] * [2,2] + [0,3] * [3,2];
   [0,3] = [0,0] * [0,3] + [0,1] * [1,3] + [0,2] * [2,3] + [0,3] * [3,3];
 
   [1,0] = [1,0] * [0,0] + [1,1] * [1,0] + [1,2] * [2,0] + [1,3] * [3,0];
   [1,1] = [1,0] * [0,1] + [1,1] * [1,1] + [1,2] * [2,1] + [1,3] * [3,1];
   [1,2] = [1,0] * [0,2] + [1,1] * [1,2] + [1,2] * [2,2] + [1,3] * [3,2];
   [1,3] = [1,0] * [0,3] + [1,1] * [1,3] + [1,2] * [2,3] + [1,3] * [3,3];
 
   [2,0] = [2,0] * [0,0] + [2,1] * [1,0] + [2,2] * [2,0] + [2,3] * [3,0];
   [2,1] = [2,0] * [0,1] + [2,1] * [1,1] + [2,2] * [2,1] + [2,3] * [3,1];
   [2,2] = [2,0] * [0,2] + [2,1] * [1,2] + [2,2] * [2,2] + [2,3] * [3,2];
   [2,3] = [2,0] * [0,3] + [2,1] * [1,3] + [2,2] * [2,3] + [2,3] * [3,3];
 
   [3,0] = [3,0] * [0,0] + [3,1] * [1,0] + [3,2] * [2,0] + [3,3] * [3,0];
   [3,1] = [3,0] * [0,1] + [3,1] * [1,1] + [3,2] * [2,1] + [3,3] * [3,1];
   [3,2] = [3,0] * [0,2] + [3,1] * [1,2] + [3,2] * [2,2] + [3,3] * [3,2];
   [3,3] = [3,0] * [0,3] + [3,1] * [1,3] + [3,2] * [2,3] + [3,3] * [3,3];
   return dst;
  }
 
  public Vector4 MatrixGetCol(int nCol)
  {
   ((nCol >= 0) && (nCol <= 3));
 
   Vector4 vec;
    = m[0,nCol];
    = m[1,nCol];
    = m[2,nCol];
    = m[3,nCol];
   return vec;
  }
 
  public Vector4 MatrixGetRow(int nRow)
  {
   ((nRow >= 0) && (nRow <= 3));
   Vector4 vec;
    = m[nRow, 0];
    = m[nRow, 1];
    = m[nRow, 2];
    = 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,  + ,  - , 0.0f);
   mat = MatrixMultiply(temp, mat);
   return mat;
  }
 }
}

Call method:

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

Shader uses:

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;
  = dot(uv, _SRT0.xy) + _SRT0.w;
  = dot(uv, _SRT1.xy) + _SRT1.w;
 return tex2D(_PatternTexture, uv2);
 }
}

If you are interested, you can try it yourself

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.