displacements and message passing in renderman
|
Basic Idea:
|
|
Fractal noise:
|
float fnc_fractal (
point P_turb;
float ampl_scale;
float freq_scale;
float amp;
float freq;
float octaves;
)
{
float a = amp,
f = freq,
i;
#define snoise(P) ((noise(P)-0.33)*amp)
varying float turb = 0;
for ( i= 1; i <= octaves; i += 1){
turb += a * snoise(P_turb*f);
a /= ampl_scale;
f *= freq_scale;
}
return turb;
}
point PP = transform("object",P); /* put noise in object space. */
hump = fnc_fractal(PP, Amp_scale, Freq_scale, amplitude, Frequency, Octaves);
|
Controling the noise:
|
vector Nn = normalize(N);
point PP = transform("object",P); /* put noise in object space. */
hump = fnc_fractal(PP, Amp_scale, Freq_scale, amplitude, Frequency, Octaves);
grasshump = fnc_fractal(PP, Grass_Amp_scale, Grass_Freq_scale, Grass_amplitude, Grass_Frequency, Grass_Octaves);
snowhump = fnc_fractal(PP, Snow_Amp_scale, Snow_Freq_scale, Snow_amplitude, Snow_Frequency, Snow_Octaves);
// These bump values are clamped to not go into the ocean
newbump = clamp(hump,ocean_height,1);
float newgrassbump = clamp(grasshump,ocean_height,1);
float newsnowhump = clamp(snowhump,ocean_height,1);
//Put them Together
P = P + Nn * (newgrassbump * Grass_amplitude)
* (newbump * amplitude)
* (newsnowhump * Snow_amplitude)
;
N = calculatenormal(P);
//Output these to be used by the surface shader for lighting + layering reasons.
Ocean_Height = ocean_height;
Grass_Height = grasshump;
|
Adding color based on displacement to surface shader:
|
float height = 0;
float mountain_offset = 0;
float mountain_height = Mountain_ht; /* note: noise is mostly btwn .3 and .8 */
/* Check for "Ocean_Offset" in displacement shader, and if it does, put it in mountain_offset and execute if statement */
if(displacement("Ocean_Height", mountain_offset) == 0.5)
{
mountain_height += mountain_offset;
}
color surfcolor = ocean_color;
if(displacement("hump", height) == 1)
{
float blend = smoothstep(mountain_height-0.1,mountain_height+0.1,height);
surfcolor += mix(ocean_color,mountain_color,blend);
}
|
Adding grass:
|
float grass_offset = 0;
float grass_height = Grass_ht;
/* Check for "Ocean_Offset" in displacement shader, and if it does, put it in grass_offset and execute if statement */
if(displacement("Ocean_Height", grass_offset) == 0.5)
{
grass_height += grass_offset;
}
/*** Same, but with grass and snow ***/
if(displacement("grasshump", height) == 1)
{
if(displacement("hump", height) == 1)
{
float grass_blend = smoothstep(grass_height+0.05,grass_height-0.05,height);
surfcolor += mix(grass_color, mountain_color, grass_blend);
}
}
|
Adding snow:
|
float snow_offset = 0;
float snow_height = Snow_ht;
/* Check for "Grass_Height" in displacement shader, and if it does, put it in snow_offset and execute if statement */
if(displacement("Grass_Height", snow_offset) == 0.5)
{
snow_height += snow_offset;
}
color snow_spec = 1;
if(displacement("snowhump", height) == 1)
{
if(displacement("hump", height) == 1)
{
float snow_blend = smoothstep(snow_height+0.03,snow_height-0.03,height);
surfcolor += mix(mountain_color, snow_color, snow_blend);
}
}
|
Adding specularity:
|
/* Initialize a specular highlight, this will be subtracted at the end of bump equations
to give a specular ocean */
ocean_spec = Specular_color * Ks * glossy_specular(Nf,Vo,roughness, glossiness);
color snow_spec = 1;
if(displacement("snowhump", height) == 1)
{
if(displacement("hump", height) == 1)
{
float snow_blend = smoothstep(snow_height+0.03,snow_height-0.03,height);
surfcolor += mix(mountain_color, snow_color, snow_blend);
/* Add a snow specular */
snow_spec = snow_blend * (Specular_color * Ks * glossy_specular(Nf,Vo,roughness, glossiness));
/* Subtract back the ocean specular based on total bumpiness above the ocean */
float ocean_blend = smoothstep(mountain_height-0.1,mountain_height+0.1,height);
ocean_spec -= ocean_blend * (Specular_color * Ks * glossy_specular(Nf,Vo,roughness, glossiness));
}
}
color diffusecolor = Kd * diffuse(nf);
Ci = Oi * Cs * diffusecolor * surfcolor
+ ocean_spec
+ snow_spec;
|
Clouds!
|
point PP = transform("object",P);
//It's messy, but the rim is being multiplied by a cloud noise that is being cut into by another noise.
Oi = (my_cloud_rim(Nf, Vo, opacity_rim_width) * opacity_rim_strength)
* (opacity * fnc_fractal(PP, Noise2_Amp_scale, Noise2_Freq_scale, Noise2_amplitude, Noise2_Frequency, Noise2_Octaves))
* fnc_fractal(PP, Amp_scale, Freq_scale, amplitude, Frequency, Octaves);
Ci = Oi * Cloud_color;
|
Lava Planet |
|
Rocky, Cold Planet |
|
Polluted Planet |
|
Flat, Dusty Alien World |
|
| Conclusion:
|
|