00001
00002
00003 #ifndef __BLINN_BRDF_H
00004 #define __BLINN_BRDF_H
00005
00006 #include <esg/Definitions.h>
00007 #include <esg/visitor/MatVisitor.h>
00008 #include <esg/brdf/SpecularBRDF.h>
00009 #include <esg/brdf/PhongBRDF.h>
00010
00011 namespace esg {
00012
00023 class OGSCENE_EXPORT BlinnBRDF : public SpecularBRDF {
00024 protected:
00025 virtual void _duplicate_attributes (const BRDF& src) {
00026 SpecularBRDF::_duplicate_attributes(src);
00027 }
00028
00029 public:
00033 BlinnBRDF (void) : SpecularBRDF(true) {}
00034
00035
00036 virtual RetVal reflectance(const MatVisitor& visitor,
00037 const Vector3* L,
00038 const Vector3* V,
00039 const Vector3* N,
00040 Vector3& color) {
00041 static Vector3 H;
00042 if (!N || !L || !V) return BAD_PARAMS;
00043 register double nl = N->dot(*L);
00044 if (nl <= 0.0) return NL_NEGATIVE;
00045 register double lv = L->dot(*V);
00046 if (lv > 0.0) return ZERO_CONTRIB;
00047 H.set(*L);
00048 H.add(*V);
00049 register double hn = H.dot(*N);
00050 if (hn < 0.0) return NL_OR_NV_NEGATIVE;
00051 color.set(visitor.specular());
00052 color.scale(pow(hn / sqrt(2. * lv + 2.),(double)visitor.intRoughness()) / nl);
00053 return NONZERO_CONTRIB;
00054 }
00055
00056 virtual RetVal reflectanceVNL(const MatVisitor& visitor,
00057 const Vector3* L,
00058 const Vector3* V,
00059 const Vector3* N,
00060 double NV,
00061 double NL,
00062 Vector3& color) {
00063 static Vector3 H;
00064 if (!N || !L || !V) return BAD_PARAMS;
00065 H.set(*L);
00066 H.add(*V);
00067 register double hn = H.dot(*N);
00068 if (hn < 0.0) return NL_OR_NV_NEGATIVE;
00069 color.set(visitor.specular());
00070 color.scale(pow(hn/sqrt(2.*L->dot(*V)+2.),(double)visitor.intRoughness()) / NL);
00071 return NONZERO_CONTRIB;
00072 }
00073
00074 virtual RetVal reflectanceNL(const MatVisitor& visitor,
00075 const Vector3* L,
00076 const Vector3* V,
00077 const Vector3* N,
00078 double NL,
00079 Vector3& color) {
00080 static Vector3 H;
00081 if (!N || !L || !V) return BAD_PARAMS;
00082 H.set(*L);
00083 H.add(*V);
00084 register double hn = H.dot(*N);
00085 if (hn < 0.0) return NL_OR_NV_NEGATIVE;
00086 color.set(visitor.specular());
00087 color.scale(pow(hn/sqrt(2.*L->dot(*V)+2.),(double)visitor.intRoughness()) / NL);
00088 return NONZERO_CONTRIB;
00089 }
00090
00091 virtual BRDF* clone (void) const { return new BlinnBRDF(); }
00092
00093 virtual double albedo (const MatVisitor& visitor,
00094 const Vector3& N,
00095 const Vector3* V) const {
00096 PhongBRDF aux;
00097 return aux.albedo(visitor, N, V);
00098 }
00099
00100 virtual void importanceSample(const MatVisitor& visitor,
00101 const Vector3& D,
00102 double r1,
00103 double r2,
00104 Vector3& dir,
00105 double* pPDFVal) {
00106
00107 PhongBRDF aux;
00108 aux.importanceSample(visitor, D, r1, r2, dir, pPDFVal);
00109 }
00110
00111 virtual Vector2 dir2uv (const MatVisitor& visitor,
00112 const Vector3& N,
00113 const Vector3& D) const {
00114
00115 PhongBRDF aux;
00116 aux.dir2uv(visitor, N, D);
00117 }
00118 };
00119
00120 };
00121
00122 #endif // __BLINN_BRDF_H