Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] 支持 sRGB #2563

Open
zhuxudong opened this issue Feb 18, 2025 · 0 comments
Open

[RFC] 支持 sRGB #2563

zhuxudong opened this issue Feb 18, 2025 · 0 comments
Assignees
Labels
enhancement New feature or request Rendering Rendering related functions
Milestone

Comments

@zhuxudong
Copy link
Member

zhuxudong commented Feb 18, 2025

背景和价值

#1227 描述, 现在引擎 shader 中采样的纹理有很多 gammaToLinear 的操作,如果支持硬件级别的 sRGB 纹理格式,有以下优点

  • 性能优化。利用 GPU 硬件特性,自动执行规范的 sRGB → Linear 转换,并减少了 Shader 中 pow 等计算指令次数。
  • 精准的色彩表现。符合 IEC 61966-2-1 标准,比 pow(2.2)更准确,保证美术资源色彩一致性。
  • 易用性。用户不用写 gammaToLinear 那一坨代码了 (${{\color{red}待定,是否需要向下兼容以及不支持 sRGB 的机型?}}$)。

关键问题和解决方案

1. 兼容性问题

  • sRGB 在 WebGL2.0 中默认支持,在 WebGL1.0 中可以通过 EXT_sRGB 插件支持。
  • 生成纹理时,ext.SRGB_EXT对标 gl.SRGB8ext.SRGB_ALPHA_EXT对标gl.SRGB8_ALPHA8
    • 这里的ext.SRGB_ALPHA_EXText.SRGB8_ALPHA8_EXT不是同一个东西,不能同时对标 WebGL2.0 的 gl.SRGB8_ALPHA8,也是目前引擎唯一无法抹平的变量,所以不在 GLCapability文件中抹平,可以在运行时通过 getExtension 获取插件的真实值( WebGL1.0 才需要这么搞 )。
    • ext 插件支持的格式都是 Unsized format,所以 WebGL1.0 的 sRGB 不支持生成 mipmap,详情如下第 2 个 mipmap 问题。
  • 生成 RBO 时,ext.SRGB8_ALPHA8_EXT 对标 gl.SRGB8_ALPHA8,不过目前引擎没有单独使用颜色 RBO 的功能,这里暂时不做特殊处理。
  • 特殊 case:需不需要兼容连 webgl1.0 插件都不支持的机型。如果需要支持的话,shader 还是要根据 ENABLE_SRGB 宏开关去进行 gammaToLinear 的操作。

2. Mipmap 支持问题

只有 WebGL2.0 的 SRGB8_ALPHA8格式才支持 Mipmap,否则会报以下错误:

Image

Image

这个是 WebGL 底层的缺陷,无法绕过去,是因为 WebGL 规范不允许 unsized format 生成 mipmap,因此我们需要判断当前环境 sRGB 是否支持 mipmap,如果不支持的话,引擎做以下处理:

  • 强制禁止generateMipmap
  • 强制采样方式TEXTURE_MIN_FILTERgl.NEAREST 或者 gl.LINEAR
  • WebGL2.0 有强制只采样 0 级的接口:gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 0);

3. 开关设计

  • 对引擎 Runtime 来说 ,sRGB 是一系列纹理格式,即引擎的 TextureFormat新增 SRGBSRGBA、各个压缩纹理格式。
  • 在编辑器测,纹理新增 sRGB 开关 ,根据原纹理格式转换成相应的 sRGB 格式:
    • R8G8B8A8 ->SRGBA
    • R8G8B8 -> SRGB
    • 压缩纹理 -> sRGB 对应的压缩纹理,详见第 5 个压缩纹理表格

4. 哪些纹理需要 sRGB 格式

一般跟视觉相关的纹理都需要 sRGB 格式,用户可以选中纹理,自己切换为 sRGB 格式,以下引擎内置的纹理也需要改为 sRGB:

  • PBR 的基础纹理、高光纹理、自发射纹理。
  • Blinn-Phong 的漫反射纹理、自发射纹理、高光纹理。
  • Unlit 的基础纹理。
  • 粒子系统的基础纹理。
  • 管线的 camera_OpaqueTexture
  • 后处理系统的纹理。
  • Skybox 非 RGBM 模式时的天空纹理。

5. 压缩纹理

  • Encoder 测支持 sRGB。
  • Decoder 测支持解析,etc 和 s3tc 参考官方说明,综合如下:
压缩格式 + sRGB 插件 原 TextureFormat sRGB 新增
astc ASTC_4x4 SRGBA_ASTC_4X4
etc ETC2_RGBA8 ${{\color{red} ETC2\_SRGBA }}$
ETC2_RGB ETC2_SRGB
bptc BC7 BC7_SRGBA
s3tc +
WEBGL_compressed_texture_s3tc_srgb
BC3 BC3_SRGBA
BC1 BC1_SRGB
pvrtc PVRTC_RGBA4 不支持 sRGB,直接降级
PVRTC_RGB4
降级 downgrade R8G8B8A8 ${{\color{red} SRGBA}}$
@zhuxudong zhuxudong added enhancement New feature or request Rendering Rendering related functions labels Feb 18, 2025
@zhuxudong zhuxudong added this to the 1.5 milestone Feb 18, 2025
@zhuxudong zhuxudong self-assigned this Feb 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Rendering Rendering related functions
Projects
None yet
Development

No branches or pull requests

1 participant