unity实现贴图矩阵运算(旋转平移缩放)
作者:bommy游戏 发布时间:2022-07-27 13:53:41
标签: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 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);
}
}
感兴趣的可以自己试一试
来源:https://blog.csdn.net/qq_17347313/article/details/107405746


猜你喜欢
- 进阶JavaSE-三大接口:Comparator、Comparable和Cloneable。Comparable和Comparator这两个
- 本文接上文“java反射之获取类的信息方法(推荐)”,利用反射(invoke)来获取一个类中的方法来执行。1、定义一个类,包含三个名称相同,
- 实例如下:static bool CheckPowerOfTwo(ulong num){ return num > 0 &
- 继续练习自定义View,这次带来的圆形进度条控件与之前的圆形百分比控件大同小异,这次涉及到了渐变渲染以及画布旋转等知识点,效果如下:虽然步骤
- 概览Android Studio 4.1 目前已经发布,该版本共修复了2370 个 bug 以及 275 个 issue,主要包含如下新增功
- windows环境下1、输出logcat日志到本地文件adb logcat -> F:/logcat.txt2、输出带时间的logca
- using System.Runtime.InteropServices;using System.Drawing.Imaging;&nbs
- 程序绑定的概念:绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后
- 背景公司的一个服务需要做类似于分片的逻辑,一开始服务基于传统部署方式通过本地配置文件配置的方式就可以指定该机器服务的分片内容如:0,1,2,
- 有时我们需要判断某个类是否实现了某个接口(Interface),比如在使用反射机制(Reflection)来查找特定类型的时候。简单来说,可
- 要使用SAPI,首先添加引用DotNetSpeech,请自行下载DotNetSpeech.dll。 初始化对象,SpVoice voice
- AOP是Spring中的面向切面的编程,这里简单感受一下如何在xml文件中配置一个切面。如上图所示,配置一个切面的主要思路有以下几个步骤。1
- 1.JVM Heap(堆)溢出:java.lang.OutOfMemoryError: Java heap spaceJVM在启动的时候会自
- 本文主要介绍了隐式Intent匹配目标组件的规则,若有叙述不清晰或是不准确的地方希望大家指出,谢谢大家: )1. Intent简
- DateTime类DateTime类是C#中最常用的时间类之一,它表示一个日期和时间。可以使用DateTime.Now属性获取当前时间,也可
- 1.JMM数据原子操作read(读取)∶从主内存读取数据load(载入):将主内存读取到的数据写入工作内存use(使用):从工作内存读取数据
- 这篇文章主要介绍了Java多态中动态绑定原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以
- stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,瞬
- 使用Button时为了让用户有“按下”的效果,有两种实现方式:1.在代码里面。imageButton.setOnTouchListener(
- 前言最近学习java,接触到了回调机制(CallBack)。初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯