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