www.doriengunnels.com/blog

Renderman II Final Project

RSL: Manipulating the Termination Angle of a Light

by TheRiverside on Nov.17, 2009, under Renderman II Final Project

In an earlier post, I made notes on how the Renderman Shading Language uses “illuminance” loops to define how a surface shader reacts to light coming from a light source. The “luminance” loop used to define a Lambertian shading model in RSL is:

Nn = normalize(N);
illuminance( P, Nn, PI/2 )
{

Ln = normalize(L);
Ci += Cs * Cl * Ln.Nn;

}

I mentioned that it is possible to change the termination angle of a light. In reality, if a sphere were to be lit from a light source coming from a specific direction, half the sphere would be in light and half would be in shadow. This termination angle can be defined as being 90 degrees from the light’s direction. If this angle were changed to something above 90, the light would theoretically seem to wrap around the surface.

The illuminance statement needs three arguments. The third of which is a cone angle (measured in radians) used by the shader to sample incoming light (see this post). By default, the angle is “PI/2″ (90 degrees). While this angle is not actually measuring the angle between the light’s direction and the light/shadow termination line, they happen to be equal. If the angle in the illuminance statement were changed to “PI” (180 degrees), the whole surface would be lit.

While it’s possible to manipulate this single value, there is a way to make this a little more useful. By default, light has a natural falloff before the surface transitions completely into shadow. It might be useful to define a point where the transition will start (begin to fade from fully illuminated) and where it will end (the point the surface will be completely in shadow).

This can be done using the following block of code:

color lightColor = color(1,1,1);
color diffuseColor = 0;
normal n = normalize(N);
float lightfall_begin_angle = 0;
float lightfall_end_angle = 90;

illuminance(”wrapper”,P, n, PI ) {

//declare illuminance variables

vector l = normalize(L);
float dot = n.l;

//PROCESS LIGHTWRAP
// note: angle = 0 = facing light
// note: angle = 180 = away from light
float lightfall_begin_radian = radians(lightfall_begin_angle);
float lightfall_end_radian = radians(lightfall_end_angle);
float illum = smoothstep(cos(lightfall_end_radian), cos(lightfall_begin_radian), dot);

diffuseColor += Cl * lightColor * illum;
}

1) Define the lightColor and diffuseColor.

2) Normalize the surface normal N.

3) Define the beginning and ending angles for the falloff (measured from the light’s direction vector L).

4) Define the illuminance loop. In this case, the loop will be applied only when using lights with the category of “wrapper”. Notice that instead of the angle defining the cone being PI/2, it is simply PI. This is so that, by default, the entire surface is sampling the light. The falloff will be done inside the illuminance loop, not by it.

5) Normalize the light’s direction vector L.

6) Take the dot product of the normalized normal N and the normalized vector L. This will essentially give the cosine of the two vectors. This means that a point facing the light will have a “dot” value of 1. A point facing 90 degrees from the light will have a “dot” value of 0. A point facing completely away from the light will have a “dot”value of -1.

7) Convert the beginning and ending falloff angles into radians.

8 ) use the “smoothstep” function to apply the gradient. This way, any value before the “lightfall_begin” angle will be white (in light). Any angle above the “lightfall_end” angle will be black (in shadow). There will be a steady gradient between the two values (the falloff). You have to take the cosine of both radian angles so they can be measured against the “dot” value.

1 Comment more...

RSL: Passing values from lights shaders to surface shaders

by TheRiverside on Nov.12, 2009, under Renderman II Final Project

Sometimes there are parameters defined in a surface shader that would ideally be controlled by the lighting artist. It is possible to have variables edited in the light and passed to the surface shader.

The process is pretty straight-forward:

In the light, define the editable variable. For example:

In the light shader:

light
wrapperlight(

float intensity = 1;
color lightcolor = 1;
string __category = “wrapper”;
float wrapAngleFromLight = 0)

{

(body)

}

Then, define a variable in the body of the surface shader, and use the “lightsource” function to feed the value from the light shader into the value into the surface shader.

In the body of the surface shader:

float wrapAngleInSurface;

illuminance(”-wrapper”, P, n, PI/2 ){

lightsource(”wrapAngleFromLight”, wrapAngleInSurface);
*rest of illuminance statement*

}

In these examples, the lighter can now change “wrapAngleFromLight” in the light itself. The value will be passed to “wrapAngleInSurface” in the surface shader. The surface shader will then use “wrapAngleInSurface” to perform calculations where the value is needed.

Leave a Comment more...

RSL Notes: illuminate, solar, and illuminance functions and Changing the termination angle of lights

by TheRiverside on Nov.12, 2009, under Renderman II Final Project

Just a few RSL notes…

Illuminance loops:

-Illuminance loops are placed in the surface shader and essentially define how the shader interacts with the light coming from incoming light sources.  There are two forms of this loop:

illuminance(string category“, point position){
statement
}

illuminance(string category“, point position, vector axis, float angle){
statement
}

From the Pixar documentation: “The first form specifies that the integral extends over the entire sphere centered at position. The second form integrates over a cone whose apex is on the surface at position.”

The “cone” created in the second form, is essentially a cone eminating from a position on the surface (usually point P , centered on an axis (usually the surface normal), and spread out using a given angle.  By increasing the cone angle, the user is essentially allowing the sampling of more illumination.  A traditional Lambertian shading model can be defined as:

Nn = normalize(N);
illuminance( P, Nn, PI/2 )
{

Ln = normalize(L);
Ci += Cs * Cl * Ln.Nn;

}

Inside the “luminance” statement, the user is now given access to certain variables:

L – vector – incoming light ray direction
Cl – color – incoming light ray color
Ol – incoming light ray color

Knowing these variables, we can see that the above block of code says:

1) normalize the surface normal N.
2) Check if vector L is detected inside a cone emanating from surface point P (centered on the normalized surface normal and spread using the angle 90 degrees).
3) If L is detected, normalize L. Also, Ci (the apparent surface color of the surface) equals Cs (the actual surface color) times Cl (the light’s color) times the dot product of the normalized N and L vectors.

Changing the termination angle of the light
The angle given in the illuminance loop is always measured in radians. In the code block above, the angle used is PI/2 (90 degrees). This essentially means that the light will stop illuminating the surface 90 degrees from the direction the light is pointing. In the case of a sphere, half the sphere will be illuminated. If this angle is changed below 90 degrees, the light will unrealistically cease to have an effect before the natural termination angle of 90 degrees. If the angle is changed above 90 degrees, this will cause the light to seemingly wrap around the object. The ability to change this termination angle is extremely useful, especially when working with non-photorealistic rendering.  Theoretically, if the angle were changed to 180 degrees, the entirety of the surface would be illuminated regardless of light position or direction.

Light category string
It is possible for surface shaders to contain more than one “illuminance” statement. The “category” string given at the beginning of both types of illuminance loops will state which lights will affect the surface in the way given by that particular illuminance statement. The category is given to the light in the light shader using a flag ” __category” (”category” preceded by two underscores). For example:

light
spotlightWrapper(

float intensity = 1;
color lightcolor = 1;
point from = point “shader” (0,0,0);
point to = point “shader” (0,0,1);
float coneangle = radians(30);
float conedeltaangle = radians(5);
float beamdistribution = 2;
string __category = “wrapper”;

)
{

(body)

}

The category is then called in the surface shader like this:

illuminance(“wrapper”,P, n, PI/2 ) {

Ln = normalize(L);
Ci += Cs * Cl * Ln.Nn;

}


“Illuminate” and “Solar” functions:

These two statements are defined in the light shader.  Like the “illuminance” statement, the user is given access to vector L (the light’s direction) and color Cl (the light’s color).

“Illuminate” function

This function is used when defining light coming from a localized light source (ie: spot lights, point lights, etc.)  and the arguements essentially define a 3d cone eminating from the light source.  Again, there are two forms to this statement:

illuminate( point position )
statement

and

illuminate( point position, vector axis, float angle )
statement

From the Pixar docs:
“The first form specifies that light is cast in all directions. The second form specifies that light is cast only inside the given cone. The length of L inside an illuminate statement is equal to the distance between the light source and the surface currently being shaded.”

Essentially, the arguments say:

The lightsource illuminates from point position, aimed down vector axis, and is spread by angle (measured in radians).  In the first form, since light is being cast in all directions, the statement only needs point position.

“Solar” function

The “solar” function is called when illuminating a surface using a directional light (distance light).  With this type of light, there is not point from which the light is emanating.  Instead, a wall of light is coming evenly from a particular direction.

solar( )
statement

solar( vector axis, float angle )
statement

From the Pixar docs:
“The first form specifies that light is being cast from all points at infinity (e.g., an illumination map). The second form specifies that light is being cast from only directions inside a cone.

An example of the solar statement is the specification of a distant light source:

solar( D, 0 )
Cl = intensity * lightcolor;

This defines a light source at infinity that sends light in the direction D. Since the angle of the cone is 0, all rays from this light are parallel.”

4 Comments more...

Renderman II Final, Technique Not Possible in RSL?

by TheRiverside on Nov.03, 2009, under Renderman II Final Project

Well, I’ve done quite a bit of experimenting trying to use Renderman to achieve the look presented at  http://www.outside-hollywood.com/siggraph/.

As far as I can tell from this abstract, the overall process should be fairly simple:

1) The surface is displaced using a procedural noise.

2) That noise is moved (oscilated) back and forth (maybe rotated?) in such a way that it completes the entire cycle of movement once per frame.

3) The displacement is then motion-blurred.  Since the displacement completes a cycle every frame, it would appear to not actually move at all.  However, once motion blurred, the object would take on the appearance of layered brush strokes.

4) The effect should be furthered using varying displacements, bump maps, tweaking diffuse settings, and “painterly” lighting.

The author of the abstract used Lightwave to achieve this effect.  However, I’ve found several examples of people in the Blender community getting very nice results with this technique as well:

http://www.blendernation.com/non-photorealistic-rendering-painting-with-polygons/

I did a quick test to see if this could be done easily with MentalRay for Maya.  From what I can tell, it is not possible to motion blur a moving displacement map using this renderer.  The object motion blurs just fine when it’s moved.  However, when the object is still and the displacement is moved, it looks as if there is no motion blur applied at all.  Admittedly, I didn’t spend an extremely long time trying to fiddle with it (this is a Renderman project after all).

I then switched to Renderman for Maya for a few quick tests in the GUI before trying to go into RSL.  Same problem.  The object motionblurs when moved.  But when the displacement alone is moved, there is no evidence of motion blur at all.  This really confused me.  I figured that if a free software like Blender can seemingly do this with relative ease, surely Renderman could do it.  There has to be something I’m missing.

Today, in class, I spoke with my professor about my problem.  After a great deal of experimenting and a few posts to the Pixar forums, it’s become my understanding that the ability to render motion-blurred displacements is now available in Renderman Pro Server 15 (the school has 14).  This leaves me with a slight dilemma.  I wanted the final product of this project to be a custom Renderman shader that grants the artist quick and easy access to perameters that can achieve this “painterly” feel.  Since motion-blurring displacements was a vital part of this particular method, unless I get access to Renderman Pro Server 15 soon, I won’t be able to do much experimenting.  I can do one of two things:  1) explore alternate methods of achieving this same effect, or 2) explore other non-photrealistic rendering styles all-together.

I’ve done a bit of experimenting over the last couple days with layering transparent displacement “passes” to try to achieve the same edge quality as the motion-blurred method without actually using motion blur.  Also, with my professor’s help, I’ve explored a method of essentially performing multiple displacements in a single render.  It has also been suggested to me to try to explore how Renderman handles motion-vector AOVs and how to possibly use Nuke to apply a blur in post.  I will be doing a writeup on these experiments tomorrow.

1 Comment more...

Renderman II Final

by TheRiverside on Nov.02, 2009, under Renderman II Final Project

For my final project in my Renderman II class, I’d like to explore the use of RSL in making non-photorealistic renderings.  Specifically, I wanted to try to emulate the look achieved here:

http://www.outside-hollywood.com/siggraph/

I am also going to try to leave myself open to using Renderman’s AOV system to generate “passes” to try to achieve a toon/painterly/styalized look in post.  This project is primarily ment to be an exploration of possible techniques.  However, if I am specifically able to generate the look shown on the website above using a single, art-directable shader, I’d consider the project a success.

Leave a Comment more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...

Archives

All entries, chronologically...