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
00026
00027 #include "carpaint.h"
00028 #include "bxdf.h"
00029 #include "blinn.h"
00030 #include "fresnelslick.h"
00031 #include "microfacet.h"
00032 #include "fresnelblend.h"
00033 #include "paramset.h"
00034
00035 using namespace lux;
00036
00037 CarPaint::CarPaint(boost::shared_ptr<Texture<Spectrum> > kd,
00038 boost::shared_ptr<Texture<Spectrum> > ks1, boost::shared_ptr<Texture<Spectrum> > ks2, boost::shared_ptr<Texture<Spectrum> > ks3,
00039 boost::shared_ptr<Texture<float> > r1, boost::shared_ptr<Texture<float> > r2, boost::shared_ptr<Texture<float> > r3,
00040 boost::shared_ptr<Texture<float> > m1, boost::shared_ptr<Texture<float> > m2, boost::shared_ptr<Texture<float> > m3,
00041 boost::shared_ptr<Texture<float> > bump) {
00042 Kd = kd;
00043 Ks1 = ks1;
00044 Ks2 = ks2;
00045 Ks3 = ks3;
00046 R1 = r1;
00047 R2 = r2;
00048 R3 = r3;
00049 M1 = m1;
00050 M2 = m2;
00051 M3 = m3;
00052 bumpMap = bump;
00053 }
00054
00055
00056 BSDF *CarPaint::GetBSDF(const DifferentialGeometry &dgGeom, const DifferentialGeometry &dgShading, float u) const {
00057
00058
00059 DifferentialGeometry dgs;
00060
00061 if (bumpMap)
00062 Bump(bumpMap, dgGeom, dgShading, &dgs);
00063 else
00064 dgs = dgShading;
00065
00066 BSDF *bsdf = BSDF_ALLOC( BSDF)(dgs, dgGeom.nn);
00067
00068
00069 SWCSpectrum kd(Kd->Evaluate(dgs).Clamp(0.f, 1.f));
00070 SWCSpectrum ks1(Ks1->Evaluate(dgs).Clamp(0.f, 1.f));
00071 SWCSpectrum ks2(Ks2->Evaluate(dgs).Clamp(0.f, 1.f));
00072 SWCSpectrum ks3(Ks3->Evaluate(dgs).Clamp(0.f, 1.f));
00073
00074
00075 float r1 = Clamp(R1->Evaluate(dgs), 0.f, 1.f);
00076 float r2 = Clamp(R2->Evaluate(dgs), 0.f, 1.f);
00077 float r3 = Clamp(R3->Evaluate(dgs), 0.f, 1.f);
00078
00079 float m1 = M1->Evaluate(dgs);
00080 float m2 = M2->Evaluate(dgs);
00081 float m3 = M3->Evaluate(dgs);
00082
00083 MicrofacetDistribution *md1 = BSDF_ALLOC( Blinn)((2.0 * M_PI / (m1 * m1)) - 1.0);
00084 MicrofacetDistribution *md2 = BSDF_ALLOC( Blinn)((2.0 * M_PI / (m2 * m2)) - 1.0);
00085 MicrofacetDistribution *md3 = BSDF_ALLOC( Blinn)((2.0 * M_PI / (m3 * m3)) - 1.0);
00086
00087
00088
00089
00090
00091
00092 Fresnel *fr1 = BSDF_ALLOC( FresnelSlick)(r1);
00093 Fresnel *fr2 = BSDF_ALLOC( FresnelSlick)(r2);
00094 Fresnel *fr3 = BSDF_ALLOC( FresnelSlick)(r3);
00095
00096
00097
00098 SWCSpectrum *lobe_ks = (SWCSpectrum *)BSDF::Alloc(3 * sizeof(SWCSpectrum));
00099 lobe_ks[0] = ks1;
00100 lobe_ks[1] = ks2;
00101 lobe_ks[2] = ks3;
00102
00103 MicrofacetDistribution **lobe_dist = (MicrofacetDistribution **)BSDF::Alloc(3 * sizeof(MicrofacetDistribution *));
00104 lobe_dist[0] = md1;
00105 lobe_dist[1] = md2;
00106 lobe_dist[2] = md3;
00107
00108 Fresnel **lobe_fres = (Fresnel **)BSDF::Alloc(3 * sizeof(Fresnel *));
00109 lobe_fres[0] = fr1;
00110 lobe_fres[1] = fr2;
00111 lobe_fres[2] = fr3;
00112
00113
00114 for (int i = 0; i < 2; i++) {
00115 bsdf->Add(BSDF_ALLOC( Microfacet)(lobe_ks[i], lobe_fres[i], lobe_dist[i]));
00116 }
00117
00118
00119 bsdf->Add(BSDF_ALLOC( FresnelBlend)(kd, lobe_ks[2], lobe_dist[2]));
00120
00121
00122
00123 return bsdf;
00124 }
00125
00126 void DataFromName(const string name, boost::shared_ptr<Texture<Spectrum> > *Kd,
00127 boost::shared_ptr<Texture<Spectrum> > *Ks1,
00128 boost::shared_ptr<Texture<Spectrum> > *Ks2,
00129 boost::shared_ptr<Texture<Spectrum> > *Ks3,
00130 boost::shared_ptr<Texture<float> > *R1,
00131 boost::shared_ptr<Texture<float> > *R2,
00132 boost::shared_ptr<Texture<float> > *R3,
00133 boost::shared_ptr<Texture<float> > *M1,
00134 boost::shared_ptr<Texture<float> > *M2,
00135 boost::shared_ptr<Texture<float> > *M3) {
00136
00137 int numPaints = sizeof(carpaintdata) / sizeof(CarPaintData);
00138
00139
00140
00141 int i;
00142
00143 for (i = 0; i < numPaints; i++) {
00144 if (name.compare(carpaintdata[i].name) == 0)
00145 break;
00146 }
00147
00148 boost::shared_ptr<Texture<Spectrum> > kd (new ConstantTexture<Spectrum>(carpaintdata[i].kd));
00149 boost::shared_ptr<Texture<Spectrum> > ks1 (new ConstantTexture<Spectrum>(carpaintdata[i].ks1));
00150 boost::shared_ptr<Texture<Spectrum> > ks2 (new ConstantTexture<Spectrum>(carpaintdata[i].ks2));
00151 boost::shared_ptr<Texture<Spectrum> > ks3 (new ConstantTexture<Spectrum>(carpaintdata[i].ks3));
00152 boost::shared_ptr<Texture<float> > r1 (new ConstantTexture<float>(carpaintdata[i].r1));
00153 boost::shared_ptr<Texture<float> > r2 (new ConstantTexture<float>(carpaintdata[i].r2));
00154 boost::shared_ptr<Texture<float> > r3 (new ConstantTexture<float>(carpaintdata[i].r3));
00155 boost::shared_ptr<Texture<float> > m1 (new ConstantTexture<float>(carpaintdata[i].m1));
00156 boost::shared_ptr<Texture<float> > m2 (new ConstantTexture<float>(carpaintdata[i].m2));
00157 boost::shared_ptr<Texture<float> > m3 (new ConstantTexture<float>(carpaintdata[i].m3));
00158
00159 *Kd = kd;
00160 *Ks1 = ks1;
00161 *Ks2 = ks2;
00162 *Ks3 = ks3;
00163 *R1 = r1;
00164 *R2 = r2;
00165 *R3 = r3;
00166 *M1 = m1;
00167 *M2 = m2;
00168 *M3 = m3;
00169 }
00170
00171 Material* CarPaint::CreateMaterial(const Transform &xform, const TextureParams &mp) {
00172
00173
00174 float def_kd[3], def_ks1[3], def_ks2[3], def_ks3[3], def_r[3], def_m[3];
00175
00176 for (int i = 0; i < 3; i++) {
00177 def_kd[i] = carpaintdata[0].kd[i];
00178 def_ks1[i] = carpaintdata[0].ks1[i];
00179 def_ks2[i] = carpaintdata[0].ks2[i];
00180 def_ks3[i] = carpaintdata[0].ks3[i];
00181 }
00182
00183 def_r[0] = carpaintdata[0].r1;
00184 def_r[1] = carpaintdata[0].r2;
00185 def_r[2] = carpaintdata[0].r3;
00186
00187 def_m[0] = carpaintdata[0].m1;
00188 def_m[1] = carpaintdata[0].m2;
00189 def_m[2] = carpaintdata[0].m3;
00190
00191 string paintname = mp.FindString("name");
00192
00193 boost::shared_ptr<Texture<Spectrum> > Kd;
00194
00195 boost::shared_ptr<Texture<Spectrum> > Ks1;
00196 boost::shared_ptr<Texture<Spectrum> > Ks2;
00197 boost::shared_ptr<Texture<Spectrum> > Ks3;
00198
00199 boost::shared_ptr<Texture<float> > R1;
00200 boost::shared_ptr<Texture<float> > R2;
00201 boost::shared_ptr<Texture<float> > R3;
00202
00203 boost::shared_ptr<Texture<float> > M1;
00204 boost::shared_ptr<Texture<float> > M2;
00205 boost::shared_ptr<Texture<float> > M3;
00206
00207 if (paintname.length() < 1) {
00208
00209 Kd = mp.GetSpectrumTexture("Kd", Spectrum(def_kd));
00210
00211 Ks1 = mp.GetSpectrumTexture("Ks1", Spectrum(def_ks1));
00212 Ks2 = mp.GetSpectrumTexture("Ks2", Spectrum(def_ks2));
00213 Ks3 = mp.GetSpectrumTexture("Ks3", Spectrum(def_ks3));
00214
00215 R1 = mp.GetFloatTexture("R1", def_r[0]);
00216 R2 = mp.GetFloatTexture("R2", def_r[1]);
00217 R3 = mp.GetFloatTexture("R3", def_r[2]);
00218
00219 M1 = mp.GetFloatTexture("M1", def_m[0]);
00220 M2 = mp.GetFloatTexture("M2", def_m[1]);
00221 M3 = mp.GetFloatTexture("M3", def_m[2]);
00222 }
00223 else
00224
00225 DataFromName(paintname, &Kd, &Ks1, &Ks2, &Ks3, &R1, &R2, &R3, &M1, &M2, &M3);
00226
00227 boost::shared_ptr<Texture<float> > bumpMap = mp.GetFloatTexture("bumpmap", 0.f);
00228
00229 return new CarPaint(Kd, Ks1, Ks2, Ks3, R1, R2, R3, M1, M2, M3, bumpMap);
00230 }