Cycles: different fix for perlin noise generating nan values, now check for
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 9 Jan 2013 22:06:03 +0000 (22:06 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 9 Jan 2013 22:06:03 +0000 (22:06 +0000)
the result to be finite afterwards which is a bit faster and works for OSL
too without needing to slow down OSL itself.

intern/cycles/kernel/kernel_path.h
intern/cycles/kernel/shaders/node_musgrave_texture.osl
intern/cycles/kernel/shaders/node_texture.h
intern/cycles/kernel/svm/svm_noise.h

index 87a10e8bba7557edfb5e3e545ffb0b667910c9cc..6302031475ab4b18ed71871f7a99f681359b4636 100644 (file)
@@ -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);
                }
 
index 541f26b4e568ec8794636759af442e612d447bce..38232ea0aeb09c41e65a82a9176087722ad224d4 100644 (file)
@@ -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;
index 1b3ba8207ab2e24115cce78e72d6c8d61745fa84..2de0fc0ea57364084f0f5673e3714f24e58c5ef6 100644 (file)
@@ -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")
index 224a1d96543be3e94187c6b9d6c9022a2126ae1f..5ead6486dd6b92ad36ff64917c7b0f84b913b675 100644 (file)
@@ -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 */