8000 [RFC] 支持 sRGB · Issue #2563 · galacean/engine · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

[RFC] 支持 sRGB #2563

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

Closed
zhuxudong opened this issue Feb 18, 2025 · 3 comments · Fixed by #2593
Closed

[RFC] 支持 sRGB #2563

zhuxudong opened this issue Feb 18, 2025 · 3 comments · Fixed by #2593
Assignees
Labels
enhancement New feature or request rendering Rendering related functions RFC
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 那一坨代码了。(待定,可能仍需要考虑 webgl 1.0)

关键问题和解决方案

1. 哪些纹理需要 sRGB 格式

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

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

2. Loader 新增 sRGB

  • Texture2DLoader 新增 params.isSRGBColorSpace,默认 false
  • TextureCubeLoader 新增 params.isSRGBColorSpace,默认 false
  • 编辑器 Texture Encoder/Decoder 新增 isSRGBColorSpace 为 nextUint8
  • SpriteAtlasLoader 强制 sRGB。

3. 开关设计

  • 引擎 Runtime 测 ,纹理构造体入参新增 sRGB 开关。
  • 编辑器测,纹理新增 sRGB 开关
  • sRGB 格式只对 R8G8B8R8G8B8A8 格式生效,当纹理格式为 R16G16B16A16Alpha8 等非 sRGB 格式时,和调研结果一致,都以纹理格式为准,忽略 sRGB 开关。

4. 兼容性问题

  • sRGB 在 WebGL2.0 中默认支持,在 WebGL1.0 中可以通过 EXT_sRGB 插件支持。在生成纹理时,ext.SRGB_EXT对标 gl2.SRGB8ext.SRGB_ALPHA_EXT对标gl2.SRGB8_ALPHA8;在生成 MSAA 时,使用gl2.SRGB8_ALPHA8

  • 当存在 webgl1.0 插件都不支持的机型 时,是否还需要兼容这块逻辑写 toLinear 的shader 代码?

    Babylon Three
    采样纹理的 shader 代码中有 GAMMAALBEDO 等宏开关,配合 texture.gammaSpace来决定是否需要 toLinear;当开启 sRGB 后,会关闭 GAMMAALBEDO 等宏开关,不考虑 sRGB 都不支持的设备 在 r163 版本之前, 通过 CPU 处理 的方式兼容这块逻辑 , 从r163 开始不再支持 webgl 1.0 ,并删除了 CPU 处理的逻辑

由于 webgl1.0 可能仍无法舍弃, 在 shader 代码里面写一大坨 #if 又非常恶心,建议增加 CPU 处理的方法,当识别到不支持 sRGB 时再走这块逻辑,虽然开销很大,但是踩中几率非常小只有不到1%,且以后方便删除。

5. Mipmap 支持问题

只有 WebGL2.0 的 SRGB8_ALPHA8格式才支持自动生成 Mipmap,否则会报错,这个是 WebGL 底层的缺陷,无法绕过去。

Babylon Three Unity
不提示,不阻止 提示用户sRGB要使用 RGBA 格式,但是不阻止 手动生成 mipmap 数据

我们可以判断当前纹理 sRGB 组合是否支持 mipmap,如果不支持的话,关闭 mipmap 开关;在未来,我们还可以在编辑器支持手动生成 mipmap 的能力。

6. 压缩纹理

  • Encoder 测支持 sRGB。
  • Decoder 测支持解析,etc 和 s3tc 参考官方说明,综合如下:
压缩格式 + sRGB 插件 原 TextureFormat sRGB 新增
astc ASTC_4x4 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
etc ETC2_RGBA8 SRGB8_ALPHA8_ETC2_EAC
ETC2_RGB SRGB8_ETC2
bptc BC7 COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT
s3tc +
WEBGL_compressed_texture_s3tc_srgb
BC3 COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
BC1 COMPRESSED_SRGB_S3TC_DXT1_EXT
pvrtc PVRTC_RGBA4 不支持 sRGB,直接降级
PVRTC_RGB4
降级 downgrade R8G8B8A8 SRGB8_ALPHA8

附录

  • mipmap 报错:
    Image
    Image

  • three 检查格式:
    Image
    Image

  • 其他格式忽略 sRGB:
    Image
    Image
    Image

  • Babylon gammaSpace 和 sRGB 配合

Image
Image
Image

  • three 不再支持 WebGL1 且删除 CPU 处理方案

Image

@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
@GuoLei1990 GuoLei1990 added the RFC label Mar 13, 2025
@GuoLei1990
Copy link
Member
  • gl2.SRGB8_ALPHA8 对应 srgb8_alpha8_ext 的扩展版是否也可以自动生成 mipmp
  • 按照调研 Babylon 应该是彻底做了兜底逻辑且只考虑 Albeo 纹理,Three.js 完全不考虑
  • 对于编辑器后续的自动检测需要考虑下,否则体验不好

@zhuxudong
Copy link
Member Author

是的,编辑器需要重点考虑一下体验提升,现在 sRGB会影响到 Sprite、UI、Spine、Lottie 8000 、Material 等所有用到纹理的元素,影响有点大

@zhuxudong
Copy link
Member Author

是的,编辑器需要重点考虑一下体验提升,现在 sRGB会影响到 Sprite、UI、Spine、Lottie、Material 等所有用到纹理的元素,影响有点大

解决方案是否可以默认开启 sRGB。
我看 Unity 拖拽进去的图片,都默认开启 sRGB,的确满足了大部分场景,只有法线、粗糙金属等纹理才需要手动关闭 sRGB 开关,并且 Unity 的法线部分还有个提示:
Image

@zhuxudong zhuxudong linked a pull request Mar 20, 2025 that will close this issue
3 tasks
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 RFC
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants
0