slim 1 extensions cutter {
extensions fundza cutr {
template multiple PaperCup {
description {Connect "output->ridges" to the "float displacement" input of GPSurface.<BR>
Use "output->mask" and a ColorMix node to control the coloration of a<BR>
cylinder that is used to model a paper cup.}
previewinfo {
shadingrate 1
objectsize 1
objectshape Cylinder
frame 1
}
parameter float context {
label "Rendering Context"
description { }
subtype selector
range {"Automatic" 0 "Maya Final" 1 "Preview" 2}
default 0
}
parameter float cup_height {
description "Set this to attenuate the output->ridges - zero at the base,
maximum at the top of the cup."
label {Cup Height}
detail varying
default 1.5
subtype slider
range {0 5}
}
parameter float freq {
description "Number of ridges around the cup's circumference."
label {Number of Ridges}
detail varying
default 30
subtype slider
range {1 40 2}
}
parameter float atten_upper {
description "The height above the base where ridges will be fully formed."
label "Ridge Max"
detail varying
default 0.2
subtype slider
range {0 2}
}
parameter float atten_lower {
description "The height above the base where ridges are \"flattened\"."
label "Ridge Min"
detail varying
default 0.05
subtype slider
range {0 2}
}
parameter float atten_ridges {
label "Attenuate Ridges"
description "Use this if the cup height has been set accurately."
subtype switch
range {0 1}
provider variable
default 1
}
parameter float ridge_sharpness {
description "Controls the curvature of the ridges."
label {Ridge Sharpness}
detail varying
default 0
subtype slider
range {0 1}
}
parameter float ridge_distortion_src {
description "Connect to a Noise or Turbulance node to vary the ridges."
label {Ridge Distortion Input}
detail varying
default 0
subtype slider
range {0 1}
}
parameter float ridge_distortion_scale {
description "A scaling factor for the distortion."
label {Ridge Distortion Scale}
detail varying
default 0
subtype slider
range {0 1}
}
collection void label {
state closed
drawmode all
label {Masks}
description "Use these to control color mixing and vertical attenuation
of the displacement of the ridges of the paper cup."
parameter float mask_amp {
description {Controls the height of mask.}
label {Mask Amplitude}
detail varying
default 0.25
subtype slider
range {0 1}
}
parameter float mask_offset {
description "Controls the vertical position of the mask."
label {Mask Vertical Offset}
detail varying
default 0.75
subtype slider
range {0 1}
}
parameter float invert_mask {
label "Invert Mask"
description "Switch the black and white areas of the mask."
subtype switch
range {0.0 1.0}
default 1
}
}
parameter float ridges {
access output
display hidden
}
parameter float mask {
access output
display hidden
}
RSLFunction {
void
cutrPaperCup (
float context;
float cup_height;
float freq;
float atten_upper;
float atten_lower;
float atten_ridges;
float ridge_sharpness;
float ridge_distortion_src;
float ridge_distortion_scale;
float mask_amp;
float mask_offset;
float invert_mask;
output float ridges;
output float mask;
)
{
point p = transform("object", P);
float x = p[0], y = 0, z = 0;
float obj_height = cup_height; // Assume the user has set the true height of
// the maya paper cup.
float obj_depth = 0.0; // Paper cup level with the Maya X-Z plane.
// The "it" preview uses a cylinder aligned to the 'z' axis. It also has
// a negative depth of 0.45 and a height of 0.45. The paper cup in the Maya
// scene, on the other hand, will have a depth of 0.0 and a height of
// approximately 1.5. Because our calculations are based on "object"
// dimensions we must take the "rendering context" into account when
// determining what should be considered to be the Y axis - either the true
// Y axis (Maya) or the Z axis (preview).
float axis, preview;
if(context == 0) {
if(option("user:PreviewRender", preview))
axis = 2; // "preview"
else
axis = 1; // "maya"
}
else
axis = context;
if(axis == 1) { // direct maya render
y = p[1];
z = p[2];
}
else // "preview" render
{
y = p[2];
z = p[1];
obj_depth = -0.45;
obj_height = 0.45;
}
// Some irregularity is added to the angle theta is so the ridges of the
// paper cup will appear slightly uneven.
// Note: atan() returns values in the range -PI to +PI.
float theta = atan(x,z) + ridge_distortion_src * ridge_distortion_scale;
ridges = sin(theta * freq);
float i, harmonics = ridge_sharpness * 10;
// The loop sharpens the ridges of the cup (thanks Aki).
for (i = 1.0; i < harmonics; i+=1.0) {
float h = i * 2.0 + 1.0;
float wave = sin(theta * freq * h)/pow(h,2.0);
if (mod(i,2.0) == 0.0)
ridges += wave;
else
ridges -= wave;
}
// To compensate for any "sharpening" of the ridges a value slightly
// greater than 1.0 should be added.
ridges += 1;
// Apply a ramp so the ridges so the displacement produced by GPSurface
// reduces to zero at the base of the paper cup..
if(atten_ridges)
ridges *= smoothstep(atten_lower, atten_upper, y);
// Remap the y position of the shading point to the range 0 to 1.0
y = y/obj_height;
// Remap the y position of the shading point to the range 0 to 1.
float vert_offset = (axis == 2) ? 1 - mask_offset : mask_offset;
mask = (ridges + 2) * smoothstep(vert_offset, vert_offset + mask_amp, y);
mask = smoothstep(0.0, 0.85, mask);
if(invert_mask == 1)
mask = 1 - mask;
if(axis == 2)
mask = 1 - mask;
}
} } } }