# HG changeset patch # User Radek Brich # Date 1208954373 -7200 # Node ID 062b1c4143f7fcbba148cd7fa00423c526603d99 # Parent 9569e9f35374bbaafc63001f6f7c83418aab02ba material and texture classes moved to material.(cc,h) 2D texture mappings from textures.cc polished and moved to material.h add ColourMap class and subclasses to make textures more flexible two example textures: CheckersTexture and CloudTexture (using Perlin noise) diff -r 9569e9f35374 -r 062b1c4143f7 TODO --- a/TODO Wed Apr 23 10:38:33 2008 +0200 +++ b/TODO Wed Apr 23 14:39:33 2008 +0200 @@ -4,7 +4,7 @@ Future Plans ============ - * textures (3D procedural, pixmaps) + * pixmap textures * generalization: Camera "shader" (ray generator), surface shader and maybe light & background shaders * namespace * Python binding for all classes diff -r 9569e9f35374 -r 062b1c4143f7 ccdemos/textures.cc --- a/ccdemos/textures.cc Wed Apr 23 10:38:33 2008 +0200 +++ b/ccdemos/textures.cc Wed Apr 23 14:39:33 2008 +0200 @@ -9,137 +9,6 @@ Float lx, ly, lz, cf; - -/*class CloudTexture: public Texture -{ - Vector3 centre; -public: - Colour evaluate(Vector3 point) - { - Float sum = 0.0; - for (int i = 1; i < 5; i++) - sum += fabsf(perlin(point.x*i, point.y*i, point.z*i))/i; - Float value = sinf(point.x + sum)/2 + 0.5; - return Colour(value, value*0.5, value*0.5); - }; -};*/ - -void texture2D(Float u, Float v, Float &r, Float &g, Float &b) -{ - // checkers - r = fabs((int)(u*4.2)%2 + (int)(v*4.2)%2 - 1); - g=r; b=r; -} - -class PlanarMapTexture: public Texture -{ - Vector3 centre; -public: - PlanarMapTexture(Vector3 acentre): centre(acentre) {}; - Colour evaluate(Vector3 point) - { - point = point - centre; - Float u = 1000+point.x; - Float v = 1000+point.y; - Float r,g,b; - texture2D(u,v, r,g,b); - return Colour(r, g, b); - }; -}; - -class CubicMapTexture: public Texture -{ - Vector3 centre; -public: - CubicMapTexture(Vector3 acentre): centre(acentre) {}; - Colour evaluate(Vector3 point) - { - point = point - centre; - Float u,v; - if (fabs(point.x) > fabs(point.y)) - { - if (fabs(point.x) > fabs(point.z)) - { - if (point.x < 0) - u = -point.y; - else - u = point.y; - v = point.z; - } - else - { - if (point.z < 0) - u = -point.x; - else - u = point.x; - v = point.y; - } - } - else - { - if (fabs(point.y) > fabs(point.z)) - { - if (point.y < 0) - u = -point.x; - else - u = point.x; - v = point.z; - } - else - { - if (point.z < 0) - u = -point.x; - else - u = point.x; - v = point.y; - } - } - u += 1000; - v += 1000; - Float r,g,b; - texture2D(u,v, r,g,b); - return Colour(r, g, b); - }; -}; - -class CylinderMapTexture: public Texture -{ - Vector3 centre; -public: - CylinderMapTexture(Vector3 acentre): centre(acentre) {}; - Colour evaluate(Vector3 point) - { - point = point - centre; - - Float u,v; - v = 1000+point.y; - u = M_PI + atan2(point.z, point.x); - - Float r,g,b; - texture2D(u,v, r,g,b); - return Colour(r, g, b); - }; -}; - -class SphereMapTexture: public Texture -{ - Vector3 centre; -public: - SphereMapTexture(Vector3 acentre): centre(acentre) {}; - Colour evaluate(Vector3 point) - { - point = point - centre; - - Float u,v; - v = acos(point.y / point.mag()); - u = M_PI + atan2(point.z, point.x); - - Float r,g,b; - texture2D(u,v, r,g,b); - return Colour(r, g, b); - }; -}; - void update_callback() { if (lx != 0.0) @@ -196,7 +65,7 @@ light.castShadows(false); Material mat0a(Colour(0.7, 0.7, 0.7)); - mat0a. setReflectivity(0.0); + mat0a.setReflectivity(0.0); Box box(Vector3(-12.0, -1.2, -20.0), Vector3(12.0, -1.0, 0.0), &mat0a); rt.addShape(&box); @@ -205,45 +74,49 @@ Box box2(Vector3(-12.0, -1.2, -10.0), Vector3(12.0, 10.0, -10.2), &mat0b); rt.addShape(&box2); + Float bounds[] = {0.3, 0.6, 1.1}; + Colour colours[] = {Colour(0,0,0), Colour(1,1,1), Colour(0,0,0)}; + BoundColourMap cmap(bounds, colours); + // spheres Material mat1(Colour(1.0, 1.0, 1.0)); - mat1.texture = new PlanarMapTexture(Vector3(-4.5, 2.0, -7.0)); + mat1.texture = new CheckersTexture(new PlanarMap(Vector3(-4.5, 2.0, -7.0), 0.48), &cmap); Sphere sphere1(Vector3(-4.5, 2.0, -7.0), 1.0, &mat1); rt.addShape(&sphere1); Material mat2(Colour(1.0, 1.0, 1.0)); - mat2.texture = new CubicMapTexture(Vector3(-1.5, 2.0, -7.0)); + mat2.texture = new CheckersTexture(new CubicMap(Vector3(-1.5, 2.0, -7.0), 0.48), &cmap); Sphere sphere2(Vector3(-1.5, 2.0, -7.0), 1.0, &mat2); rt.addShape(&sphere2); Material mat3(Colour(1.0, 1.0, 1.0)); - mat3.texture = new CylinderMapTexture(Vector3(1.5, 2.0, -7.0)); + mat3.texture = new CheckersTexture(new CylinderMap(Vector3(1.5, 2.0, -7.0), 0.48), &cmap); Sphere sphere3(Vector3(1.5, 2.0, -7.0), 1.0, &mat3); rt.addShape(&sphere3); Material mat4(Colour(1.0, 1.0, 1.0)); - mat4.texture = new SphereMapTexture(Vector3(4.5, 2.0, -7.0)); + mat4.texture = new CheckersTexture(new SphereMap(Vector3(4.5, 2.0, -7.0), 0.48), &cmap); Sphere sphere4(Vector3(4.5, 2.0, -7.0), 1.0, &mat4); rt.addShape(&sphere4); // cubes Material mat5(Colour(1.0, 1.0, 1.0)); - mat5.texture = new PlanarMapTexture(Vector3(-4.5, 0.0, -7.0)); + mat5.texture = new CheckersTexture(new PlanarMap(Vector3(-4.5, 0.0, -7.0), 0.48), &cmap); Box cube1(Vector3(-4.5, 0.0, -7.0)-1.0, Vector3(-4.5, 0.0, -7.0)+1.0, &mat5); rt.addShape(&cube1); Material mat6(Colour(1.0, 1.0, 1.0)); - mat6.texture = new CubicMapTexture(Vector3(-1.5, 0.0, -7.0)); + mat6.texture = new CheckersTexture(new CubicMap(Vector3(-1.5, 0.0, -7.0), 0.48), &cmap); Box cube2(Vector3(-1.5, 0.0, -7.0)-1.0, Vector3(-1.5, 0.0, -7.0)+1.0, &mat6); rt.addShape(&cube2); Material mat7(Colour(1.0, 1.0, 1.0)); - mat7.texture = new CylinderMapTexture(Vector3(1.5, 0.0, -7.0)); + mat7.texture = new CheckersTexture(new CylinderMap(Vector3(1.5, 0.0, -7.0), 0.48), &cmap); Box cube3(Vector3(1.5, 0.0, -7.0)-1.0, Vector3(1.5, 0.0, -7.0)+1.0, &mat7); rt.addShape(&cube3); Material mat8(Colour(1.0, 1.0, 1.0)); - mat8.texture = new SphereMapTexture(Vector3(4.5, 0.0, -7.0)); + mat8.texture = new CheckersTexture(new SphereMap(Vector3(4.5, 0.0, -7.0), 0.48), &cmap); Box cube4(Vector3(4.5, 0.0, -7.0)-1.0, Vector3(4.5, 0.0, -7.0)+1.0, &mat8); rt.addShape(&cube4); diff -r 9569e9f35374 -r 062b1c4143f7 include/material.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/material.h Wed Apr 23 14:39:33 2008 +0200 @@ -0,0 +1,296 @@ +/* + * material.h: material and texture classes + * + * This file is part of Pyrit Ray Tracer. + * + * Copyright 2006, 2007, 2008 Radek Brich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MATERIAL_H +#define MATERIAL_H + +#include "common.h" +#include "vector.h" +#include "noise.h" + +/** + * perlin noise + */ +Float perlin(Float x, Float y, Float z); + +/** + * general texture + */ +class Texture +{ +public: + virtual ~Texture() {}; + virtual Colour evaluate(const Vector3 &point) = 0; +}; + +/** + * general colour map + */ +class ColourMap +{ +public: + virtual Colour map(const Float &val) = 0; +}; + +/** + * linear colour map + * maps value lineary between two colours + */ +class LinearColourMap: public ColourMap +{ + Colour col,cdiff; +public: + LinearColourMap(const Colour &clow, const Colour &chigh): + col(clow), cdiff(chigh-clow) {}; + Colour map(const Float &val) { return col + cdiff*val; }; +}; + +/** + * bound colour map + * initialize with two arrays, bounds and colours, of same size + * bounds must contain numbers between 0 and 1 in rising order, + * last number should be larger than max 'val' + * colours are mapped to slices between bounds (with zero being + * implicit bottom bound) + */ +class BoundColourMap: public ColourMap +{ + Float *bounds; + Colour *colours; +public: + BoundColourMap(Float *abounds, Colour *acolours): + bounds(abounds), colours(acolours) {}; + Colour map(const Float &val) + { + Float *b = bounds; + Colour *c = colours; + while (val > *b) + { + b++; + c++; + } + return *c; + }; +}; + +/** + * general texture mapping + */ +class TextureMap +{ +protected: + Vector3 center; + Float invsize; +public: + TextureMap(const Vector3 &acenter, const Float &size): + center(acenter), invsize(1./size) {}; + virtual void map(const Vector3 &point, Float &u, Float &v) = 0; +}; + +/** + * planar mapping + */ +class PlanarMap: public TextureMap +{ +public: + PlanarMap(const Vector3 &acenter, const Float &size): + TextureMap(acenter, size) {}; + void map(const Vector3 &point, Float &u, Float &v) + { + const Vector3 p = point - center; + u = p.x*invsize; + v = p.y*invsize; + }; +}; + +/** + * cubic mapping + */ +class CubicMap: public TextureMap +{ +public: + CubicMap(const Vector3 &acenter, const Float &size): + TextureMap(acenter, size) {}; + void map(const Vector3 &point, Float &u, Float &v) + { + const Vector3 p = point - center; + if (fabs(p.x) > fabs(p.y)) + { + if (fabs(p.x) > fabs(p.z)) + { + if (p.x < 0) + u = -p.y; + else + u = p.y; + v = p.z; + } + else + { + if (p.z < 0) + u = -p.x; + else + u = p.x; + v = p.y; + } + } + else + { + if (fabs(p.y) > fabs(p.z)) + { + if (p.y < 0) + u = -p.x; + else + u = p.x; + v = p.z; + } + else + { + if (p.z < 0) + u = -p.x; + else + u = p.x; + v = p.y; + } + } + u = u*invsize; + v = v*invsize; + }; +}; + +/** + * cylindrical mapping + */ +class CylinderMap: public TextureMap +{ +public: + CylinderMap(const Vector3 &acenter, const Float &size): + TextureMap(acenter, size) {}; + void map(const Vector3 &point, Float &u, Float &v) + { + const Vector3 p = point - center; + u = ( M_PI + atan2(p.z, p.x) ) * invsize; + v = p.y * invsize; + }; +}; + +/** + * spherical mapping + */ +class SphereMap: public TextureMap +{ +public: + SphereMap(const Vector3 &acenter, const Float &size): + TextureMap(acenter, size) {}; + void map(const Vector3 &point, Float &u, Float &v) + { + const Vector3 p = point - center; + u = ( M_PI + atan2(p.z, p.x) ) * invsize; + v = acos(p.y / p.mag()) * invsize; + }; +}; + +/** + * general 2D texture + */ +class Texture2D: public Texture +{ +protected: + TextureMap *map; +public: + Texture2D(TextureMap *amap): map(amap) {}; +}; + +/** + * 2D checkers texture + */ +class CheckersTexture: public Texture2D +{ + ColourMap *colourmap; +public: + CheckersTexture(TextureMap *tmap, ColourMap *cmap): + Texture2D(tmap), colourmap(cmap) {}; + Colour evaluate(const Vector3 &point) + { + Float u,v, val; + map->map(point, u,v); + val = 0.5*(round(u - floor(u)) + round(v - floor(v))); + return colourmap->map(val); + }; +}; + +/** + * 3D perlin cloud texture + */ +class CloudTexture: public Texture +{ + Float detail; + ColourMap *colourmap; +public: + CloudTexture(const Float &adetail, ColourMap *cmap): + detail(adetail), colourmap(cmap) {}; + Colour evaluate(const Vector3 &point) + { + Float sum = 0.0; + for (int i = 1; i < detail; i++) + sum += fabs(perlin(point.x*i, point.y*i, point.z*i))/i; + //Float value = sinf(point.x + sum)/2 + 0.5; + return colourmap->map(sum); + }; +}; + +/** + * material + */ +class Material +{ +public: + Colour colour; + Texture *texture; + Float ambient, diffuse, specular, shininess; // Phong constants + Float reflectivity; // how much reflective is the surface + Float transmissivity, refract_index; // part of light which can be refracted; index of refraction + bool smooth; // triangle smoothing + + Material(const Colour &acolour): colour(acolour), texture(NULL), smooth(false) + { + ambient = 0.2; + diffuse = 0.8; + specular = 0.2; + shininess = 0.5; + reflectivity = 0.2; + transmissivity = 0.0; + refract_index = 1.3; + } + + void setPhong(const Float amb, const Float dif, const Float spec, const Float shin) + { ambient = amb; diffuse = dif; specular = spec; shininess = shin; }; + void setReflectivity(const Float refl) { reflectivity = refl; }; + void setTransmissivity(const Float trans, const Float rindex) + { transmissivity = trans; refract_index = rindex; }; + void setSmooth(bool sm) { smooth = sm; }; +}; + +#endif diff -r 9569e9f35374 -r 062b1c4143f7 include/noise.h --- a/include/noise.h Wed Apr 23 10:38:33 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * noise.h: noise generators - * - * This file is part of Pyrit Ray Tracer. - * - * Copyright 2006 Radek Brich - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef NOISE_H -#define NOISE_H - -#include "common.h" - -/** - * Perlin noise generator - */ -Float perlin(Float x, Float y, Float z); - -#endif diff -r 9569e9f35374 -r 062b1c4143f7 include/scene.h --- a/include/scene.h Wed Apr 23 10:38:33 2008 +0200 +++ b/include/scene.h Wed Apr 23 14:39:33 2008 +0200 @@ -81,22 +81,6 @@ }; /** - * axis-aligned bounding box - */ -class BBox -{ -public: - Vector3 L; - Vector3 H; - BBox(): L(), H() {}; - BBox(const Vector3 aL, const Vector3 aH): L(aL), H(aH) {}; - Float w() { return H.x-L.x; }; - Float h() { return H.y-L.y; }; - Float d() { return H.z-L.z; }; - bool intersect(const Ray &ray, Float &a, Float &b); -}; - -/** * light object */ class Light @@ -114,45 +98,19 @@ }; /** - * texture + * axis-aligned bounding box */ -class Texture -{ -public: - virtual ~Texture() {}; - virtual Colour evaluate(Vector3 point) = 0; -}; - -/** - * material - */ -class Material +class BBox { public: - Colour colour; - Texture *texture; - Float ambient, diffuse, specular, shininess; // Phong constants - Float reflectivity; // how much reflective is the surface - Float transmissivity, refract_index; // part of light which can be refracted; index of refraction - bool smooth; // triangle smoothing - - Material(const Colour &acolour): colour(acolour), texture(NULL), smooth(false) - { - ambient = 0.2; - diffuse = 0.8; - specular = 0.2; - shininess = 0.5; - reflectivity = 0.2; - transmissivity = 0.0; - refract_index = 1.3; - } - - void setPhong(const Float amb, const Float dif, const Float spec, const Float shin) - { ambient = amb; diffuse = dif; specular = spec; shininess = shin; }; - void setReflectivity(const Float refl) { reflectivity = refl; }; - void setTransmissivity(const Float trans, const Float rindex) - { transmissivity = trans; refract_index = rindex; }; - void setSmooth(bool sm) { smooth = sm; }; + Vector3 L; + Vector3 H; + BBox(): L(), H() {}; + BBox(const Vector3 aL, const Vector3 aH): L(aL), H(aH) {}; + Float w() { return H.x-L.x; }; + Float h() { return H.y-L.y; }; + Float d() { return H.z-L.z; }; + bool intersect(const Ray &ray, Float &a, Float &b); }; #endif diff -r 9569e9f35374 -r 062b1c4143f7 include/shapes.h --- a/include/shapes.h Wed Apr 23 10:38:33 2008 +0200 +++ b/include/shapes.h Wed Apr 23 14:39:33 2008 +0200 @@ -29,6 +29,7 @@ #include "common.h" #include "scene.h" +#include "material.h" /* triangle intersection alghoritm diff -r 9569e9f35374 -r 062b1c4143f7 src/SConscript --- a/src/SConscript Wed Apr 23 10:38:33 2008 +0200 +++ b/src/SConscript Wed Apr 23 14:39:33 2008 +0200 @@ -17,7 +17,7 @@ sources = [ 'raytracer.cc', 'scene.cc', 'shapes.cc', 'sampler.cc', - 'container.cc', 'kdtree.cc', 'octree.cc', 'noise.cc', + 'container.cc', 'kdtree.cc', 'octree.cc', 'material.cc', 'serialize.cc'] objs = [] diff -r 9569e9f35374 -r 062b1c4143f7 src/material.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/material.cc Wed Apr 23 14:39:33 2008 +0200 @@ -0,0 +1,108 @@ +/* + * material.cc: material and texture classes + * + * This file is part of Pyrit Ray Tracer. + * + * Copyright 2006, 2008 Radek Brich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "material.h" + +/** + * Perlin noise + * Based on JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE by KEN PERLIN (COPYRIGHT 2002) + */ + +Float fade(Float t) +{ + return t * t * t * (t * (t * 6 - 15) + 10); +} + +Float lerp(Float t, Float a, Float b) +{ + return a + t * (b - a); +} + +Float grad(unsigned char hash, Float x, Float y, Float z) +{ + unsigned char h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE + Float u = h<8 ? x : y, // INTO 12 GRADIENT DIRECTIONS. + v = h<4 ? y : h==12||h==14 ? x : z; + return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); +} + +const unsigned char p[512] = +{ + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 +}; + + +Float perlin(Float x, Float y, Float z) +{ + int X = (int)floor(x) & 255, + Y = (int)floor(y) & 255, + Z = (int)floor(z) & 255; + x -= floor(x); + y -= floor(y); + z -= floor(z); + Float u = fade(x), + v = fade(y), + w = fade(z); + int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z, + B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z; + + return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), + grad(p[BA ], x-1, y , z )), + lerp(u, grad(p[AB ], x , y-1, z ), + grad(p[BB ], x-1, y-1, z ))), + lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), + grad(p[BA+1], x-1, y , z-1 )), + lerp(u, grad(p[AB+1], x , y-1, z-1 ), + grad(p[BB+1], x-1, y-1, z-1 )))); +} diff -r 9569e9f35374 -r 062b1c4143f7 src/noise.cc --- a/src/noise.cc Wed Apr 23 10:38:33 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * noise.cc: noise generators - * - * This file is part of Pyrit Ray Tracer. - * - * Copyright 2006, 2008 Radek Brich - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "noise.h" - -/* -Perlin noise -Based on JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE by KEN PERLIN (COPYRIGHT 2002) -*/ - -Float fade(Float t) -{ - return t * t * t * (t * (t * 6 - 15) + 10); -} - -Float lerp(Float t, Float a, Float b) -{ - return a + t * (b - a); -} - -Float grad(unsigned char hash, Float x, Float y, Float z) -{ - unsigned char h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE - Float u = h<8 ? x : y, // INTO 12 GRADIENT DIRECTIONS. - v = h<4 ? y : h==12||h==14 ? x : z; - return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); -} - -const unsigned char p[512] = -{ - 151,160,137,91,90,15, - 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, - 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, - 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, - 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, - 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, - 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, - 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, - 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, - 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, - 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, - 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, - 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, - - 151,160,137,91,90,15, - 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, - 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, - 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, - 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, - 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, - 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, - 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, - 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, - 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, - 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, - 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, - 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 -}; - - -Float perlin(Float x, Float y, Float z) -{ - int X = (int)floor(x) & 255, - Y = (int)floor(y) & 255, - Z = (int)floor(z) & 255; - x -= floor(x); - y -= floor(y); - z -= floor(z); - Float u = fade(x), - v = fade(y), - w = fade(z); - int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z, - B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z; - - return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), - grad(p[BA ], x-1, y , z )), - lerp(u, grad(p[AB ], x , y-1, z ), - grad(p[BB ], x-1, y-1, z ))), - lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), - grad(p[BA+1], x-1, y , z-1 )), - lerp(u, grad(p[AB+1], x , y-1, z-1 ), - grad(p[BB+1], x-1, y-1, z-1 )))); -}