00001 #include <esg/brdf/CookTorranceBRDF.h>
00002
00003 using namespace esg;
00004
00005 BRDF::RetVal CookTorranceBRDF::reflectance(const MatVisitor& visitor,
00006 const Vector3* L,
00007 const Vector3* V,
00008 const Vector3* N,
00009 Vector3& color)
00010 {
00011 static Vector3 H;
00012
00013
00014
00015
00016 if (!N || !L || !V) return BAD_PARAMS;
00017
00018 register double nv = N->dot(*V);
00019 if (nv <= 0.0) return NV_NEGATIVE;
00020 register double nl = N->dot(*L);
00021 if (nl <= 0.0) return NL_NEGATIVE;
00022 H.set(*V);
00023 H.add(*L);
00024 H.scale(0.5);
00025 register double hn = H.dot(*N);
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 color.set(visitor.gaussianCoef());
00037 color.scale(exp(-pow(acos(hn)/visitor.roughness(),2)));
00038
00039
00040
00041
00042
00043
00044
00045 double aux = (2 * hn) / H.dot(*V);
00046 double Gm = aux * nv;
00047 double Gs = aux * nl;
00048 double G = 1;
00049 if (Gm < G) G = Gm;
00050 if (Gs < G) G = Gs;
00051
00052 #ifndef WIN32
00053 #warning "TODO: Interpolated Fresnel term"
00054 #endif
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 Vector3 F(visitor.fresnelTerm());
00065 Vector3 F0(1,1,1);
00066 F0.sub(F);
00067 F0.scale(pow(1-nl,5));
00068 F.add(F0);
00069
00070
00071
00072
00073
00074
00075
00076
00077 F.scale(G/nv);
00078
00079
00080
00081 color.x *= F.x;
00082 color.y *= F.y;
00083 color.z *= F.z;
00084
00085
00086
00087
00088
00089 Vector3 auxv(visitor.diffuse());
00090 auxv.scale(nl);
00091 color.add(auxv);
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 return NONZERO_CONTRIB;
00105 }
00106
00107 BRDF::RetVal CookTorranceBRDF::reflectanceVNL(const MatVisitor& visitor,
00108 const Vector3* L,
00109 const Vector3* V,
00110 const Vector3* N,
00111 double NV,
00112 double NL,
00113 Vector3& color)
00114 {
00115 static Vector3 H;
00116
00117
00118
00119
00120 if (!N || !L || !V) return BAD_PARAMS;
00121
00122 H.set(*V);
00123 H.add(*L);
00124 H.scale(0.5);
00125 register double hn = H.dot(*N);
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 color.set(visitor.gaussianCoef());
00137 color.scale(exp(-pow(acos(hn)/visitor.roughness(),2)));
00138
00139
00140
00141
00142
00143
00144
00145 double aux = (2 * hn) / H.dot(*V);
00146 double Gm = aux * NV;
00147 double Gs = aux * NL;
00148 double G = 1;
00149 if (Gm < G) G = Gm;
00150 if (Gs < G) G = Gs;
00151
00152 #ifndef WIN32
00153 #warning "TODO: Interpolated Fresnel term"
00154 #endif
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 Vector3 F(visitor.fresnelTerm());
00165 Vector3 F0(1,1,1);
00166 F0.sub(F);
00167 F0.scale(pow(1-NL,5));
00168 F.add(F0);
00169
00170
00171
00172
00173
00174
00175
00176
00177 F.scale(G/NV);
00178 color.x *= F.x * visitor.specular().x;
00179 color.y *= F.y * visitor.specular().y;
00180 color.z *= F.z * visitor.specular().z;
00181
00182
00183
00184
00185
00186 Vector3 auxv(visitor.diffuse());
00187 auxv.scale(NL);
00188 color.add(auxv);
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 return NONZERO_CONTRIB;
00202 }
00203
00204 BRDF::RetVal CookTorranceBRDF::reflectanceNL(const MatVisitor& visitor,
00205 const Vector3* L,
00206 const Vector3* V,
00207 const Vector3* N,
00208 double NL,
00209 Vector3& color)
00210 {
00211 static Vector3 H;
00212
00213
00214
00215
00216 if (!N || !L || !V) return BAD_PARAMS;
00217
00218 register double nv = N->dot(*V);
00219 if (nv <= 0.0) return NV_NEGATIVE;
00220 H.set(*V);
00221 H.add(*L);
00222 H.scale(0.5);
00223 register double hn = H.dot(*N);
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 color.set(visitor.gaussianCoef());
00235 color.scale(exp(-pow(acos(hn)/visitor.roughness(),2)));
00236
00237
00238
00239
00240
00241
00242
00243 double aux = (2 * hn) / H.dot(*V);
00244 double Gm = aux * nv;
00245 double Gs = aux * NL;
00246 double G = 1;
00247 if (Gm < G) G = Gm;
00248 if (Gs < G) G = Gs;
00249
00250 #ifndef WIN32
00251 #warning "TODO: Interpolated Fresnel term"
00252 #endif
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 Vector3 F(visitor.fresnelTerm());
00263 Vector3 F0(1,1,1);
00264 F0.sub(F);
00265 F0.scale(pow(1-NL,5));
00266 F.add(F0);
00267
00268
00269
00270
00271
00272
00273
00274
00275 F.scale(G/nv);
00276 color.x *= F.x * visitor.specular().x;
00277 color.y *= F.y * visitor.specular().y;
00278 color.z *= F.z * visitor.specular().z;
00279
00280
00281
00282
00283
00284 Vector3 auxv(visitor.diffuse());
00285 auxv.scale(NL);
00286 color.add(auxv);
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 return NONZERO_CONTRIB;
00300 }
00301
00302