unity实现贴图矩阵运算(旋转平移缩放)
我们在shader中对贴图处理时,有时候会有一些比较复杂的运算,比方说三角函数,开方等,一般情况下,如果可以在越上层做运算,性能会越高。C# >Vertex>fragment
因此,考虑到贴图的旋转用到的三角函数,可以使用在C#中传入旋转矩阵得到,然后使用uv直接乘以矩阵就可以了。
封装了vmatrix4x4,分享一下:
usingUnityEngine;
namespaceD11.Skin
{
publicclassVMatrix
{
publicfloat[,]m;
publicVMatrix()
{
m=newfloat[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;
}
publicstaticvoidMatrixSetIdentity(VMatrixmatrix)
{
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;
}
publicstaticvoidMatrixBuildTranslation(VMatrixmatrix,floatx,floaty,floatz)
{
MatrixSetIdentity(matrix);
matrix.m[0,3]=x;
matrix.m[1,3]=y;
matrix.m[2,3]=z;
}
publicstaticvoidMatrixBuildTranslation(VMatrixmatrix,Vector3vec)
{
MatrixSetIdentity(matrix);
matrix.m[0,3]=vec.x;
matrix.m[1,3]=vec.y;
matrix.m[2,3]=vec.z;
}
publicstaticvoidMatrixBuildScale(VMatrixmatrix,floatx,floaty,floatz)
{
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;
}
publicstaticvoidMatrixBuildScale(VMatrixmatrix,Vector3scale)
{
MatrixBuildScale(matrix,scale.x,scale.y,scale.z);
}
publicstaticvoidMatrixBuildRotate(VMatrixmatrix,floatangleDegrees)
{
floatradians=angleDegrees*(Mathf.PI/180.0f);
floatfSin=Mathf.Sin(radians);
floatfCos=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;
}
publicstaticVMatrixMatrixMultiply(VMatrixsrc1,VMatrixsrc2)
{
VMatrixdst=newVMatrix();
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];
returndst;
}
publicVector4MatrixGetCol(intnCol)
{
System.Diagnostics.Debug.Assert((nCol>=0)&&(nCol<=3));
Vector4vec;
vec.x=m[0,nCol];
vec.y=m[1,nCol];
vec.z=m[2,nCol];
vec.w=m[3,nCol];
returnvec;
}
publicVector4MatrixGetRow(intnRow)
{
System.Diagnostics.Debug.Assert((nRow>=0)&&(nRow<=3));
Vector4vec;
vec.x=m[nRow,0];
vec.y=m[nRow,1];
vec.z=m[nRow,2];
vec.w=m[nRow,3];
returnvec;
}
publicstaticVMatrixGetSRTMatrix(Vector2scale,floatrotation,Vector2center,Vector2translation)
{
VMatrixmat=newVMatrix();
VMatrixtemp=newVMatrix();
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);
returnmat;
}
}
}
调用方式:
VMatrixmatrix=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;
float4get_pattern_color(float2uv)
{
float2uv2;
uv2.x=dot(uv,_SRT0.xy)+_SRT0.w;
uv2.y=dot(uv,_SRT1.xy)+_SRT1.w;
returntex2D(_PatternTexture,uv2);
}
}
感兴趣的可以自己试一试
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。