Blender V2.61 - r43446

svm_noise.h

Go to the documentation of this file.
00001 /*
00002  * Adapted from Open Shading Language with this license:
00003  *
00004  * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
00005  * All Rights Reserved.
00006  *
00007  * Modifications Copyright 2011, Blender Foundation.
00008  * 
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are
00011  * met:
00012  * * Redistributions of source code must retain the above copyright
00013  *   notice, this list of conditions and the following disclaimer.
00014  * * Redistributions in binary form must reproduce the above copyright
00015  *   notice, this list of conditions and the following disclaimer in the
00016  *   documentation and/or other materials provided with the distribution.
00017  * * Neither the name of Sony Pictures Imageworks nor the names of its
00018  *   contributors may be used to endorse or promote products derived from
00019  *   this software without specific prior written permission.
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00023  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00024  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00026  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00027  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00028  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00030  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 */
00032 
00033 CCL_NAMESPACE_BEGIN
00034 
00035 __device int quick_floor(float x)
00036 {
00037     return (int)x - ((x < 0) ? 1 : 0);
00038 }
00039 
00040 __device float bits_to_01(uint bits)
00041 {
00042     return bits * (1.0f/(float)0xFFFFFFFF);
00043 }
00044 
00045 __device uint hash(uint kx, uint ky, uint kz)
00046 {
00047     // define some handy macros
00048 #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
00049 #define final(a,b,c) \
00050 { \
00051     c ^= b; c -= rot(b,14); \
00052     a ^= c; a -= rot(c,11); \
00053     b ^= a; b -= rot(a,25); \
00054     c ^= b; c -= rot(b,16); \
00055     a ^= c; a -= rot(c,4);  \
00056     b ^= a; b -= rot(a,14); \
00057     c ^= b; c -= rot(b,24); \
00058 }
00059     // now hash the data!
00060     uint a, b, c, len = 3;
00061     a = b = c = 0xdeadbeef + (len << 2) + 13;
00062 
00063     c += kz;
00064     b += ky;
00065     a += kx;
00066     final(a, b, c);
00067 
00068     return c;
00069     // macros not needed anymore
00070 #undef rot
00071 #undef final
00072 }
00073 
00074 __device int imod(int a, int b)
00075 {
00076     a %= b;
00077     return a < 0 ? a + b : a;
00078 }
00079 
00080 __device uint phash(int kx, int ky, int kz, int3 p) 
00081 {
00082     return hash(imod(kx, p.x), imod(ky, p.y), imod(kz, p.z));
00083 }
00084 
00085 __device float floorfrac(float x, int* i)
00086 {
00087     *i = quick_floor(x);
00088     return x - *i;
00089 }
00090 
00091 __device float fade(float t)
00092 {
00093     return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
00094 }
00095 
00096 __device float nerp(float t, float a, float b)
00097 {
00098     return (1.0f - t) * a + t * b;
00099 }
00100 
00101 __device float grad(int hash, float x, float y, float z)
00102 {
00103     // use vectors pointing to the edges of the cube
00104     int h = hash & 15;
00105     float u = h<8 ? x : y;
00106     float v = h<4 ? y : h==12||h==14 ? x : z;
00107     return ((h&1) ? -u : u) + ((h&2) ? -v : v);
00108 }
00109 
00110 __device float scale3(float result)
00111 {
00112     return 0.9820f * result;
00113 }
00114 
00115 __device_noinline float perlin(float x, float y, float z)
00116 {
00117     int X; float fx = floorfrac(x, &X);
00118     int Y; float fy = floorfrac(y, &Y);
00119     int Z; float fz = floorfrac(z, &Z);
00120 
00121     float u = fade(fx);
00122     float v = fade(fy);
00123     float w = fade(fz);
00124 
00125     float result;
00126 
00127     result = nerp (w, nerp (v, nerp (u, grad (hash (X  , Y  , Z  ), fx   , fy    , fz     ),
00128                                         grad (hash (X+1, Y  , Z  ), fx-1.0f, fy  , fz     )),
00129                                nerp (u, grad (hash (X  , Y+1, Z  ), fx   , fy-1.0f, fz    ),
00130                                         grad (hash (X+1, Y+1, Z  ), fx-1.0f, fy-1.0f, fz      ))),
00131                       nerp (v, nerp (u, grad (hash (X  , Y  , Z+1), fx   , fy    , fz-1.0f ),
00132                                         grad (hash (X+1, Y  , Z+1), fx-1.0f, fy  , fz-1.0f )),
00133                                nerp (u, grad (hash (X  , Y+1, Z+1), fx   , fy-1.0f, fz-1.0f ),
00134                                         grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f ))));
00135     return scale3(result);
00136 }
00137 
00138 __device_noinline float perlin_periodic(float x, float y, float z, float3 pperiod)
00139 {
00140     int X; float fx = floorfrac(x, &X);
00141     int Y; float fy = floorfrac(y, &Y);
00142     int Z; float fz = floorfrac(z, &Z);
00143 
00144     int3 p;
00145 
00146     p.x = max(quick_floor(pperiod.x), 1);
00147     p.y = max(quick_floor(pperiod.y), 1);
00148     p.z = max(quick_floor(pperiod.z), 1);
00149 
00150     float u = fade(fx);
00151     float v = fade(fy);
00152     float w = fade(fz);
00153 
00154     float result;
00155 
00156     result = nerp (w, nerp (v, nerp (u, grad (phash (X  , Y  , Z  , p), fx   , fy    , fz     ),
00157                                         grad (phash (X+1, Y  , Z  , p), fx-1.0f, fy  , fz     )),
00158                                nerp (u, grad (phash (X  , Y+1, Z  , p), fx   , fy-1.0f, fz    ),
00159                                         grad (phash (X+1, Y+1, Z  , p), fx-1.0f, fy-1.0f, fz      ))),
00160                       nerp (v, nerp (u, grad (phash (X  , Y  , Z+1, p), fx   , fy    , fz-1.0f ),
00161                                         grad (phash (X+1, Y  , Z+1, p), fx-1.0f, fy  , fz-1.0f )),
00162                                nerp (u, grad (phash (X  , Y+1, Z+1, p), fx   , fy-1.0f, fz-1.0f ),
00163                                         grad (phash (X+1, Y+1, Z+1, p), fx-1.0f, fy-1.0f, fz-1.0f ))));
00164     return scale3(result);
00165 }
00166 
00167 /* perlin noise in range 0..1 */
00168 __device float noise(float3 p)
00169 {
00170     float r = perlin(p.x, p.y, p.z);
00171     return 0.5f*r + 0.5f;
00172 }
00173 
00174 /* perlin noise in range -1..1 */
00175 __device float snoise(float3 p)
00176 {
00177     return perlin(p.x, p.y, p.z);
00178 }
00179 
00180 /* cell noise */
00181 __device_noinline float cellnoise(float3 p)
00182 {
00183     uint ix = quick_floor(p.x);
00184     uint iy = quick_floor(p.y);
00185     uint iz = quick_floor(p.z);
00186 
00187     return bits_to_01(hash(ix, iy, iz));
00188 }
00189 
00190 __device float3 cellnoise_color(float3 p)
00191 {
00192     float r = cellnoise(p);
00193     float g = cellnoise(make_float3(p.y, p.x, p.z));
00194     float b = cellnoise(make_float3(p.y, p.z, p.x));
00195 
00196     return make_float3(r, g, b);
00197 }
00198 
00199 /* periodic perlin noise in range 0..1 */
00200 __device float pnoise(float3 p, float3 pperiod)
00201 {
00202     float r = perlin_periodic(p.x, p.y, p.z, pperiod);
00203     return 0.5f*r + 0.5f;
00204 }
00205 
00206 /* periodic perlin noise in range -1..1 */
00207 __device float psnoise(float3 p, float3 pperiod)
00208 {
00209     return perlin_periodic(p.x, p.y, p.z, pperiod);
00210 }
00211 
00212 CCL_NAMESPACE_END
00213