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