I post the template of cloud here. Impossible to use in production, but good for learning to write shaders maybe.
slim 1 extensions zhangdb {
extensions zhang pxsl {
template shadingmodel cloud {
parameter float step {
default 0.5
}
parameter float radius {
detail uniform
description "Radius of the sphere to do ray marching."
default 1
}
parameter float frequency {
detail uniform
default 1
}
parameter float octaves {
detail uniform
subtype slider
range {1 6 1}
default 2
}
parameter float lacunarity {
detail uniform
default 2
}
parameter float gain {
detail uniform
subtype slider
range {0 1 0.001}
default 0.5
}
parameter float density {
label "cloud density"
detail uniform
default 0.5
}
parameter float dens {
label "shadow density"
detail uniform
default 4
}
parameter color cloudcolor {
label "cloud color"
detail uniform
default {1 0.9 0.675}
}
parameter color shdcolor {
label "shadow color"
detail uniform
default {0 0 0}
}
parameter color glowcolor {
label "glow color"
detail uniform
default {0 0.125 0.125}
}
collection shadingmodel shadingmodel {
access output
display hidden
parameter color CI {
detail varying
default "0 0 0"
access output
}
parameter color OI {
detail varying
default "0 0 0"
access output
}
}
RSLFunction {
#include "noises.h"
void
pxslcloud(
float step;
uniform float radius,freq,octaves,lacunarity,gain,K,Kshd;
uniform color cloudcolor,shadowcolor,glowcolor;
output color CI;
output color OI; )
{
float mindist(point q,p1,p2

{
vector p1toq = q - p1;
vector p1top2 = p2 - p1;
float ang = acos(normalize(p1toq).normalize(p1top2));
return length(p1toq)*sin(ang);
}
float spherehit(float radius;point center,Q; vector V)
{
vector qtoc = center - Q;
float toc = length(qtoc);
float dist = mindist( center, Q, Q+V);
float mid = sqrt(radius*radius - dist*dist);
float way = sqrt(toc*toc - dist*dist);
/*Calculate sphere ray hit length*/
float hit;
if(L.qtoc>0)
hit = mid + way;
else
hit = mid - way;
return max(hit,1.0e-6);
}
float get_density (point Psample; float stepsize,unitsize;uniform float frequency,octaves,lacunarity,gain

{
float density = 0.5+0.5*fBm(Psample/unitsize*frequency,stepsize/unitsize*frequency,octaves,lacunarity,gain);
density = pow ( clamp(density,0,1),3);
return density;
}
color get_lightcolor(point Q,center;float step;uniform float freq,radius,octaves,lacunarity,gain,scale;uniform color shadowcolor)
{
float shd=0;
color C=0;
illuminance(Q){
extern vector L;
extern color Cl;
if(L!=vector(0)){
vector Ln = normalize(L);
float dist = spherehit(radius,center,Q,Ln);
float i,cur_stepsize;
float num_of_steps = ceil(dist/step);
float Last_step = dist - (num_of_steps - 1) * step;
for(i=1;i<=num_of_steps;i+=1){
if(i!=num_of_steps)
cur_stepsize = step;
else
cur_stepsize = Last_step;
point Psamp = Q + i*cur_stepsize*Ln;
/*calculate volume density*/
point pp = transform ("world",Psamp);
float density = get_density (pp,cur_stepsize,radius*2,freq,octaves,lacunarity, gain);
/*calculate volume self-shadow*/
shd+=cur_stepsize*density*scale;
if(shd>1){
shd = 1;
i = num_of_steps+1;
}
}
}
C+=mix(Cl,shadowcolor,shd);
}
return C;
}
extern point P;
extern normal N;
extern vector I;
normal Nn = normalize(N);
vector V = normalize (I);
float dot = V.(-Nn);
/*center of the sphere*/
point origin = P - Nn*radius;
/*calculate ray march length*/
float volume_distance = dot*2*radius;
float stepsize = max(0.005,step);
point Psamp;
float opacity = 0;
color c = 0;
float light_intensity=1;
color light_color;
float start = step*(random()-0.5);
float num_of_steps,Last_stepsize,cur_stepsize;
if(N.I<0) {
num_of_steps = ceil(volume_distance/stepsize);
Last_stepsize = volume_distance - (num_of_steps - 1) * stepsize;
float i;
for (i = 1; i <=num_of_steps; i+= 1)
{
if(i!=num_of_steps)
cur_stepsize = stepsize;
else
cur_stepsize = Last_stepsize;
Psamp = P + i*cur_stepsize*V;
/*calculate volume density*/
point pp = transform ("world",Psamp);
float density = get_density (pp,stepsize,radius*2,freq,octaves,lacunarity,gain );
density*= abs(pow(dot,3.91));
/*calculate light intensity*/
light_color = get_lightcolor(Psamp,origin,stepsize,freq,radius,o ctaves,lacunarity,gain,Kshd,shadowcolor);
/*composite sample point*/
opacity+= cur_stepsize*density*K;
c+= cur_stepsize*K*density*(light_color*cloudcolor+glo wcolor);
if(opacity>1){
opacity = 1;
i = num_of_steps+1;
}
}
}
OI = opacity;
CI = c;
}
}
}
}
}