Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 CCL_NAMESPACE_BEGIN 00020 00021 /* Voronoi Distances */ 00022 00023 __device float voronoi_distance(NodeDistanceMetric distance_metric, float3 d, float e) 00024 { 00025 if(distance_metric == NODE_VORONOI_DISTANCE_SQUARED) 00026 return dot(d, d); 00027 if(distance_metric == NODE_VORONOI_ACTUAL_DISTANCE) 00028 return len(d); 00029 if(distance_metric == NODE_VORONOI_MANHATTAN) 00030 return fabsf(d.x) + fabsf(d.y) + fabsf(d.z); 00031 if(distance_metric == NODE_VORONOI_CHEBYCHEV) 00032 return fmaxf(fabsf(d.x), fmaxf(fabsf(d.y), fabsf(d.z))); 00033 if(distance_metric == NODE_VORONOI_MINKOVSKY_H) 00034 return sqrtf(fabsf(d.x)) + sqrtf(fabsf(d.y)) + sqrtf(fabsf(d.y)); 00035 if(distance_metric == NODE_VORONOI_MINKOVSKY_4) 00036 return sqrtf(sqrtf(dot(d*d, d*d))); 00037 if(distance_metric == NODE_VORONOI_MINKOVSKY) 00038 return powf(powf(fabsf(d.x), e) + powf(fabsf(d.y), e) + powf(fabsf(d.z), e), 1.0f/e); 00039 00040 return 0.0f; 00041 } 00042 00043 /* Voronoi / Worley like */ 00044 00045 __device_noinline void voronoi(float3 p, NodeDistanceMetric distance_metric, float e, float da[4], float3 pa[4]) 00046 { 00047 /* returns distances in da and point coords in pa */ 00048 int xx, yy, zz, xi, yi, zi; 00049 00050 xi = (int)floorf(p.x); 00051 yi = (int)floorf(p.y); 00052 zi = (int)floorf(p.z); 00053 00054 da[0] = 1e10f; 00055 da[1] = 1e10f; 00056 da[2] = 1e10f; 00057 da[3] = 1e10f; 00058 00059 pa[0] = make_float3(0.0f, 0.0f, 0.0f); 00060 pa[1] = make_float3(0.0f, 0.0f, 0.0f); 00061 pa[2] = make_float3(0.0f, 0.0f, 0.0f); 00062 pa[3] = make_float3(0.0f, 0.0f, 0.0f); 00063 00064 for(xx = xi-1; xx <= xi+1; xx++) { 00065 for(yy = yi-1; yy <= yi+1; yy++) { 00066 for(zz = zi-1; zz <= zi+1; zz++) { 00067 float3 ip = make_float3((float)xx, (float)yy, (float)zz); 00068 float3 vp = cellnoise_color(ip); 00069 float3 pd = p - (vp + ip); 00070 float d = voronoi_distance(distance_metric, pd, e); 00071 00072 vp += ip; 00073 00074 if(d < da[0]) { 00075 da[3] = da[2]; 00076 da[2] = da[1]; 00077 da[1] = da[0]; 00078 da[0] = d; 00079 00080 pa[3] = pa[2]; 00081 pa[2] = pa[1]; 00082 pa[1] = pa[0]; 00083 pa[0] = vp; 00084 } 00085 else if(d < da[1]) { 00086 da[3] = da[2]; 00087 da[2] = da[1]; 00088 da[1] = d; 00089 00090 pa[3] = pa[2]; 00091 pa[2] = pa[1]; 00092 pa[1] = vp; 00093 } 00094 else if(d < da[2]) { 00095 da[3] = da[2]; 00096 da[2] = d; 00097 00098 pa[3] = pa[2]; 00099 pa[2] = vp; 00100 } 00101 else if(d < da[3]) { 00102 da[3] = d; 00103 pa[3] = vp; 00104 } 00105 } 00106 } 00107 } 00108 } 00109 00110 __device float voronoi_Fn(float3 p, int n) 00111 { 00112 float da[4]; 00113 float3 pa[4]; 00114 00115 voronoi(p, NODE_VORONOI_DISTANCE_SQUARED, 0, da, pa); 00116 00117 return da[n]; 00118 } 00119 00120 __device float voronoi_FnFn(float3 p, int n1, int n2) 00121 { 00122 float da[4]; 00123 float3 pa[4]; 00124 00125 voronoi(p, NODE_VORONOI_DISTANCE_SQUARED, 0, da, pa); 00126 00127 return da[n2] - da[n1]; 00128 } 00129 00130 __device float voronoi_F1(float3 p) { return voronoi_Fn(p, 0); } 00131 __device float voronoi_F2(float3 p) { return voronoi_Fn(p, 1); } 00132 __device float voronoi_F3(float3 p) { return voronoi_Fn(p, 2); } 00133 __device float voronoi_F4(float3 p) { return voronoi_Fn(p, 3); } 00134 __device float voronoi_F1F2(float3 p) { return voronoi_FnFn(p, 0, 1); } 00135 00136 __device float voronoi_Cr(float3 p) 00137 { 00138 /* crackle type pattern, just a scale/clamp of F2-F1 */ 00139 float t = 10.0f*voronoi_F1F2(p); 00140 return (t > 1.0f)? 1.0f: t; 00141 } 00142 00143 __device float voronoi_F1S(float3 p) { return 2.0f*voronoi_F1(p) - 1.0f; } 00144 __device float voronoi_F2S(float3 p) { return 2.0f*voronoi_F2(p) - 1.0f; } 00145 __device float voronoi_F3S(float3 p) { return 2.0f*voronoi_F3(p) - 1.0f; } 00146 __device float voronoi_F4S(float3 p) { return 2.0f*voronoi_F4(p) - 1.0f; } 00147 __device float voronoi_F1F2S(float3 p) { return 2.0f*voronoi_F1F2(p) - 1.0f; } 00148 __device float voronoi_CrS(float3 p) { return 2.0f*voronoi_Cr(p) - 1.0f; } 00149 00150 /* Noise Bases */ 00151 00152 __device float noise_basis(float3 p, NodeNoiseBasis basis) 00153 { 00154 /* Only Perlin enabled for now, others break CUDA compile by making kernel 00155 too big, with compile using > 4GB, due to everything being inlined. */ 00156 00157 #if 0 00158 if(basis == NODE_NOISE_PERLIN) 00159 #endif 00160 return noise(p); 00161 #if 0 00162 if(basis == NODE_NOISE_VORONOI_F1) 00163 return voronoi_F1S(p); 00164 if(basis == NODE_NOISE_VORONOI_F2) 00165 return voronoi_F2S(p); 00166 if(basis == NODE_NOISE_VORONOI_F3) 00167 return voronoi_F3S(p); 00168 if(basis == NODE_NOISE_VORONOI_F4) 00169 return voronoi_F4S(p); 00170 if(basis == NODE_NOISE_VORONOI_F2_F1) 00171 return voronoi_F1F2S(p); 00172 if(basis == NODE_NOISE_VORONOI_CRACKLE) 00173 return voronoi_CrS(p); 00174 if(basis == NODE_NOISE_CELL_NOISE) 00175 return cellnoise(p); 00176 00177 return 0.0f; 00178 #endif 00179 } 00180 00181 /* Soft/Hard Noise */ 00182 00183 __device float noise_basis_hard(float3 p, NodeNoiseBasis basis, int hard) 00184 { 00185 float t = noise_basis(p, basis); 00186 return (hard)? fabsf(2.0f*t - 1.0f): t; 00187 } 00188 00189 /* Waves */ 00190 00191 __device float noise_wave(NodeWaveType wave, float a) 00192 { 00193 if(wave == NODE_WAVE_SINE) { 00194 return 0.5f + 0.5f*sin(a); 00195 } 00196 else if(wave == NODE_WAVE_SAW) { 00197 float b = 2.0f*M_PI_F; 00198 int n = (int)(a / b); 00199 a -= n*b; 00200 if(a < 0.0f) a += b; 00201 00202 return a / b; 00203 } 00204 else if(wave == NODE_WAVE_TRI) { 00205 float b = 2.0f*M_PI_F; 00206 float rmax = 1.0f; 00207 00208 return rmax - 2.0f*fabsf(floorf((a*(1.0f/b))+0.5f) - (a*(1.0f/b))); 00209 } 00210 00211 return 0.0f; 00212 } 00213 00214 /* Turbulence */ 00215 00216 __device_noinline float noise_turbulence(float3 p, NodeNoiseBasis basis, float octaves, int hard) 00217 { 00218 float fscale = 1.0f; 00219 float amp = 1.0f; 00220 float sum = 0.0f; 00221 int i, n; 00222 00223 octaves = clamp(octaves, 0.0f, 16.0f); 00224 n= (int)octaves; 00225 00226 for(i = 0; i <= n; i++) { 00227 float t = noise_basis(fscale*p, basis); 00228 00229 if(hard) 00230 t = fabsf(2.0f*t - 1.0f); 00231 00232 sum += t*amp; 00233 amp *= 0.5f; 00234 fscale *= 2.0f; 00235 } 00236 00237 float rmd = octaves - floor(octaves); 00238 00239 if(rmd != 0.0f) { 00240 float t = noise_basis(fscale*p, basis); 00241 00242 if(hard) 00243 t = fabsf(2.0f*t - 1.0f); 00244 00245 float sum2 = sum + t*amp; 00246 00247 sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); 00248 sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1)); 00249 00250 return (1.0f - rmd)*sum + rmd*sum2; 00251 } 00252 else { 00253 sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); 00254 return sum; 00255 } 00256 } 00257 00258 CCL_NAMESPACE_END 00259