Friday, April 8, 2011

Writing mental ray shaders: Z Depth Part I

Unlike the shader demonstrated in Chapter 7 of Writing Mental Shaders, this is a camera z depth shader. The shader in the book is a world z depth shader.

A shader that displays a grey scale from near to far from the rendering camera.

Hypershade Equivalent

Zdepth shader tree

From the shader tree above,
1. For a point P in space, from the rendering camera, find the -Z position of point P.
2.  Define a near distance and a far distance, use the rendering camera near/far clipping planes to determine, or alternately use the measure distance tool.
3. Use a set range function to remap the distance of (near to far) to 0 and 1, and assign this to a variable factor.
4. Use factor as greyscale values of a surface shader, or use factor as an blend value of a blend function(as above) to blend two colors.

MI File
declare shader
 color "zdepth" (
  scalar "near" default 0,
  scalar "far" default -1000
apply material
end declare

C File
#include "shader.h"

struct zdepth {
 miScalar near;
 miScalar far;

miBoolean zdepth (miColor *result, miState *state, struct zdepth *params) {
 miScalar near = *mi_eval_scalar(&params->near);
 miScalar far = *mi_eval_scalar(&params->far);
 miVector position;
 miScalar factor;
 mi_point_to_camera(state, &position, &state->point);
 if(position.z < far) {
  factor = 0;
 } else
 if(position.z > near) {
  factor = 1;
 } else
 factor = (position.z - far) / (near - far);
 result->r = factor;
 result->g = factor;
 result->b = factor;
 result->a = 1;
return miTRUE;

The example from the book befuddled me for a while, take for instance,

miScalar zpos = state->point.z, factor;

Assigning a value while declaring multiple variables freaked me out. I did a search for that exact line, and here is what the author had to say,

"Here I’ve separated the variables that are initialized to parameter values to two separate lines, but put the zpos and factor variables on a line by themselves. It just didn’t seem worth spending another line on factor, though I realize that the combination of the initialization of zpos (created simply to simplify the logic of the following code) with the non-initialized value of factor could be confusing. Coding standards in a formal programming environment will often dictate how such declarations should be handled." 

Also, keep in mind that position.z is negative as we are looking through the camera along the -z axis.


Post a Comment