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?
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)...