diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-01-10 02:06:03 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-01-10 02:06:03 +0400 |
commit | 8cf374d4012e193a50a58f1e2abcdae306ae33cd (patch) | |
tree | f808c24cb69591385f1a07eaebd82df9ffa0bb14 /intern | |
parent | ad10cbf04aed17c69ccd4e15921669d18ed987e1 (diff) |
Cycles: different fix for perlin noise generating nan values, now check for
the result to be finite afterwards which is a bit faster and works for OSL
too without needing to slow down OSL itself.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_musgrave_texture.osl | 24 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_texture.h | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_noise.h | 15 |
4 files changed, 42 insertions, 18 deletions
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 87a10e8bba7..6302031475a 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -238,7 +238,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, float min_ray_pdf = FLT_MAX; float ray_pdf = 0.0f; +#ifdef __LAMP_MIS__ float ray_t = 0.0f; +#endif PathState state; int rng_offset = PRNG_BASE_NUM; @@ -446,7 +448,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, /* set labels */ if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; +#ifdef __LAMP_MIS__ ray_t = 0.0f; +#endif min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); } @@ -484,7 +488,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer, float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) { +#ifdef __LAMP_MIS__ float ray_t = 0.0f; +#endif /* path iteration */ for(;; rng_offset += PRNG_BOUNCE_NUM) { @@ -655,7 +661,9 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray /* set labels */ if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; +#ifdef __LAMP_MIS__ ray_t = 0.0f; +#endif min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); } diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl index 541f26b4e56..38232ea0aeb 100644 --- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl +++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl @@ -37,14 +37,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float int i; for (i = 0; i < (int)octaves; i++) { - value += noise("perlin", p) * pwr; + value += safe_noise(p) * pwr; pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); if (rmd != 0.0) - value += rmd * noise("perlin", p) * pwr; + value += rmd * safe_noise(p) * pwr; return value; } @@ -65,14 +65,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar int i; for (i = 0; i < (int)octaves; i++) { - value *= (pwr * noise("perlin", p) + 1.0); + value *= (pwr * safe_noise(p) + 1.0); pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); if (rmd != 0.0) - value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */ + value *= (rmd * pwr * safe_noise(p) + 1.0); /* correct? */ return value; } @@ -93,11 +93,11 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna int i; /* first unscaled octave of function; later octaves are scaled */ - value = offset + noise("perlin", p); + value = offset + safe_noise(p); p *= lacunarity; for (i = 1; i < (int)octaves; i++) { - increment = (noise("perlin", p) + offset) * pwr * value; + increment = (safe_noise(p) + offset) * pwr * value; value += increment; pwr *= pwHL; p *= lacunarity; @@ -105,7 +105,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna rmd = octaves - floor(octaves); if (rmd != 0.0) { - increment = (noise("perlin", p) + offset) * pwr * value; + increment = (safe_noise(p) + offset) * pwr * value; value += rmd * increment; } @@ -128,7 +128,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float pwr = pwHL; int i; - result = noise("perlin", p) + offset; + result = safe_noise(p) + offset; weight = gain * result; p *= lacunarity; @@ -136,7 +136,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, if (weight > 1.0) weight = 1.0; - signal = (noise("perlin", p) + offset) * pwr; + signal = (safe_noise(p) + offset) * pwr; pwr *= pwHL; result += weight * signal; weight *= gain * signal; @@ -145,7 +145,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, rmd = octaves - floor(octaves); if (rmd != 0.0) - result += rmd * ((noise("perlin", p) + offset) * pwr); + result += rmd * ((safe_noise(p) + offset) * pwr); return result; } @@ -166,7 +166,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float pwr = pwHL; int i; - signal = offset - fabs(noise("perlin", p)); + signal = offset - fabs(safe_noise(p)); signal *= signal; result = signal; weight = 1.0; @@ -174,7 +174,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, for (i = 1; i < (int)octaves; i++) { p *= lacunarity; weight = clamp(signal * gain, 0.0, 1.0); - signal = offset - fabs(noise("perlin", p)); + signal = offset - fabs(safe_noise(p)); signal *= signal; signal *= weight; result += signal * pwr; diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h index 1b3ba8207ab..2de0fc0ea57 100644 --- a/intern/cycles/kernel/shaders/node_texture.h +++ b/intern/cycles/kernel/shaders/node_texture.h @@ -151,12 +151,23 @@ float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; } /* Noise Bases */ +float safe_noise(point p) +{ + float f = noise(p); + + /* can happen for big coordinates, things even out to 0.5 then anyway */ + if(!isfinite(f)) + return 0.5; + + return f; +} + float noise_basis(point p, string basis) { float result = 0.0; if (basis == "Perlin") - result = noise(p); /* returns perlin noise in range 0..1 */ + result = safe_noise(p); /* returns perlin noise in range 0..1 */ if (basis == "Voronoi F1") result = voronoi_F1S(p); if (basis == "Voronoi F2") diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h index 224a1d96543..5ead6486dd6 100644 --- a/intern/cycles/kernel/svm/svm_noise.h +++ b/intern/cycles/kernel/svm/svm_noise.h @@ -84,9 +84,8 @@ __device uint phash(int kx, int ky, int kz, int3 p) __device float floorfrac(float x, int* i) { - float f = floorf(x); - *i = (int)f; - return x - f; + *i = quick_floor(x); + return x - *i; } __device float fade(float t) @@ -133,7 +132,10 @@ __device_noinline float perlin(float x, float y, float z) grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )), nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ), grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f )))); - return scale3(result); + float r = scale3(result); + + /* can happen for big coordinates, things even out to 0.0 then anyway */ + return (isfinite(r))? r: 0.0f; } __device_noinline float perlin_periodic(float x, float y, float z, float3 pperiod) @@ -162,7 +164,10 @@ __device_noinline float perlin_periodic(float x, float y, float z, float3 pperio grad (phash (X+1, Y , Z+1, p), fx-1.0f, fy , fz-1.0f )), nerp (u, grad (phash (X , Y+1, Z+1, p), fx , fy-1.0f, fz-1.0f ), grad (phash (X+1, Y+1, Z+1, p), fx-1.0f, fy-1.0f, fz-1.0f )))); - return scale3(result); + float r = scale3(result); + + /* can happen for big coordinates, things even out to 0.0 then anyway */ + return (isfinite(r))? r: 0.0f; } /* perlin noise in range 0..1 */ |