Work Log by Kevin Beason

Latest personal graphics developments

Archive for March, 2009

Glossy reflections

Added Ashikhmin & Shirley’s Anisotropic Phong BRDF and Schlick’s BRDF (the ’94 paper) support for pure path tracing (implicit light paths only). My Schlick BRDF is probably broken. Adding these entailed abstracting a BRDF interface class, implementing importance sampling and computing BRDF/PDF. The daylight image is after sunset for a good reason. The sun would only contribute if a ray found it by chance… talk about noise.

Front row is Ashikhmin & Shirley Anisotropic Phong BRDF. 2nd row is Schlick’s anisotropic BRDF. Third row is my preexisting set of materials. Back row is A&S BRDF with measured reflectance values (in RGB. See previous post.) The floor is A&S BRDF and my fascimile of their texture.

Left image is Preetham daylight model. Right is Debevec’s Uffizi HDR environment probe.

2048 spp, 24-30 minutes each on a Q6600 2.4GHz Core 2 Quad.

This work is from May 2008.

No comments

Measured reflectance

image395

Chromium, Copper, Iron, Lithium, Nickel, Silicon, Tungsten

Inspired by this beauty I set out for rendering with “measured reflectance” values.

FreeSnell comes with spectral data for a variety of materials in a series of .nk files, including the index of refraction (n), the extinction coefficient (k, aka absorbtion), and most importantly in this case, the reflectance. I converted the spectral reflectance into RGB by multiplying by a 6500 K blackbody emission spectrum, converting to XYZ, then to RGB, and normalizing by dividing by the red channel of a 6500 K spectrum converted to RGB. RGB values and code are below. The Spectrum class is in the pane source code. This is work from May 2008.

Metal R G B values
Chromium 0.637800 0.628488 0.676412
Copper 0.934587 0.606404 0.509491
Iron 0.561852 0.533074 0.557609
Lithium 0.911137 0.839446 0.767515
Nickel 0.654712 0.575060 0.499619
Silicon 0.348758 0.347516 0.415774
Tungsten 0.513084 0.468396 0.448025
void nkToRefl(const char *file){
  ifstream inFile;
  inFile.open(file);
  if (!inFile){
    cerr << "Error opening " << file << "\n";
    return;
  }
  string str;
  getline(inFile, str);
  getline(inFile, str);
  fprintf(stderr, "%8s %30s reflectance = ", file, str.substr(18).c_str());
 
  double eV, n, k, r;
  double h = 6.626068e-34;       // m^2 kg/s
  double c = 299792458;          // m/2
  double ec = 1.60217646e-19;    // C
 
  map reflsMap;
  while (!inFile.eof()){
    inFile >> eV >> n >> k >> r;
    double nrg = eV * ec;          // V = J/C => J = VC
    double wavelen = h*c/nrg;      // nrg = h*c/l  => l=h*c/nrg
    double nm = wavelen*1e9;
    reflsMap[nm] = r;
  }
  inFile.close();
 
  vector wavelens, refls;
  for (map::iterator i=reflsMap.begin(); i!=reflsMap.end(); i++){
    wavelens.push_back(i->first);
    refls.push_back(i->second);
  }
 
  Spectrum lightSpec(6500);                // start out with light
  Spectrum reflSpec(&wavelens[0], &refls[0], wavelens.size());
  lightSpec.scaleSpec(1/4.73223e+06);      // normalize by red channel
  reflSpec.scaleSpec(lightSpec);           // mult light by refl
  SbColor rgb = reflSpec.getRGB();
  fprintf(stderr, "(%5f, %5f, %5f)\n", rgb[0], rgb[1], rgb[2]);
}
No comments