unity实现贴图矩阵运算(旋转平移缩放)
- 作者: 动人湖泊
- 来源: 51数据库
- 2021-08-23
我们在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);
}
}
感兴趣的可以自己试一试
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
- C#通过fleck实现wss协议的WebSocket多人Web实时聊天(附源码)
- 团队城市未满足要求:MSBuildTools12.0_x86_Path 存在
- 使用 MSBuild.exe 在发布模式下构建 C# 解决方案
- 当我发布 Web 应用程序时,AfterPublish 脚本不运行
- 构建时 T4 转换的产品仅在下一个构建中使用
- ASP.NET Core Application (.NET Framework) for Windows x64 only error in project.assets.json
- 新的 .csproj 格式 - 如何将整个目录指定为“链接文件"到子目录?
- 如何将条件编译符号(DefineConstants)传递给 msbuild
- MSBuild 支持 Visual Studio 2017 RTM 中的 T4 模板
- NuGet 包还原找不到包,没有源
热点文章
团队城市未满足要求:MSBuildTools12.0_x86_Path 存在
0
使用 MSBuild.exe 在发布模式下构建 C# 解决方案
0
当我发布 Web 应用程序时,AfterPublish 脚本不运行
0
构建时 T4 转换的产品仅在下一个构建中使用
0
ASP.NET Core Application (.NET Framework) for Windows x64 only error in project.assets.json
0
新的 .csproj 格式 - 如何将整个目录指定为“链接文件"到子目录?
0
如何将条件编译符号(DefineConstants)传递给 msbuild
0
MSBuild 支持 Visual Studio 2017 RTM 中的 T4 模板
0
NuGet 包还原找不到包,没有源
0
使用 C# 6.0 功能运行 TFS 构建
0
