|
Reference Images
|
|
|
|
First, the gradient between the blue base of the flame and the white body was set up.
|
|
color basecolor = mix(white, blue, smoothstep(blue_height -
blue_deviation, blue_height, tt));
This function sets that base color of the flame, over which
the other colors will be added, and is keyed to the
following artist inputs: blue_height, a float that
establishes where the transition is between the blue
and white parts of the flame, blue_deviation, a float
that establishes how large the smoothstep transition
from blue to white should be; and the color inputs
white and blue, which establish the colors for the upper
and lower portions of the flame.
|
|
Then, a yellow tint around the edges.
|
|
float yellow_edge = (1 - smoothstep (blue_height -
blue_deviation, blue_height, tt)) * smoothstep (1 -
yellow_edge_width, 1.0, 1 - i.nf);
This function outputs a float value to be used when mixing
the yellow tint with the previously established color.
It uses the blue_height and blue_height_deviation artist
inputs, as well as the yellow_edge_width float, which
adjusts how far into the white portion of the flame the
yellow tint extends.
color yellowedge = mix(basecolor, yellow, yellow_edge);
This takes the yellow_edge float value, and uses it to mix
the tint into the surface's color.
|
|
Next, the transparancy is achived using angle of incidence and a smoothstep.
|
|
float dot = 1 - smoothstep (blue_height - blue_deviation,
blue_height, tt) + (1 - i.nf);
This function is keyed to the same float inputs as the first
color function so that it matches the location of the
color gradient automatically.
Oi = smoothstep (1 - rim_width, 1.0, dot) / transparancy_factor;
This function takes the float value from the above function and
sets it as the Oi transparancy value. The function also
makes use of the rim_width float value to adjust the
thickness of the opaque areas at the edge of the flame's
base. It includes an extra float variable (transparancy_factor)
to allow the artist to tweak the effect a bit.
|
|
I attempted to achieve an elegant solution by combining the surface and displacement functions into a single shader, which caused problems later.
|
|
The displacement function's noise input was added next.
|
|
dispvalue = noise(transform(spacename, P) * frequency) +
displacement_magnitude_adjustment;
This function is keyed to two artist inputs; frequency,
which adjusts the frequency of the noise, as the
name implies, and displacement_magnitude_adjustment,
which is a value added to the noise output to make
the displacement larger or smaller. There is also
a world space input, spacename, which can be linked
to a Maya place3dTexture node to animate the noise
for a flickering effect.
|
|
Then a smoothstep was added to create a displacement falloff effect.
|
|
dispfalloff = smoothstep(displacement_adjustment, 1, t);
The smoothstep is keyed to the displacemet_adjustement
artist input, which acts as the start value for the
smoothstep, and can be moved up or down the geometry.
|
|
There is a problem due to the Displacement Bounds defaulting to zero.
|
|
A problem arose when the dual purpose shader was applied to a Maya object
and rendered: because RenderMan surface shaders do not come with a
Displacement Bounds attribute, the renderer assumed a default value of
zero, and provided no slider or other input for me to change the value.
The result is a choppy, artifact filled, and unusable render.
|
|
The Displacement Bounds problem has been fixed,
|
|
The problem could be fixed in one of two ways: splitting the displacement
functions off from the original shader and applying them separately, or
by applying a 'blank' displacement shader and using its 'Displacement
Bounds' attribute to make an end run around the problem.
|