Approximate PBR in old OpenGL 1

Viewed 86

As mentioned in my previous question, I am trying to import/export glTF models in R. The R 3d graphics engine that I'm using (rgl) is really old, and the rendering within R is done using OpenGL 1.x methods: material colors like GL_DIFFUSE, GL_AMBIENT, GL_SPECULAR and GL_EMISSION colors, as well as GL_SHININESS. It also uses WebGL 1 in web output.

I need to translate existing code using these parameters into PBR parameters for output to glTF, and translate glTF PBR parameters into the older model when reading.

Currently I have the following:

  • baseColorFactor in material.pbrMetallicRoughness and textures corresponds to the diffuse color.
  • emissiveFactor corresponds to the emission color.

However, I have no idea how to approximate the other material components in the old style.

I'm hoping this has been done before; can anyone provide formulas for the conversions, or a pointer to a source so I can work them out myself?

1 Answers

Unfortunately, there is no direct conversion between PBR and legacy OpenGL material models.

Maybe the following pseudo-formula might help as a starting point:

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;
}

As an extra note, PBR normally (like in glTF) uses linear RGB color values, while legacy OpenGL usually performed rendering without conversion into non-linear sRGB color space used by most of displays. If referred WebGL 1.0 renderer doesn't perform gamma correction, than it could be cheated on conversion into Diffuse/Ambient/Specular/Emission vectors to have more corellated visual results (but still inconsistent a lot)...

Related