6.基于BLE SoC芯片GR5526开发GPU 3D图形效果(6) - 开发炫酷新动画

系列文章:

1.基于BLE SoC芯片GR5526开发GPU 3D图形效果(1) - 概览

2.基于BLE SoC芯片GR5526开发GPU 3D图形效果(2) - 先看Demo效果

3.基于BLE SoC芯片GR5526开发GPU 3D图形效果(3) - GPU知识概念梳理

4.基于BLE SoC芯片GR5526开发GPU 3D图形效果(4) - 解析第一个GPU工程

5.基于BLE SoC芯片GR5526开发GPU 3D图形效果(5) - 理解图形学中的矩阵变换

6.基于BLE SoC芯片GR5526开发GPU 3D图形效果(6) - 开发炫酷新动画

前言:  这个专题的几篇文章下来, 对汇顶GR5526 的特点和图形化能力, 总体有了一个熟悉和理解. 可不可以在 GR5526  SDK 的基础上, 再开发出一些新的动画效果, 来应用到产品上, 让产品更炫酷一些呢?  毕竟这就是 GPU 应该具备的能力和强项.  答案必定是可以的.

结合前面的知识点,  再深入看了下 graphics_animation_effects 和 graphics_rotate_box 示例工程的参考代码,  这篇文章来开发一个新效果.

一、绘制旋转立方体的MVVP 矩阵变换逻辑

1. 定义立方体8个点(x,y,z)的初始坐标


        坐标系为 X向右Y向下Z向后. 参考上图

  • box_size_2 设置0.2, 是对立方体进行了缩小处理
  • FoV 是一个经验值, 参考上一篇文章, 可以根据效果进行条件
  • v[] 定义了 立方体6个面8个点的NDC 坐标

float box_size_2 = 0.2f;

float FoV = 28.0724869359f;

   

//x     y    z

float v[]   = {-box_size_2, -box_size_2, box_size_2,   //0  0

                    box_size_2, -box_size_2, box_size_2,   //1  3

                    box_size_2,  box_size_2, box_size_2,   //2  6

                   -box_size_2,  box_size_2, box_size_2,   //3  9

                   -box_size_2, -box_size_2,-box_size_2,   //4  12

                    box_size_2, -box_size_2,-box_size_2,   //5  15

                    box_size_2,  box_size_2,-box_size_2,   //6  18

                   -box_size_2,  box_size_2,-box_size_2};  //7  21

2. 用参数组合(FoV=28.07, aspect=1, near=0.2, far=100) 构建透视投影矩阵

  • 454/454 表示屏幕的宽高都为 454 像素, 正方屏, aspect 算下来为1
  • Fov, Near 和 far 给的 经验值, 可以根据需要条件

hal_gfx_matrix4x4_t mvp;

hal_gfx_mat4x4_load_perspective(mvp, FoV, (float)454/454, 0.2f, 100.f);

3. M 变换

创建单位矩阵, 在其基础上分别进行基于 X/Y/Z 轴的角度旋转. 然后再进行 Z=1.8 轴向平移.

  • 这里进行的是从局部空间到世界空间的模型变换(Model Transform)

hal_gfx_matrix4x4_t proj;

hal_gfx_mat4x4_load_identity(proj);

hal_gfx_mat4x4_rotate_X(proj, angle_x);

hal_gfx_mat4x4_rotate_Y(proj, angle_y);

hal_gfx_mat4x4_rotate_Z(proj, angle_z);

hal_gfx_mat4x4_translate(proj, 0, 0, 2.f-box_size_2);

4. P 变换和NDC 归一化处理

  • 由于只存在单视觉, 就没有独立的View 变换 (或者可以将第3步视作 V 变换). 然后计算 M' = P * M, 得到 P变换结果, 但透视变换还没有完成, 需要在hal_gfx_mat4x4_obj_to_win_coords 中进一步NDC归一化处理
  • 每个顶点坐标逐次调用接口hal_gfx_mat4x4_obj_to_win_coords, 进行: 空间剪切处理(裁切空间); NDC 归一化处理; 计算视口屏幕空间坐标

hal_gfx_mat4x4_mul(mvp, mvp, proj);

int i;

void * pic = s_canvas_buf;

for (i = 0; i < 24; i+=3) {

float w = 1.f;

hal_gfx_mat4x4_obj_to_win_coords(mvp, 0.f, 0.f, 454, 454,

  1.f, 100.f,

  &v[i  ], &v[i+1], &v[i+2], &w);

}

5. 最后的Fragment 处理 - 纹理贴图

  • 设置混合模式
  • 配置透视剔除模式
  • 进行纹理贴图, 完成从 剪切空间到屏幕空间的处理

//blend color with background

hal_gfx_set_blend_fill(HAL_GFX_BL_SIMPLE );

//remove this to draw back sides also

hal_gfx_tri_cull(HAL_GFX_CULL_NONE);                //配置透视剔除模式

//进行 纹理贴图处理, 从 剪切空间到屏幕空间

_draw_cube_side(v, 0, 1, 2, 3, 0xA08b008b); //front

_draw_cube_side(v, 4, 0, 3, 7, 0xA0228b22); //left

_draw_cube_side(v, 1, 5, 6, 2, 0xA0ff4500); //right

_draw_cube_side(v, 4, 5, 1, 0, 0xA0003366); //top

_draw_cube_side(v, 3, 2, 6, 7, 0xA066cc99); //bottom

_draw_cube_side(v, 5, 4, 7, 6, 0x60808080); //back

通过分析旋转立方体的渲染和变换逻辑, 厘清了GPU涉及的矩阵变换和流水线处理, 接下来通过这套逻辑, 设计一个垂直面翻转效果.

二、基于GR5526 GPU设计垂直面翻转动画效果

1. 定义动画效果的NDC 坐标示意图

  • 动画可以围绕Y轴进行顺时针或逆时针方向的翻转
  • 动画只有正反两个面, 不是立方体形式
  • 动画正反面可以进行纹理贴图

/*************************************************

     *    Coordinate Axis

     *

     *            7 (Z)

     *           *

     *          *

     *         *

     *        *

     *       *

     *      **************************> (X)

     *      *

     *      *

     *      *

     *      *

     *      *

     *      *

     *      *

     *      * (Y)

     *      V

     *

     *************************************************

     *

     *  围绕Y轴的翻转动画

     *

     **** 围绕Y轴的顺时针翻转动画示意图

     *

     *    0_____1           0  /| 1            1_____0

     *    |        |             /  |               |         |

     *    |        |  ------> |  |    ------>  |         |

     *    |_____|             |  |               |_____|

     *    3     2               3\ |              2        3

     *                               \| 2

     *

     *

     ****围绕Y轴的逆时针翻转动画示意图

     *

     *    0_____1         0|\                 1_____0

     *    |        |           | \ 1             |        |

     *    |        | ------> |  |   ------>  |        |

     *    |_____|            |  |              |_____|

     *    3     2               | / 2             2       3

     *                          3|/

     *

     *

     *************************************************

     */

2. 定义动画面NDC 坐标

  • 由于动画是面翻转而非立体翻转, 因此只需定义一个面(存在正面和反面).

float v[12] = {-box_size_2, -box_size_2, 0,   //0

                 box_size_2, -box_size_2, 0,   //1

                   box_size_2,  box_size_2, 0,   //2

                -box_size_2,  box_size_2, 0,   //3

              };

3. 根据step定义旋转规则

float angle = step*180.f;

if(is_clockwise) { //

if(angle <= 90.0) {

angle = angle;

} else {

angle = 180 + angle;

}

} else {

if(angle <= 90.0) {

angle = 180 - angle;

} else {

angle = 360 - angle;

}

}

4. 构建透视投影矩阵并进行MVP 矩阵变换

hal_gfx_matrix4x4_t mvp;

hal_gfx_mat4x4_load_perspective(mvp, FoV, 1.f, 1.f, 100.f);

mvp[0][0] = mvp[1][1] = 2.f;

hal_gfx_matrix4x4_t proj;

hal_gfx_mat4x4_load_identity(proj);

hal_gfx_mat4x4_rotate_Y(proj, angle);

hal_gfx_mat4x4_translate(proj, 0.f, 0.f, 1.0f);                // 向Z轴平移一个单位, 让界面产生一个视觉上的相对距离.

hal_gfx_mat4x4_mul(mvp, mvp, proj);

float w = 1.f;

for (int i = 0; i <= 9; i+=3) {

(void)hal_gfx_mat4x4_obj_to_win_coords(mvp, 0.f, 0.f, width, height,  1.f, 100.f,  &v[i  ], &v[i+1], &v[i+2], &w);

}

5. 最后, 根据是顺时针旋转还是逆时针旋转, 完成纹理贴图渲染即可.

  1. 要点
    1. 使用step 值来区分 第一、二个界面的分界
    2. 旋转方向, 有 angle 的范围与变化趋势觉得
    3. 注意 View 变化时候,需要将 画面向Z 轴移动一段距离. 产生一个视觉深度, 看起来舒服.
    4. v[0] / v[3] 的位置关系,也表明了旋转方向

三、效果及终章

下面来看看GR5526 GPU开发的新动画效果 - 基于Y轴的垂直翻转动画

这个效果是 Demo 性质的效果, 最终在产品效果呈现 更惊艳些。

经过这段时间对GR5526 GPU的学习, 及这几篇技术博客的梳理, 基本把 GR5526 GPU 的用法弄熟悉了,可以看出来, GR5526 GPU表现出的图形化能力和实现的3D动画效果是很不错的, 接下来等有时间把之前挖的几个坑给填一下.

另外抽时间再研究下GR5526 GPU版本 Lvgl 相对原生Lvgl 的优化情况, 因为实际产品中用GR5526 Lvgl 版本表现出来的帧率还是很不错的. 又挖个大坑 : )

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值