HarmonyOS 自适应 VRS OpenGL ES 版
2026/6/8 11:45:57 网站建设 项目流程

HarmonyOS 自适应 VRS OpenGL ES 版:降低 GPU 负载的另一种选择

什么是自适应 VRS

上一篇我们介绍了用 Vulkan 实现自适应 VRS,这篇来看看用 OpenGL ES 怎么做。功能是一样的:自动分析画面,对不同区域使用不同的渲染精度,从而降低 GPU 负载。

简单回顾一下 VRS 的原理:人眼对画面中心的细节更敏感,对边缘区域不太在意。VRS 就是利用这个特点,重要的地方精细渲染,不重要的地方粗糙渲染,既保证视觉效果又提高性能。

环境搭建

硬件要求

  • 设备类型:请参考 XEngine 开发指南的硬件要求

软件要求

  • DevEco Studio 版本:DevEco Studio 6.0.0 Release 及以上
  • HarmonyOS SDK 版本:HarmonyOS 6.0.0 Release SDK 及以上

搭建步骤

  1. 安装 DevEco Studio:去华为开发者官网下载安装
  2. 配置开发环境:确保网络环境正常
  3. 设备调试:使用真机进行调试

项目结构

├── entry/src/main // 代码区 │ ├── cpp │ │ ├── types │ │ │ ├── libnativerender │ │ │ └── index.d.ts // native层接口注册文件 │ │ │── napi_init.cpp // native api层接口的具体实现函数 │ │ │── CMakeLists.txt // native层编译配置 │ │ │── 3rdParty // 三方件 │ │ │── common // 通用接口 │ │ │── model // 模型 │ │ │── file // 文件管理 │ │ │── libs // 三方动态库 │ │ │── manager // native&arkts交互 │ │ │── render // 渲染 │ │ │── shader // 渲染shader │ ├── ets │ │ ├── entryability │ │ │ └── EntryAbility.ts // 程序入口类 │ │ ├── pages │ │ │ └── index.ets // 主界面展示类 │ ├── resources // 资源文件目录 │ │ ├── base │ │ │ ├── media │ │ │ └── icon.png // 图片资源 │ │ ├── rawfile/model/Sponza │ │ │ └── sponza.obj // 模型资源

第一步:引入头文件

#include<cstring>#include<cstdlib>#include<xengine/xeg_gles_extension.h>#include<xengine/xeg_gles_adaptive_vrs.h>

这些头文件的作用:

  • cstringcstdlib:C++ 标准库
  • xeg_gles_extension.h:XEngine 的 OpenGL ES 扩展接口
  • xeg_gles_adaptive_vrs.h:自适应 VRS 的核心接口

第二步:配置 CMakeLists.txt

find_library( xengine-lib xengine ) find_library( EGL-lib EGL ) find_library( GLES-lib GLESv3 ) target_link_libraries(nativerender PUBLIC ${EGL-lib} ${GLES-lib} ${xengine-lib})

链接了xengineEGLGLESv3三个库。

第三步:查询设备是否支持

constchar*extensions=(constchar*)HMS_XEG_GetString(XEG_EXTENSIONS);if(!strstr(extensions,XEG_ADAPTIVE_VRS_EXTENSION_NAME)){exit(1);// return error}

和 Vulkan 版本一样,先检查设备是否支持自适应 VRS。OpenGL ES 的查询方式更简单,直接调用HMS_XEG_GetString获取扩展列表字符串,然后用strstr查找。

第四步:设置 VRS 参数

这是自适应 VRS 的配置步骤,需要设置多个参数:

设置输入尺寸

uint32_trenderWidth=800;uint32_trenderHeight=600;GLsizei inputSize[2]={static_cast<GLsizei>(renderWidth),static_cast<GLsizei>(renderHeight)};HMS_XEG_AdaptiveVRSParameter(XEG_ADAPTIVE_VRS_INPUT_SIZE,inputSize);

设置输入图像的尺寸,就是上一帧渲染结果的大小。inputSize是一个包含宽高的数组。

设置输入区域

GLuint inputRegion[4]={0,0,renderWidth,renderHeight};HMS_XEG_AdaptiveVRSParameter(XEG_ADAPTIVE_VRS_INPUT_REGION,inputRegion);

设置输入图像的采样区域。inputRegion是一个包含 4 个元素的数组:起始坐标 (x, y) 和宽高。从 (0, 0) 开始,大小等于渲染分辨率,表示处理整个图像。

设置分片大小

GLsizei texelSizes[2]={8,8};HMS_XEG_AdaptiveVRSParameter(XEG_ADAPTIVE_VRS_TEXEL_SIZE,texelSizes);

设置 VRS 的分片大小。画面会被分成很多小块,每块独立决定渲染精度。当前支持两种规格:

  • [8, 8]:8x8 像素一块,精度高但计算量大
  • [16, 16]:16x16 像素一块,精度低但性能好

设置误差敏感度

GLfloat sensitivity=0.15;HMS_XEG_AdaptiveVRSParameter(XEG_ADAPTIVE_VRS_ERROR_SENSITIVITY,&sensitivity);

设置误差敏感度阈值,取值范围 [0, 1]。值越小,越倾向于高精度渲染;值越大,越倾向于低精度渲染。0.15 是一个比较保守的值,画质影响很小。

设置翻转选项

GLboolean flip=false;HMS_XEG_AdaptiveVRSParameter(XEG_ADAPTIVE_VRS_FLIP,&flip);

设置是否翻转图像。false表示不翻转。

第五步:生成着色率纹理

GLuint inputColorImage;GLuint inputDepthImage;GLuint outputShadingRateImage;float*reprojectionMatrix=nullptr;HMS_XEG_DispatchAdaptiveVRS(reprojectionMatrix,inputColorImage,inputDepthImage,outputShadingRateImage);

调用HMS_XEG_DispatchAdaptiveVRS生成着色率纹理。参数说明:

  • reprojectionMatrix:重投影矩阵,用于处理相机运动。如果相机不动,传nullptr
  • inputColorImage:上一帧的颜色纹理,就是渲染出来的彩色画面
  • inputDepthImage:深度纹理,记录每个像素离相机有多远
  • outputShadingRateImage:输出的着色率纹理,GPU 会根据它决定每个区域的渲染精度

第六步:应用着色率纹理

HMS_XEG_ApplyAdaptiveVRS(outputShadingRateImage);

最后调用HMS_XEG_ApplyAdaptiveVRS把着色率纹理应用到渲染目标中。之后 GPU 在渲染下一帧时,就会根据这个纹理来决定每个区域的渲染精度。

自适应 VRS 的整体工作流程如下:

查询设备是否支持自适应VRS

设置输入尺寸

设置输入区域

设置分片大小

设置误差敏感度

设置翻转选项

调用 DispatchAdaptiveVRS

分析颜色和深度信息

生成着色率纹理

调用 ApplyAdaptiveVRS

GPU 根据着色率渲染下一帧

VRS 参数配置的决策流程:

精度优先

性能优先

画质优先

性能优先

开始配置VRS参数

选择分片大小

8x8 像素分片

16x16 像素分片

设置误差敏感度

较小值 如 0.15

较大值 如 0.5

相机是否移动?

传入重投影矩阵

传入 nullptr

参数配置完成

OpenGL ES 版和 Vulkan 版的区别

对比一下两个版本:

方面OpenGL ES 版Vulkan 版
查询扩展HMS_XEG_GetStringHMS_XEG_EnumerateDeviceExtensionProperties
设置参数HMS_XEG_AdaptiveVRSParameter通过创建结构体
生成着色率HMS_XEG_DispatchAdaptiveVRSHMS_XEG_CmdDispatchAdaptiveVRS
应用着色率HMS_XEG_ApplyAdaptiveVRS自动应用
销毁实例无需显式销毁HMS_XEG_DestroyAdaptiveVRS

主要区别:

  1. API 风格:OpenGL ES 版用函数参数设置,Vulkan 版用结构体设置
  2. 资源管理:OpenGL ES 版不需要显式销毁实例,Vulkan 版需要
  3. 命令提交:Vulkan 版需要通过命令缓冲区提交,OpenGL ES 版直接调用

选择哪个版本取决于你的应用已经在用哪个图形 API。

适用场景

自适应 VRS 特别适合以下场景:

  • 3D 游戏:画面复杂,有很多区域可以降低精度
  • VR/AR 应用:对帧率要求极高
  • 图形渲染应用:需要稳定帧率的场景

注意事项

  1. 设备支持:不是所有设备都支持自适应 VRS,一定要先查询扩展
  2. 分片大小:8x8 精度高但性能开销大,16x16 性能好但精度低,要根据实际需求选择
  3. 误差敏感度sensitivity要根据画面质量要求来调整
  4. 重投影矩阵:如果相机在移动,需要传入正确的重投影矩阵

总结

OpenGL ES 版本的自适应 VRS 和 Vulkan 版本功能相同,核心流程:

  1. 查询设备是否支持
  2. 设置参数(输入尺寸、分片大小、误差敏感度等)
  3. 调用HMS_XEG_DispatchAdaptiveVRS生成着色率纹理
  4. 调用HMS_XEG_ApplyAdaptiveVRS应用着色率纹理

如果你的应用已经在用 OpenGL ES,用这个版本会更方便。如果用的是 Vulkan,就用 Vulkan 版本。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询