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