In order to get a handle on the depths of prman, we decided to experiment with DSOs, or Dynamic Shared Objects. We did this by adding our own custom function as a shadeop. This special C program will run within the shader and place points at every micropolygon on the shaded surface. Here is a look at the shadeop that Professor Kesson wrote: |
#include <stdio.h>
#include <stdlib.h>
#include <shadeop.h>
// Because these variables are declared outside of the shadeop functions
// they have "file scope". They are, in effect, shared by the functions
// implemented within this file.
FILE *f = NULL;
int dataOnLine = 0;
float width;
// The startup function. Its been added to the table even though
// it does not do anything useful!
SHADEOP_INIT(writePoints_init) {
return NULL;
}
// The shutdown function. Here we conclude the points statement
// and ensure the output rib file is properly closed.
SHADEOP_CLEANUP(writePoints_cleanup) {
fprintf(f, "\n] \"constantwidth\" [%1.3f] ", width);
fflush(f);
fclose(f);
}
// Here we define the "signature" of the writePoints() custom
// function we are adding to the RenderMan Shading Language.
SHADEOP_TABLE(writePoints) =
{
{ "float writePoints (point, float, string)",
"writePoints_init", "writePoints_cleanup" },
// The table is always concluded with an empty string.
{ "" }
};
// Here we implement the core functionality of our custom
// RSL function
SHADEOP (writePoints)
{
float *pnt = (float*)argv[1]; // an array of floats
width = *(float*)argv[2]; // a single float
STRING_DESC *desc = (STRING_DESC *)argv[3];
// Open the output rib file and begin our points statement
if(f == NULL) {
f = fopen( desc->s, "w");
fprintf(f, "Points \"P\" [\n");
}
// For formating purposes ensure short lines of data
if(dataOnLine < 12)
fprintf(f, "%1.3f %1.3f %1.3f ", pnt[0],pnt[1],pnt[2]);
else
{
fprintf(f, "\n%1.3f %1.3f %1.3f ", pnt[0],pnt[1],pnt[2]);
dataOnLine = 0;
}
dataOnLine += 3;
return 0;
}
|
surface
pointPlacer(float Kfb = 1,
jitter = 0.05,
radius = 0.08,
freq = 8;
string bakename = "")
{
color surfcolor = 1;
if(bakename != "")
{
point pp = transform("object", P);
point ppp = pp + (noise(P * freq) - 0.5) * jitter;
float x = ppp[0] + (random() - 0.5) * jitter/2;
float y = ppp[1] + (random() - 0.5) * jitter/2;
float z = ppp[2] + (random() - 0.5) * jitter/2;
ppp = point ( x,y,z );
writePoints(ppp,radius,bakename);
}
Oi = Os;
Ci = Oi * Cs * surfcolor * Kfb;
} |