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 #include "stdafx.h"
00027 #include "texture.h"
00028 #include "shape.h"
00029 
00030 
00031 inline float SmoothStep(float min, float max, float value) {
00032     float v = Clamp((value - min) / (max - min), 0.f, 1.f);
00033     return v * v * (-2.f * v  + 3.f);
00034 }
00035 
00036 
00037 
00038 
00039 inline float Grad(int x, int y, int z, float dx, float dy, float dz);
00040 inline float NoiseWeight(float t);
00041 
00042 
00043 #define NOISE_PERM_SIZE 256
00044 static int NoisePerm[2 * NOISE_PERM_SIZE] = {
00045     151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96,
00046     53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142,
00047     
00048     8, 99, 37, 240, 21, 10, 23,
00049        190,  6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
00050        88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168,  68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
00051        77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
00052        102, 143, 54,  65, 25, 63, 161,  1, 216, 80, 73, 209, 76, 132, 187, 208,  89, 18, 169, 200, 196,
00053        135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186,  3, 64, 52, 217, 226, 250, 124, 123,
00054        5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
00055        223, 183, 170, 213, 119, 248, 152,  2, 44, 154, 163,  70, 221, 153, 101, 155, 167,  43, 172, 9,
00056        129, 22, 39, 253,  19, 98, 108, 110, 79, 113, 224, 232, 178, 185,  112, 104, 218, 246, 97, 228,
00057        251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241,  81, 51, 145, 235, 249, 14, 239, 107,
00058        49, 192, 214,  31, 181, 199, 106, 157, 184,  84, 204, 176, 115, 121, 50, 45, 127,  4, 150, 254,
00059        138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180,
00060        151, 160, 137, 91, 90, 15,
00061        131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23,
00062        190,  6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
00063        88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168,  68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
00064        77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
00065        102, 143, 54,  65, 25, 63, 161,  1, 216, 80, 73, 209, 76, 132, 187, 208,  89, 18, 169, 200, 196,
00066        135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186,  3, 64, 52, 217, 226, 250, 124, 123,
00067        5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
00068        223, 183, 170, 213, 119, 248, 152,  2, 44, 154, 163,  70, 221, 153, 101, 155, 167,  43, 172, 9,
00069        129, 22, 39, 253,  19, 98, 108, 110, 79, 113, 224, 232, 178, 185,  112, 104, 218, 246, 97, 228,
00070        251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241,  81, 51, 145, 235, 249, 14, 239, 107,
00071        49, 192, 214,  31, 181, 199, 106, 157, 184,  84, 204, 176, 115, 121, 50, 45, 127,  4, 150, 254,
00072        138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180
00073 };
00074 
00075 
00076 
00077 
00078 UVMapping2D::UVMapping2D(float ssu, float ssv, float ddu, float ddv)
00079     : su(ssu), sv(ssv), du(ddu), dv(ddv) { }
00080 void UVMapping2D::Map(const DifferentialGeometry &dg,
00081                       float *s, float *t, float *dsdx, float *dtdx,
00082                       float *dsdy, float *dtdy) const {
00083     *s = su * dg.u + du;
00084     *t = sv * dg.v + dv;
00085     
00086     *dsdx = su * dg.dudx;
00087     *dtdx = sv * dg.dvdx;
00088     *dsdy = su * dg.dudy;
00089     *dtdy = sv * dg.dvdy;
00090 }
00091 
00092 
00093 void SphericalMapping2D::Map(const DifferentialGeometry &dg,
00094         float *s, float *t, float *dsdx, float *dtdx,
00095         float *dsdy, float *dtdy) const {
00096     sphere(dg.p, s, t);
00097     
00098     float sx, tx, sy, ty;
00099     const float delta = .1f;
00100     sphere(dg.p + delta * dg.dpdx, &sx, &tx);
00101     *dsdx = (sx - *s) / delta;
00102     *dtdx = (tx - *t) / delta;
00103     if (*dtdx > .5) *dtdx = 1.f - *dtdx;
00104     else if (*dtdx < -.5f) *dtdx = -(*dtdx + 1);
00105     sphere(dg.p + delta * dg.dpdy, &sy, &ty);
00106     *dsdy = (sy - *s) / delta;
00107     *dtdy = (ty - *t) / delta;
00108     if (*dtdy > .5) *dtdy = 1.f - *dtdy;
00109     else if (*dtdy < -.5f) *dtdy = -(*dtdy + 1);
00110 }
00111 
00112 
00113 void SphericalMapping2D::sphere(const Point &p, float *s, float *t) const {
00114     Vector vec = Normalize(WorldToTexture(p) - Point(0,0,0));
00115     float theta = SphericalTheta(vec);
00116     float phi = SphericalPhi(vec);
00117     *s = theta * INV_PI;
00118     *t = phi * INV_TWOPI;
00119 }
00120 
00121 
00122 void CylindricalMapping2D::Map(const DifferentialGeometry &dg,
00123         float *s, float *t, float *dsdx, float *dtdx,
00124         float *dsdy, float *dtdy) const {
00125     cylinder(dg.p, s, t);
00126     
00127     float sx, tx, sy, ty;
00128     const float delta = .01f;
00129     cylinder(dg.p + delta * dg.dpdx, &sx, &tx);
00130     *dsdx = (sx - *s) / delta;
00131     *dtdx = (tx - *t) / delta;
00132     if (*dtdx > .5) *dtdx = 1.f - *dtdx;
00133     else if (*dtdx < -.5f) *dtdx = -(*dtdx + 1);
00134     cylinder(dg.p + delta * dg.dpdy, &sy, &ty);
00135     *dsdy = (sy - *s) / delta;
00136     *dtdy = (ty - *t) / delta;
00137     if (*dtdy > .5) *dtdy = 1.f - *dtdy;
00138     else if (*dtdy < -.5f) *dtdy = -(*dtdy + 1);
00139 }
00140 
00141 
00142 void PlanarMapping2D::Map(const DifferentialGeometry &dg,
00143         float *s, float *t, float *dsdx, float *dtdx,
00144         float *dsdy, float *dtdy) const {
00145     Vector vec = dg.p - Point(0,0,0);
00146     *s = ds + Dot(vec, vs);
00147     *t = dt + Dot(vec, vt);
00148     *dsdx = Dot(dg.dpdx, vs);
00149     *dtdx = Dot(dg.dpdx, vt);
00150     *dsdy = Dot(dg.dpdy, vs);
00151     *dtdy = Dot(dg.dpdy, vt);
00152 }
00153 
00154 
00155 Point IdentityMapping3D::Map(const DifferentialGeometry &dg,
00156                              Vector *dpdx, Vector *dpdy) const {
00157     *dpdx = WorldToTexture(dg.dpdx);
00158     *dpdy = WorldToTexture(dg.dpdy);
00159     return WorldToTexture(dg.p);
00160 }
00161 
00162 
00163 float Noise(float x, float y, float z) {
00164     
00165     int ix = Floor2Int(x), iy = Floor2Int(y), iz = Floor2Int(z);
00166     float dx = x - ix, dy = y - iy, dz = z - iz;
00167 
00168     
00169     ix &= (NOISE_PERM_SIZE-1);
00170     iy &= (NOISE_PERM_SIZE-1);
00171     iz &= (NOISE_PERM_SIZE-1);
00172     float w000 = Grad(ix,   iy,   iz,   dx,   dy,   dz);
00173     float w100 = Grad(ix+1, iy,   iz,   dx-1, dy,   dz);
00174     float w010 = Grad(ix,   iy+1, iz,   dx,   dy-1, dz);
00175     float w110 = Grad(ix+1, iy+1, iz,   dx-1, dy-1, dz);
00176     float w001 = Grad(ix,   iy,   iz+1, dx,   dy,   dz-1);
00177     float w101 = Grad(ix+1, iy,   iz+1, dx-1, dy,   dz-1);
00178     float w011 = Grad(ix,   iy+1, iz+1, dx,   dy-1, dz-1);
00179     float w111 = Grad(ix+1, iy+1, iz+1, dx-1, dy-1, dz-1);
00180 
00181     
00182     float wx = NoiseWeight(dx), wy = NoiseWeight(dy), wz = NoiseWeight(dz);
00183     float x00 = Lerp(wx, w000, w100);
00184     float x10 = Lerp(wx, w010, w110);
00185     float x01 = Lerp(wx, w001, w101);
00186     float x11 = Lerp(wx, w011, w111);
00187     float y0 = Lerp(wy, x00, x10);
00188     float y1 = Lerp(wy, x01, x11);
00189     return Lerp(wz, y0, y1);
00190 }
00191 
00192 
00193 float Noise(const Point &P) { return Noise(P.x, P.y, P.z); }
00194 inline float Grad(int x, int y, int z, float dx, float dy, float dz) {
00195     int h = NoisePerm[NoisePerm[NoisePerm[x]+y]+z];
00196     h &= 15;
00197     float u = h<8 || h==12 || h==13 ? dx : dy;
00198     float v = h<4 || h==12 || h==13 ? dy : dz;
00199     return ((h&1) ? -u : u) + ((h&2) ? -v : v);
00200 }
00201 
00202 
00203 inline float NoiseWeight(float t) {
00204     float t3 = t*t*t;
00205     float t4 = t3*t;
00206     return 6.f*t4*t - 15.f*t4 + 10.f*t3;
00207 }
00208 
00209 
00210 float FBm(const Point &P, const Vector &dpdx, const Vector &dpdy,
00211           float omega, int maxOctaves) {
00212     
00213     float s2 = max(dpdx.LengthSquared(), dpdy.LengthSquared());
00214     float foctaves = min((float)maxOctaves, 1.f - .5f * Log2(s2));
00215     int octaves = Floor2Int(foctaves);
00216 
00217     
00218     float sum = 0., lambda = 1., o = 1.;
00219     for (int i = 0; i < octaves; ++i) {
00220         sum += o * Noise(lambda * P);
00221         lambda *= 1.99f;
00222         o *= omega;
00223     }
00224     float partialOctave = foctaves - octaves;
00225     sum += o * SmoothStep(.3f, .7f, partialOctave) * Noise(lambda * P);
00226     return sum;
00227 }
00228 
00229 
00230 float Turbulence(const Point &P, const Vector &dpdx, const Vector &dpdy,
00231                  float omega, int maxOctaves) {
00232     
00233     float s2 = max(dpdx.LengthSquared(), dpdy.LengthSquared());
00234     float foctaves = min((float)maxOctaves, 1.f - .5f * Log2(s2));
00235     int octaves = Floor2Int(foctaves);
00236 
00237     
00238     float sum = 0., lambda = 1., o = 1.;
00239     for (int i = 0; i < octaves; ++i) {
00240         sum += o * fabsf(Noise(lambda * P));
00241         lambda *= 1.99f;
00242         o *= omega;
00243     }
00244     float partialOctave = foctaves - octaves;
00245     sum += o * SmoothStep(.3f, .7f, partialOctave) *
00246            fabsf(Noise(lambda * P));
00247     return sum;
00248 }
00249 
00250 
00251 
00252 
00253 float Lanczos(float x, float tau) {
00254     x = fabsf(x);
00255     if (x < 1e-5) return 1;
00256     if (x > 1.)    return 0;
00257     x *= M_PI;
00258     float s = sinf(x * tau) / (x * tau);
00259     float lanczos = sinf(x) / x;
00260     return s * lanczos;
00261 }
00262 
00263