00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if defined(_MSC_VER)
00025 #pragma once
00026 #endif
00027
00028 #ifndef PBRT_TEXTURES_CHECKERBOARD_H
00029 #define PBRT_TEXTURES_CHECKERBOARD_H
00030
00031
00032 #include "pbrt.h"
00033 #include "texture.h"
00034 #include "paramset.h"
00035 #include "montecarlo.h"
00036 #include "shape.h"
00037 #include "parallel.h"
00038 #include "progressreporter.h"
00039
00040
00041 template <typename T> class Checkerboard2DTexture : public Texture<T> {
00042 public:
00043
00044 Checkerboard2DTexture(TextureMapping2D *m, Reference<Texture<T> > c1,
00045 Reference<Texture<T> > c2, const string &aa)
00046 : mapping(m), tex1(c1), tex2(c2) {
00047
00048 if (aa == "none") aaMethod = NONE;
00049 else if (aa == "closedform") aaMethod = CLOSEDFORM;
00050 else {
00051 Warning("Antialiasing mode \"%s\" not understood by "
00052 "Checkerboard2DTexture; using \"closedform\"", aa.c_str());
00053 aaMethod = CLOSEDFORM;
00054 }
00055 }
00056 ~Checkerboard2DTexture() {
00057 delete mapping;
00058 }
00059 T Evaluate(const DifferentialGeometry &dg) const {
00060 float s, t, dsdx, dtdx, dsdy, dtdy;
00061 mapping->Map(dg, &s, &t, &dsdx, &dtdx, &dsdy, &dtdy);
00062 if (aaMethod == NONE) {
00063
00064 if ((Floor2Int(s) + Floor2Int(t)) % 2 == 0)
00065 return tex1->Evaluate(dg);
00066 return tex2->Evaluate(dg);
00067 }
00068 else {
00069
00070
00071
00072 float ds = max(fabsf(dsdx), fabsf(dsdy));
00073 float dt = max(fabsf(dtdx), fabsf(dtdy));
00074 float s0 = s - ds, s1 = s + ds;
00075 float t0 = t - dt, t1 = t + dt;
00076 if (Floor2Int(s0) == Floor2Int(s1) && Floor2Int(t0) == Floor2Int(t1)) {
00077
00078 if ((Floor2Int(s) + Floor2Int(t)) % 2 == 0)
00079 return tex1->Evaluate(dg);
00080 return tex2->Evaluate(dg);
00081 }
00082
00083
00084 #define BUMPINT(x) \
00085 (Floor2Int((x)/2) + \
00086 2.f * max((x/2)-Floor2Int(x/2) - .5f, 0.f))
00087 float sint = (BUMPINT(s1) - BUMPINT(s0)) / (2.f * ds);
00088 float tint = (BUMPINT(t1) - BUMPINT(t0)) / (2.f * dt);
00089 float area2 = sint + tint - 2.f * sint * tint;
00090 if (ds > 1.f || dt > 1.f)
00091 area2 = .5f;
00092 return (1.f - area2) * tex1->Evaluate(dg) +
00093 area2 * tex2->Evaluate(dg);
00094 }
00095 }
00096 private:
00097
00098 TextureMapping2D *mapping;
00099 Reference<Texture<T> > tex1, tex2;
00100 enum { NONE, CLOSEDFORM } aaMethod;
00101 };
00102
00103
00104 template <typename T> class Checkerboard3DTexture : public Texture<T> {
00105 public:
00106
00107 Checkerboard3DTexture(TextureMapping3D *m, Reference<Texture<T> > c1,
00108 Reference<Texture<T> > c2)
00109 : mapping(m), tex1(c1), tex2(c2) {
00110 }
00111 ~Checkerboard3DTexture() {
00112 delete mapping;
00113 }
00114 T Evaluate(const DifferentialGeometry &dg) const {
00115 Vector dpdx, dpdy;
00116 Point p = mapping->Map(dg, &dpdx, &dpdy);
00117 if ((Floor2Int(p.x) + Floor2Int(p.y) + Floor2Int(p.z)) % 2 == 0)
00118 return tex1->Evaluate(dg);
00119 else
00120 return tex2->Evaluate(dg);
00121 }
00122 private:
00123
00124 TextureMapping3D *mapping;
00125 Reference<Texture<T> > tex1, tex2;
00126 };
00127
00128
00129 Texture<float> *CreateCheckerboardFloatTexture(const Transform &tex2world,
00130 const TextureParams &tp);
00131 Texture<Spectrum> *CreateCheckerboardSpectrumTexture(const Transform &tex2world,
00132 const TextureParams &tp);
00133
00134 #endif // PBRT_TEXTURES_CHECKERBOARD_H