unity實(shí)現(xiàn)貼圖矩陣運(yùn)算(旋轉(zhuǎn)平移縮放)
我們?cè)趕hader中對(duì)貼圖處理時(shí),有時(shí)候會(huì)有一些比較復(fù)雜的運(yùn)算,比方說(shuō)三角函數(shù),開(kāi)方等,一般情況下,如果可以在越上層做運(yùn)算,性能會(huì)越高。C# > Vertex > fragment
因此,考慮到貼圖的旋轉(zhuǎn)用到的三角函數(shù),可以使用在C#中傳入旋轉(zhuǎn)矩陣得到,然后使用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;
}
}
}
調(diào)用方式:
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);
}
}
感興趣的可以自己試一試
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#遍歷文件夾及其子目錄的完整實(shí)現(xiàn)方法
這篇文章主要介紹了C#遍歷文件夾及其子目錄的方法,涉及C#文件與目錄的基本操作技巧,簡(jiǎn)單實(shí)用,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
自動(dòng)輸出類(lèi)的字段值實(shí)用代碼分享
有點(diǎn)時(shí)候在測(cè)試的時(shí)候希望打印輸出返回對(duì)象的各字段的值,采用下面的代碼可以很方便的列出對(duì)象的各字段值2013-12-12
System.Data.OleDb.OleDbException: 未指定的錯(cuò)誤的完美解決方法
本文給大家?guī)?lái)三種有關(guān)System.Data.OleDb.OleDbException: 未指定的錯(cuò)誤的完美解決方法,每種方法都很不錯(cuò),需要的朋友可以參考下2016-09-09
C# 使用multipart form-data方式post數(shù)據(jù)到服務(wù)器
這篇文章主要介紹了C# 使用multipart form-data方式post數(shù)據(jù)到服務(wù)器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
C#實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)繪圖graphic的方法示例
這篇文章主要介紹了C#實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)繪圖graphic的方法,結(jié)合實(shí)例形式分析了C#根據(jù)動(dòng)態(tài)數(shù)據(jù)繪制2D數(shù)據(jù)表格的相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
C#實(shí)現(xiàn)讀寫(xiě)ini文件類(lèi)實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)讀寫(xiě)ini文件類(lèi),實(shí)例分析了C#實(shí)現(xiàn)針對(duì)ini文件的讀、寫(xiě)、刪除等操作的常用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03

