00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "pbrt.h"
00026 #include "material.h"
00027
00028 class UberMaterial : public Material {
00029 public:
00030
00031 UberMaterial(Reference<Texture<Spectrum> > kd,
00032 Reference<Texture<Spectrum> > ks,
00033 Reference<Texture<Spectrum> > kr,
00034 Reference<Texture<float> > rough,
00035 Reference<Texture<Spectrum> > op,
00036 Reference<Texture<float> > bump) {
00037 Kd = kd;
00038 Ks = ks;
00039 Kr = kr;
00040 roughness = rough;
00041 opacity = op;
00042 bumpMap = bump;
00043 }
00044 BSDF *GetBSDF(const DifferentialGeometry &dgGeom, const DifferentialGeometry &dgShading) const;
00045 private:
00046
00047 Reference<Texture<Spectrum> > Kd, Ks, Kr, opacity;
00048 Reference<Texture<float> > roughness;
00049 Reference<Texture<float> > bumpMap;
00050 };
00051
00052 BSDF *UberMaterial::GetBSDF(const DifferentialGeometry &dgGeom, const DifferentialGeometry &dgShading) const {
00053
00054 DifferentialGeometry dgs;
00055 if (bumpMap)
00056 Bump(bumpMap, dgGeom, dgShading, &dgs);
00057 else
00058 dgs = dgShading;
00059 BSDF *bsdf = BSDF_ALLOC(BSDF)(dgs, dgGeom.nn);
00060
00061 Spectrum op = opacity->Evaluate(dgs).Clamp();
00062 if (op != Spectrum(1.)) {
00063 BxDF *tr = BSDF_ALLOC(SpecularTransmission)(-op + Spectrum(1.), 1., 1.);
00064 bsdf->Add(tr);
00065 }
00066
00067 Spectrum kd = op * Kd->Evaluate(dgs).Clamp();
00068 if (!kd.Black()) {
00069 BxDF *diff = BSDF_ALLOC(Lambertian)(kd);
00070 bsdf->Add(diff);
00071 }
00072
00073 Spectrum ks = op * Ks->Evaluate(dgs).Clamp();
00074 if (!ks.Black()) {
00075 Fresnel *fresnel = BSDF_ALLOC(FresnelDielectric)(1.5f, 1.f);
00076 float rough = roughness->Evaluate(dgs);
00077 BxDF *spec = BSDF_ALLOC(Microfacet)(ks, fresnel, BSDF_ALLOC(Blinn)(1.f / rough));
00078 bsdf->Add(spec);
00079 }
00080
00081 Spectrum kr = op * Kr->Evaluate(dgs).Clamp();
00082 if (!kr.Black()) {
00083 Fresnel *fresnel = BSDF_ALLOC(FresnelDielectric)(1.5f, 1.f);
00084 bsdf->Add(BSDF_ALLOC(SpecularReflection)(kr, fresnel));
00085 }
00086
00087 return bsdf;
00088 }
00089
00090 extern "C" DLLEXPORT Material * CreateMaterial(const Transform &xform,
00091 const TextureParams &mp) {
00092 Reference<Texture<Spectrum> > Kd = mp.GetSpectrumTexture("Kd", Spectrum(1.f));
00093 Reference<Texture<Spectrum> > Ks = mp.GetSpectrumTexture("Ks", Spectrum(1.f));
00094 Reference<Texture<Spectrum> > Kr = mp.GetSpectrumTexture("Kr", Spectrum(0.f));
00095 Reference<Texture<float> > roughness = mp.GetFloatTexture("roughness", .1f);
00096 Reference<Texture<Spectrum> > opacity = mp.GetSpectrumTexture("opacity", 1.f);
00097 Reference<Texture<float> > bumpMap = mp.GetFloatTexture("bumpmap", 0.f);
00098 return new UberMaterial(Kd, Ks, Kr, roughness, opacity, bumpMap);
00099 }