Work Log by Kevin Beason

Latest personal graphics developments

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

No comments yet. Be the first.

Leave a reply