HarmonyOS GPU 超分:用 OpenGL ES 把低分辨率图像变清晰

什么是 GPU 超分

你有没有遇到过这种情况:一张小图片放大后变得模糊不清,全是马赛克?这是因为原始图片的分辨率不够,放大后像素点被拉伸,自然就模糊了。

GPU 超分(Super Resolution)就是用来解决这个问题的。它利用 GPU 的计算能力,通过算法把低分辨率图像"重建"成高分辨率图像。不是简单地拉伸像素,而是智能地补充细节,让放大后的图像看起来更清晰。

打个比方,就像一个画家看到一张模糊的小照片,然后凭经验和技巧画出一张清晰的大画。GPU 超分就是这个"画家",只不过它是用算法来"画"的。

环境搭建

硬件要求

  • 设备类型:请参考 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    // 模型资源

这个项目使用 OpenGL ES 图形 API,代码主要在 C++ 层。

第一步:引入头文件

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

这些头文件的作用:

  • cstringcstdlib:C++ 标准库,处理字符串、内存等
  • xeg_gles_extension.h:XEngine 的 OpenGL ES 扩展接口
  • xeg_gles_spatial_upscale.h:空域 GPU 超分的核心接口

第二步:配置 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})

链接了三个库:

  • xengine:XEngine 核心库,超分功能在这个库里
  • EGL:OpenGL ES 的窗口系统接口
  • GLESv3:OpenGL ES 3.0 版本的库

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

在使用超分功能之前,先检查设备是否支持:

const char* extensions = (const char*)HMS_XEG_GetString(XEG_EXTENSIONS);
if (!strstr(extensions, XEG_SPATIAL_UPSCALE_EXTENSION_NAME)) {
    exit(1); // return error
}

这段代码做了两件事:

  1. 获取扩展列表HMS_XEG_GetString(XEG_EXTENSIONS) 返回设备支持的所有扩展名称,是一个字符串
  2. 查找超分扩展:用 strstr 在扩展列表里查找空域超分的扩展名。如果找不到,说明设备不支持,退出程序

这是使用任何图形扩展前的标准操作:先确认设备支持,再使用。

第四步:设置超分参数

float m_sharpness = 0.3f;
uint32_t m_renderWidth = 800;
uint32_t m_renderHeight = 600;

定义一些参数:

  • m_sharpness:锐化参数,0.3 是一个平衡值。值越大,图像越锐利,但可能会有伪影;值越小,图像越平滑
  • m_renderWidthm_renderHeight:原始渲染分辨率,800x600
HMS_XEG_SpatialUpscaleParameter(XEG_SPATIAL_UPSCALE_SHARPNESS, &m_sharpness);

设置锐化参数。XEG_SPATIAL_UPSCALE_SHARPNESS 表示要设置的是锐化参数。

int upscaleScissor[4] = {0, 0, static_cast<int>(m_renderWidth), static_cast<int>(m_renderHeight)}; 
HMS_XEG_SpatialUpscaleParameter(XEG_SPATIAL_UPSCALE_SCISSOR, upscaleScissor);

设置超分的采样区域。upscaleScissor 是一个包含 4 个元素的数组:

  • 前两个是起始坐标 (x, y),从 (0, 0) 开始
  • 后两个是宽高,等于原始渲染分辨率

这意味着超分会处理整个原始图像。

第五步:执行超分

unsigned int upscaleFBO;
glBindFramebuffer(GL_FRAMEBUFFER, upscaleFBO); 

先绑定一个 framebuffer。framebuffer 就像一块画布,超分的结果会画到这块画布上。

uint32_t m_upscaleWidth = 1200;
uint32_t m_upscaleHeight = 900;
glViewport(0, 0, m_upscaleWidth, m_upscaleHeight);
glScissor(0, 0, m_upscaleWidth, m_upscaleHeight); 

设置超分后的目标分辨率:从 800x600 超分到 1200x900。glViewport 设置视口大小,glScissor 设置裁剪区域。

unsigned int upscaleColorBuffer;
HMS_XEG_RenderSpatialUpscale(upscaleColorBuffer);

最后调用 HMS_XEG_RenderSpatialUpscale 执行超分。upscaleColorBuffer 是原始图像的纹理附件,超分算法会读取这个纹理,然后把结果写入之前绑定的 framebuffer。

超分的工作原理

让我用更通俗的语言解释超分是怎么工作的:

  1. 分析原始图像:超分算法会分析低分辨率图像的像素分布
  2. 识别特征:找出图像中的边缘、纹理、细节等特征
  3. 智能放大:根据识别出的特征,在放大时补充细节
  4. 锐化处理:根据锐化参数,对图像进行适度的锐化

这个过程是在 GPU 上并行执行的,所以速度很快。

超分算法的内部处理流程:

读取低分辨率原始图像

分析像素分布

识别边缘特征

识别纹理特征

识别细节特征

智能插值放大

根据锐化参数进行锐化

输出高分辨率图像

GPU 超分的整体工作流程如下:

查询设备是否支持超分

设置锐化参数

设置采样区域

绑定输出 Framebuffer

设置目标视口大小

调用 RenderSpatialUpscale

GPU 分析原始图像特征

智能补充放大后的细节

输出高分辨率图像

适用场景

GPU 超分特别适合以下场景:

  • 游戏渲染:先用低分辨率渲染(性能好),再超分到高分辨率(画质好)
  • 视频播放:把低分辨率视频超分到高分辨率显示
  • 图片查看:放大图片时保持清晰度

注意事项

  1. 设备支持:不是所有设备都支持 GPU 超分,一定要先查询扩展
  2. 锐化参数m_sharpness 要根据实际效果来调整。太大会有伪影,太小效果不明显
  3. 分辨率比例:超分的倍率不宜过大,一般 1.5 到 2 倍比较合适。倍率太大,效果会变差
  4. 性能开销:超分本身有性能开销,要权衡超分带来的画质提升和性能损失

总结

GPU 超分是一个很实用的图形优化技术,它能在低分辨率渲染的基础上,获得接近高分辨率的画质。核心流程:

  1. 查询设备是否支持超分
  2. 设置超分参数(锐化度、采样区域)
  3. 绑定输出 framebuffer
  4. 调用 HMS_XEG_RenderSpatialUpscale 执行超分

掌握了这些,你就能在 HarmonyOS 应用中实现 GPU 趍分,让你的应用在性能和画质之间找到最佳平衡。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐