Metal渲染:实现旋转/翻转功能
2021-03-17 16:25
标签:播放器 技术 nbsp 这一 com ted 矩阵 dev c中 本文主要讲解如何在使用Metal渲染的时候,实现画面的旋转/翻转功能。 在讲旋转和翻转前先理解两个坐标系统,Metal的NDC (Normalized Device Coordinate) 坐标系统,和纹理坐标。 Metal的NDC是一个原点在中心,边长为2个单位长度的正方体: 对于2D视频渲染,NDC坐标系统就是原点在中心,边长为2个单位长度的正方形。 对于2D纹理来说,其坐标原点在左上角,是边长为1个单位长度的正方形: 我们要实现旋转和翻转有两种方法: 从我们的上层需求来看,旋转都是绕画面中心点进行旋转,翻转也是绕画面居中的水平线(X轴)和垂直线(Y轴)进行翻转,如果对纹理进行操作,原点不在中心,虽然绕任意点做旋转,任意轴做翻转都能实现,但是计算会复杂很多。简化一些的话,我们可以先将坐标原点平移到(0.5, 0.5)的中心再基于原点做转换,最后再把坐标原点平移回去,最开始的一个版本就是这样实现的。 但NDC坐标系统,其原点本身就在中心,旋转翻转操作会方便很多,因此现在的实现中我们都是对NDC坐标(顶点坐标)进行操作。 翻转的实现 水平翻转就是绕NDC坐标系Y轴进行翻转,点(x, y, 1)绕Y转翻转后为(-x, y, 1),变换矩阵为: 垂直翻转就是绕NDC坐标系X轴进行翻转,点(x, y, 1)绕X轴翻转后为(x, -y, 1),变换矩阵为: 平面中一点绕另一点旋转 如图所示,a点绕o点旋转angle角度后(逆时针旋转)到b点的坐标?假设o点为原点,则有计算公式: b.x = a.x*cos(angle) - a.y*sin(angle) b.y = a.x*sin(angle) + a.y*cos(angle) 其中顺时针为负,逆时针为正,角度angle为弧度值。 在我们实现中只两个旋转角度,顺时针90度和逆时针90度,所有的旋转都是这两个旋转通过不断的组合最后叠加的结果。 这里需要注意的是,我们现在旋转的是NDC中的顶点坐标,因此与用户视角来说的的旋转图形(纹理)方向是相反的。 用户期望的画面顺时针旋转90度,也就是顶点坐标逆时针旋转90度(PI/2),cos(PI/2) = 0, sin(PI/2) = 1, 代入公式b点坐标为: b.x = -a.y b.y = a.x 变换矩阵如下: 同样用户期望的画面逆时针旋转90度,即顶点坐标顺时针旋转90度(-PI/2),cos(-PI/2) = 0, sin(-PI/2) = -1, 代入公式b点坐标为: b.x = a.y b.y = -a.x 变换矩阵如下: 每进行旋转/翻转操作后,就是在当前的变换矩阵基础(最开始是标准矩阵)上再乘上相应的翻转/旋转变换矩阵。 旋转存储 一些视频本身会有旋转/翻转的属性,如果产品需要对此情况要求进行自动纠正显示则如何处理? Metal渲染:实现旋转/翻转功能 标签:播放器 技术 nbsp 这一 com ted 矩阵 dev c中 原文地址:https://www.cnblogs.com/csutanyu/p/12768339.html
matrix_float3x3 const GHorizontalFlipMatrix = {
(simd_float3){-1, 0, 0},
(simd_float3){0, 1, 0},
(simd_float3){0, 0, 1}
};
matrix_float3x3 const GVerticalFlipMatrix = {
(simd_float3){1, 0, 0},
(simd_float3){0, -1, 0},
(simd_float3){0, 0, 1}
};
matrix_float3x3 const GClockwiseMatrix = {
(simd_float3){0, 1, 0},
(simd_float3){-1, 0, 0},
(simd_float3){0, 0, 1}
};
matrix_float3x3 const GAntiClockwiseMatrix = {
(simd_float3){0, -1, 0},
(simd_float3){1, 0, 0},
(simd_float3){0, 0, 1}
};
matrix_float3x3 const GIdentityMatrix = {
(simd_float3){1, 0, 0},
(simd_float3){0, 1, 0},
(simd_float3){0, 0, 1}
}
typedef union {
struct {
uint32_t m11:2;
uint32_t m12:2;
uint32_t m13:2;
uint32_t m21:2;
uint32_t m22:2;
uint32_t m23:2;
uint32_t m31:2;
uint32_t m32:2;
uint32_t m33:2;
uint32_t reserved:14;
} matrix;
uint32_t value;
} QLVCompactTranslateMatrix;