Puffy Clouds

Ported KMPuffyClouds from RSL. Had so trouble with the smoothstep function, so I had to add stand-in floats for it to work (weird imo, but I don’t know programming, so maybe that’s normal to you). Apart from that, it was very straight forward.


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

float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float octaves)
{
    float rmd;
    float value = 0.0;
    float pwr = 1;
    float pwHL = pow(lacunarity, -H);
    int i;


    for (i = 0; i < (int)octaves; i++) {
        value += noise("perlin", p) * pwr;
        pwr *= pwHL;
        p *= lacunarity;
    }


    rmd = octaves - floor(octaves);
    if (rmd != 0.0)
        value += rmd * noise("perlin", p) * pwr;


    return value;
}


shader node_musgrave_texture(
    color Sky = color(.15, .15, .6),
    color Clouds = 1,
    int use_mapping = 0,
    matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    string Type = "fBM",
    float Threshold = .25,
    float Dimension = .5,
    float Lacunarity = 2.0,
    float Detail = 8.0,
    float Scale = 5.0,
    point Vector = P,
    output float Fac = 0.0,
    output color Color = color(0.0, 0.0, 0.0))
{
    float threshold = clamp(Threshold, 0, 1);
    float dimension = max(Dimension, 1e-5);
    float octaves = clamp(Detail, 0.0, 16.0);
    float lacunarity = max(Lacunarity, 1e-5);
    string Basis = "Perlin";


    point p = Vector;


    if (use_mapping)
        p = transform(mapping, p);


    p = p * Scale;


        Fac = noise_musgrave_fBm(p, Basis, dimension, lacunarity, octaves);
    float Condition = Fac;
    float Mu = smoothstep(Threshold, 1, Condition);
    Color = mix(Sky, Clouds, Mu);
}



It’s great, works like a charm and blends well with skies, congrats! Didn’t try with hdr environment, did you?

https://dl.dropboxusercontent.com/u/58007699/Blog%20images/RecentBlender/OSL_puffy-Clouds_script.png

Thanks. I didn’t try that… After wrestling with the coding, I didn’t really want to think about the shader for a while. But your render looks awesome!

Dude this is extremely useful. Thanks so much.

@dolemite You’re very welcome.
I wrote another script (that doesn’t really deserve it’s own thread). Although it’s pretty simple, it could be very useful. It’s similar in function to the Fresnel node, but (imo) it’s way easier to tweak in order to get different effects. I hope to make a lightsaber shader from it that won’t need to be blurred in the compositor.
If anyone finds some cool implementations of the code, please post so I, and anyone for that matter, can see it.



shader super_fresnel(
int Function = 1, /* 1 uses a third degree polynomial function; 2, a 5 polynomial one */
float Threshold = 0.8, /* Lower voundary of mix */
float Ceiling = 0.9, /* Uppr boundary of mix */
vector Vector1 = N, /* Normal at the point */
vector Vector2 = I, /* Vector from camera to point */
output float Fac = 0.0
)
{
float mu = 1 - (dot(Vector1, Vector2)/(length(Vector1) * length(Vector2)));
/* ^ Normalized dot product of vectors. Values flippd accros .5 */
float ep = smoothstep(Threshold, Ceiling, mu);
/* ^ Third degree function (built in) */
float x = clamp((mu - Threshold)/(Ceiling - Threshold), 0, 1);
float la = x*x*x*(x*(x*6 - 15) + 10);
/* Fifth degree function */
if (Function <= 1)
    Fac = mix(0, 1, ep);
if (Function >= 2)
    Fac = la;
}

Third degree:


Fifth degree:


I didn’t realise that you couldn’t easily apply clouds to the background… is there any density variation towards the horizon? That is as you look across the atmosphere clouds usually stack up differently than straight up.

Seriously love the clouds osl, first thing I did was attach to background shader. I can see a million different ways to add to its complexity.

@3pointEdit I don’t know, but I’ll start brainstorming. It might be possible using some vectors…
@sundiego47 Thanks. There are a ton of rsl shaders out there that should be easily portable. Check them out.

Finally had a chance to play with osl some. I stole what you had and added some so I could have a cloud that flowed into the horizon.


I didn’t change it much but check it out. Here is my node setup too.


#include “stdosl.h”
#include “node_texture.h”

float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float octaves)
{
float rmd;
float value = 0.0;
float pwr = 1;
float pwHL = pow(lacunarity, -H);
int i;

for (i = 0; i < (int)octaves; i++) {
    value += noise("perlin", p) * pwr;
    pwr *= pwHL;
    p *= lacunarity;
}


rmd = octaves - floor(octaves);
if (rmd != 0.0)
    value += rmd * noise("perlin", p) * pwr;


return value;

}

shader node_musgrave_texture(
color Sky = color(.15, .15, .6),
color GroundColor = color(0.0, 0.0, 0.0),
color Clouds = 1,
int use_mapping = 0,
matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
string Type = “fBM”,
float Threshold = .25,
float Dimension = .5,
float Lacunarity = 2.0,
float Detail = 8.0,
float Scale = 5.0,
point Vector = P,
float HorizonScale = 1.0,
float HorizonOffset = 0.0,
int Mirror = 1 // 1 = Yes 0 = NO
[[ string widget = “checkBox”]],
output float Fac = 0.0,
output float HorizonFac = 0.0,
output color Color = color(0.0, 0.0, 0.0))
{
float threshold = clamp(Threshold, 0, 1);
float dimension = max(Dimension, 1e-5);
float octaves = clamp(Detail, 0.0, 16.0);
float lacunarity = max(Lacunarity, 1e-5);
string Basis = “Perlin”;

point p = Vector;


if (use_mapping)
    p = transform(mapping, p);

// float angle_intern = 0;

//angle_intern = atan2(p[0],p[1]) + Angle*3.1415926/180.0;

p = p * Scale ;

P[2] = P[2] - HorizonOffset;

// p[1] = sqrt(P[0] * P[0] + P[1] * P[1]) * (1/ (P[2] * 100) );
p[2] = 1 / P[2] ;

    Fac = noise_musgrave_fBm(p, Basis, dimension, lacunarity, octaves);
    
    float cloudFac = 1 - (1 - HorizonScale / abs ( P[2] ));
float Condition = Fac;
float Mu = smoothstep(Threshold, 1, Condition) * cloudFac;



if(P[2] > 0 || Mirror == 1) {
    Color = mix(Sky, Clouds, Mu);
    HorizonFac = cloudFac;
} else {
    Color = GroundColor;
    Fac = 1;
    HorizonFac =  1; 
}

Fac = HorizonFac;

}