旧 OpenGL 1 中的近似 PBR
Approximate PBR in old OpenGL 1
正如我在 , I am trying to import/export glTF models in R. The R 3d graphics engine that I'm using (rgl) 中提到的那样,它确实很旧,R 中的渲染是使用 OpenGL 1.x 方法完成的:material 颜色,如 GL_DIFFUSE
、GL_AMBIENT
、GL_SPECULAR
和 GL_EMISSION
颜色,以及 GL_SHININESS
。它还在 Web 输出中使用 WebGL 1。
我需要将使用这些参数的现有代码转换为 PBR 参数以输出到 glTF,并在阅读时将 glTF PBR 参数转换为旧模型。
目前我有:
baseColorFactor
in material.pbrMetallicRoughness
和纹理对应漫反射颜色。
emissiveFactor
对应发光颜色
但是,我不知道如何近似旧样式中的其他 material
组件。
我希望以前有人这样做过;任何人都可以提供转换公式或指向源的指针以便我自己计算吗?
遗憾的是,PBR 和遗留 OpenGL material 模型之间没有直接转换。
也许以下伪公式可以作为起点:
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 颜色 space。如果引用的 WebGL 1.0 渲染器不执行伽玛校正,那么它可能会在转换为 Diffuse/Ambient/Specular/Emission 向量时被欺骗以获得更多相关的视觉结果(但仍然不一致)...
正如我在 GL_DIFFUSE
、GL_AMBIENT
、GL_SPECULAR
和 GL_EMISSION
颜色,以及 GL_SHININESS
。它还在 Web 输出中使用 WebGL 1。
我需要将使用这些参数的现有代码转换为 PBR 参数以输出到 glTF,并在阅读时将 glTF PBR 参数转换为旧模型。
目前我有:
baseColorFactor
inmaterial.pbrMetallicRoughness
和纹理对应漫反射颜色。emissiveFactor
对应发光颜色
但是,我不知道如何近似旧样式中的其他 material
组件。
我希望以前有人这样做过;任何人都可以提供转换公式或指向源的指针以便我自己计算吗?
遗憾的是,PBR 和遗留 OpenGL material 模型之间没有直接转换。
也许以下伪公式可以作为起点:
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 颜色 space。如果引用的 WebGL 1.0 渲染器不执行伽玛校正,那么它可能会在转换为 Diffuse/Ambient/Specular/Emission 向量时被欺骗以获得更多相关的视觉结果(但仍然不一致)...