首页 > 解决方案 > 旧 OpenGL 1 中的近似 PBR

问题描述

正如我在上一个问题中提到的,我正在尝试在 R 中导入/导出 glTF 模型。我使用的 R 3d 图形引擎 ( rgl ) 非常旧,并且 R 中的渲染是使用 OpenGL 1.x 方法完成的:材料颜色,如、GL_DIFFUSE和颜色,以及。它还在 Web 输出中使用 WebGL 1。GL_AMBIENTGL_SPECULARGL_EMISSIONGL_SHININESS

我需要将使用这些参数的现有代码转换为 PBR 参数以输出到 glTF,并在读取时将 glTF PBR 参数转换为旧模型。

目前我有以下内容:

但是,我不知道如何近似material旧样式中的其他组件。

我希望以前已经这样做过;谁能提供转换公式或指向源的指针,以便我自己解决?

标签: rgltfrgl

解决方案


不幸的是,PBR 和传统的 OpenGL 材质模型之间没有直接的转换。

也许以下伪公式可能有助于作为起点:

struct PbrMaterial
{
  vec4  BaseColor; //!< base color + alpha
  vec3  Emission;  //!< emission
  float Metallic;  //!< metalness factor
  float Roughness; //!< roughness factor
};

struct CommonMaterial
{
  vec4  Diffuse;   //!< diffuse RGB coefficients + alpha (GL_DIFFUSE)
  vec4  Ambient;   //!< ambient RGB coefficients (GL_AMBIENT)
  vec4  Specular;  //!< glossy  RGB coefficients (GL_SPECULAR)
  vec4  Emission;  //!< material RGB emission (GL_EMISSION)
  float Shininess; //!< shininess (GL_SHININESS in 0..128 range)
};

CommonMaterial pbrToCommon (const PbrMaterial& thePbr)
{
  CommonMaterial aCommon;
  aCommon.Diffuse   = thePbr.BaseColor;
  aCommon.Ambient   = thePbr.BaseColor * 0.25;
  aCommon.Specular  = vec4 (thePbr.Metallic, thePbr.Metallic, thePbr.Metallic, 1.0);
  aCommon.Emission  = vec4 (thePbr.Emission, 1.0);
  aCommon.Shininess = 128.0 * (1.0 - thePbr.Roughness);
  return aCommon;
}

作为额外说明,PBR 通常(如在 glTF 中)使用线性 RGB 颜色值,而传统 OpenGL 通常执行渲染而不转换为大多数显示器使用的非线性 sRGB 颜色空间。如果引用的 WebGL 1.0 渲染器不执行 gamma 校正,那么它可能会在转换为 Diffuse/Ambient/Specular/Emission 矢量时被欺骗以获得更多相关的视觉结果(但仍然不一致)......


推荐阅读