OSL Noise Detail, Distortion


(drichter79) #1

Hi,

I am trying to animate a noise texture with OSL. It works nicely using the OSL template for noise by animating time variable.

However the Detail and Distortion settings/variables that the usual noise texture node offers seem to be missing.

Is there any way to implement them in OSL too?
Or maybe a workaround to get the same effect of more detailed noise

Attachments



(Secrop) #2

You can use the noise function from the original noise_texture node instead of using the osl builtin noise…


#include "stdosl.h"
#include "node_texture.h"

float noise(point p, float distortion, float detail, float fac, color Color)
{
    point r;
    int hard = 0;

    if (distortion != 0.0) {
        r[0] = safe_noise(p + point(13.5), "unsigned") * distortion;
        r[1] = safe_noise(p, "unsigned") * distortion;
        r[2] = safe_noise(p - point(13.5), "unsigned") * distortion;
        
        p += r;
    }

    fac = noise_turbulence(p, detail, hard);
    
    Color = color(fac, noise_turbulence(point(p[1], p[0], p[2]), detail, hard),
        noise_turbulence(point(p[1], p[2], p[0]), detail, hard));

    return fac;
}

shader node_noise_texture(
    float Distortion = 0.0,
    float Scale = 5.0,
    float Detail = 2.0,
    point Vector = P,
    output float Fac = 0.0,
    output color Color = 0.0)
{
    point p = Vector;

    Fac = noise(p * Scale, Distortion, Detail, Fac, Color);
}


(drichter79) #3

Interesting.

Any chance to implement the time factor there to keep the noise 4D?


(Secrop) #4

That may also be possible… you can check how OSL makes use of the w float in its build in noise function, and try to implement it in your noise…
The code is located here: https://github.com/imageworks/OpenShadingLanguage/blob/master/src/liboslnoise/simplexnoise.cpp
(check the simplexnoise4 function)

here’s an example (all i did was to propagate the t float all the way to the builtin noise functions (which accept 4 floats as coordinate)

float safe_noise(point p, float t, string type)
{
    float f = 0.0;
    
    /* Perlin noise in range -1..1 */
    if (type == "signed")
        f = noise("perlin", p, t);
    
    /* Perlin noise in range 0..1 */
    else
        f = noise(p, t);

    /* can happen for big coordinates, things even out to 0.5 then anyway */
    if (!isfinite(f))
        return 0.5;
    
    return f;
}

float noise_turbulence(point p, float t, float details, int hard)
{
    float fscale = 1.0;
    float amp = 1.0;
    float sum = 0.0;
    int i, n;
    
    float octaves = clamp(details, 0.0, 16.0);
    n = (int)octaves;

    for (i = 0; i <= n; i++) {
        float t = safe_noise(fscale * p, t, "unsigned");

        if (hard)
            t = fabs(2.0 * t - 1.0);

        sum += t * amp;
        amp *= 0.5;
        fscale *= 2.0;
    }
    
    float rmd = octaves - floor(octaves);

    if (rmd != 0.0) {
        float t = safe_noise(fscale * p, t,  "unsigned");

        if (hard)
            t = fabs(2.0 * t - 1.0);

        float sum2 = sum + t * amp;

        sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
        sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));

        return (1.0 - rmd) * sum + rmd * sum2;
    }
    else {
        sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
        return sum;
    }
}

float noise(point p, float t,float distortion, float detail, float fac, color Color)
{
    point r;
    int hard = 0;

    if (distortion != 0.0) {
        r[0] = safe_noise(p + point(13.5), t, "unsigned") * distortion;
        r[1] = safe_noise(p, t, "unsigned") * distortion;
        r[2] = safe_noise(p - point(13.5), t, "unsigned") * distortion;
        
        p += r;
    }

    fac = noise_turbulence(p, t,  detail, hard);
    
    Color = color(fac, noise_turbulence(point(p[1], p[0], p[2]), t, detail, hard),
        noise_turbulence(point(p[1], p[2], p[0]), t, detail, hard));

    return fac;
}

shader node_noise_texture(
    float Distortion = 0.0,
    float Scale = 5.0,
    float Detail = 2.0,
    point Vector = P,
    float Time=0,
    output float Fac = 0.0,
    output color Color = 0.0)
{
    point p = Vector;

    Fac = noise(p * Scale, Time, Distortion, Detail, Fac, Color);
}

(drichter79) #5

That works out great man, thanks!