slightknack/keikan

Update Rendering Code to be PBR Compliant.

Tloru opened this issue · 1 comments

Tloru commented

In the rendering code, this rather ugly line of code determines the color of the ray:

// combine the samples in a PBR manner
return (
    (
        ( // for dielectric materials. TODO: fresnel blending
            (
                (transmission *        material.transmission)  // mix transparent
              + (diffuse      * (1.0 - material.transmission)) // and diffuse
            )
          + (specular * material.specular) // with a specular layer on top
          // TODO: specular seems off, violating cons. of energy. review.
        )
      * (1.0 - material.metallic) // lerp with metal

      + ( // for metallic materials
            specular * material.color
        )
      * material.metallic
    )
  * (1.0 - material.emission).max(0.0) // modified lerp with emissive

  + ( // for emissive materials
      material.color * material.emission
    )
);

I'll simplify it a bit:

// combine the samples in a PBR manner
// mix transparent and diffuse
let base = (transmission * material.transmission) + (diffuse * (1.0 - material.transmission));

// TODO: specular seems off, violating cons. of energy. review.
let dielectric = base + (specular * material.specular); // with a specular layer on top
let electric = specular * material.color; // for metallic materials

// lerp electric and dielectric
let non_emmisive = (electric * material.metallic) + (dielectric * (1.0 - material.metallic));
let combined = (material.color * material.emission) + (non_emmisive * (1.0 - material.emmision).max(0.0));

// final color.
return combined;

This color combination technique is naive, at best. This should be fixed to work in a PBR compliant manner. Any help is appreciated.

I refactored that beast and added fresnel, as well as corrected the behavior of emmisive materials. As per #10, the rendering pipeline is PBR-compliant. I still need to implement transmissive materials - I'm a bit hesitant because this requires that distance fields be defined for the inside of objects as well, which is not always the case for ray-marched objects.