/*
*
* Kind of Hot Lava Shader - Dave Hale
*
* Malcolm Kesson's Renderman 2
* Last Updated: May 20th, 2008
*
* Use sub-surface scattering point cloud data to control the incandescance
* and other various aspects of the shader. Use ambient occlusion point data
* to drive a dynamic wrinkle displacement for the "cool" crust edges of the lava.
* Essentially the lights will be controlling the "temperature" which will translate
* into which part of the layers it will display.
*
*/
surface dh_lava(
float bake = 0, // [ 1 or 0 ] bake toggle
Ks = 0.5, // specular brightness
Kd = 0.5, // diffuse brightness
Ka = 1, // ambient brightness
roughness = 0.1, // highlight spread
ssintensity = 3, // subsurface influence intensity
maskRampIntensity = -10,
looks_good = 0;
output varying float
magma_turbFreq = 1; // hot layer's turbulence frequency
float magma_turbCrinkle = 12, // crinkle amount
magma_turbDepth = 4,
magma_turbIntensity = 20, // intensity overdrive
crust_turbFreq = 1, // crust layer's turbulence frequency
crust_turbAmp = 1, // turbulence amplitude
crust_turbDepth = 3, // turbulence depth
crust_turbMag = 1.2, // turbulence magnitude
crust_noiseFreq = 7,
crust_noiseAmp = 1,
crust_noiseDepth = 4,
crust_noiseMag = 1;
string filename = "", // brickmap location
displaychannels = "_area,_radiance_t";
color diffusecolor = color (1),
specularcolor = color (1);
)
{
//---------------------------------------------
// Magma Layer
//---------------------------------------------
// initialize some variables
float a = area(P, "dicing"),
magma_turb = 0,
i;
normal Nn = normalize(N),
Nf;
color rad_t = 0,
ssdiffusion = 0,
direct;
vector V;
point PP = transform("object", P);
// pre-calculate values needed for color
direct = (Ka * ambient()) + (Kd * diffuse(Nn));
rad_t = diffusecolor * direct;
Nf = faceforward( normalize(N), I );
V = -normalize(I);
// generate some turbulent noise
for(i = 0; i < magma_turbDepth; i = i + 1)
{
magma_turb = magma_turb + abs(0.5 - noise(magma_turbCrinkle * magma_turbFreq * PP) ) / magma_turbFreq;
magma_turbFreq *= 1.2;
}
magma_turb *= magma_turbIntensity;
//---------------------------------------------
// Crust Layer
//---------------------------------------------
// turbulent noise
float j, f = crust_turbFreq, crust_turbAmp = 1;
float crust_turb = 0, crust_noise = 0;
point p = transform("object", P);
for(j = 0; j < crust_turbDepth; j += 1)
{
crust_turb += abs(noise(p * f) - 0.5) * crust_turbAmp;
f *= -2;
crust_turbAmp *= 0.5;
}
crust_turb *= crust_turbMag;
// fractal noise
float g, h = crust_noiseFreq, crust_noiseAmp = 1;
for(g = 0; g < crust_noiseDepth; g += 1) {
crust_noise += (noise(p * h) - 0.5) * crust_noiseAmp;
h *= 2;
crust_noiseAmp *= 0.5;
} crust_noise *= crust_noiseMag;
//---------------------------------------------
// Composite
//---------------------------------------------
/* if the bake toggle is on, bake it, otherwise, read in the
specified brickmap to add in, thanks to Chris Wilson */
if ((filename != "") && (displaychannels != ""))
{
if (bake == 1)
bake3d(filename, displaychannels, P, Nn, "interpolate", 1,
"_area", a, "_radiance_t", rad_t);
else
texture3d(filename, P, N, "_ssdiffusion", ssdiffusion);
}
/* Now that we have everything we need for our two color layers
let's go ahead and calculate them*/
color lavaColor = ( ssdiffusion * ssintensity ) * magma_turb;
color crustColor = ( ( diffusecolor * direct * crust_turb ) +
specularcolor * Ks * specular(Nf, V, roughness) );
/* Temporary mixing ramp, until I figure out how to have the sub-surface values
drives the mask properly */
color maskRamp = mix(color(1), color(maskRampIntensity), ssdiffusion),
mrHSV = ctransform("rgb", "hsv", maskRamp),
layeredColor = mix(lavaColor, crustColor, mrHSV[2]);
Ci = layeredColor * Os;
// Ci = mrHSV[2];
Oi = Os;
}