Marc Olano

SGI

SGI

So, if RenderMan is "the standard", why aren't there any real-time RenderMan implementations? It isn't that we wouldn't want one. First, graphics hardware simply isn't capable enough yet. Second, the running time for a RenderMan shader can be arbitrarily long. Finally, real-time rendering encourages a different style of shader writing than software rendering.

At the time [Peercy00] was written, most hardware also lacked the ability to look up texture results based on previous computations. Many current graphics systems support either pixel texture (interpret per-pixel framebuffer color as texture coordinates) or dependent texture (interpret previous texturing results as new texture coordinates). Either of these extensions is sufficient to allow RenderMan's indirect lookups.

If the necessary hardware capabilities were present, it would be completely possible to have a hardware accelerated RenderMan. We have demonstrated this using a software implementation of OpenGL (a modified version of the SGI OpenGL sample implementation). This modified OpenGL uses floating point for all computations and storage, it supports pixel texture and color matrix OpenGL extensions, and base OpenGL 1.2. This demo system translates any RenderMan shader into multiple OpenGL rendering passes.

More concretely, even if we had the ability to run RenderMan on
graphics hardware we couldn't guarantee that **all** RenderMan
shaders would run in real-time. Some

surface beachball( uniform float Ka = 1, Kd = 1; uniform float Ks = .5, roughness = .1; uniform color starcolor = color (1,.5,0); uniform color bandcolor = color (1,.2,.2); uniform float rmin = .15, rmax = .4; uniform float npoints = 5; ) { color Ct; float angle, r, a, in_out; uniform float starangle = 2*PI/npoints; uniform point p0 = rmax*point(cos(0),sin(0),0); uniform point p1 = rmin* point(cos(starangle/2),sin(starangle/2),0); uniform vector d0 = p1 - p0; vector d1; angle = 2*PI * s; r = .5-abs(t-.5); a = mod(angle, starangle)/starangle; if (a >= 0.5) a = 1 - a; d1 = r*(cos(a), sin(a),0) - p0; in_out = step(0, zcomp(d0^d1)); Ct = mix(mix(Cs, starcolor, in_out), bandcolor, step(rmax,r)); /* specular shading model */ normal Nf = normalize(faceforward(N,I)); Oi = Os; Ci = Os * (Ct * (Ka * ambient() + Kd * diffuse(Nf)) + Ks * specular(Nf,-normalize(I),roughness)); }

// set stencil for masking in later passes

angle = 2*PI *s; // draw geometry with 's' as color

angle =2*PI * s; // use blend to multiply by 2*PIangle = 2*PI * s; // store in texture named "angle"

r = .5-abs(t-.5); // draw geometry with 't' as color

r = .5-abs(t-.5); // use blend to subtract .5

r = .5-abs(t-.5); // copy through "abs" color table

r =.5-abs(t-.5); // blend: subtract from .5r = .5-abs(t-.5); // store in texture named "r"

a = mod(angle, starangle)/starangle; // load "angle" from texture

a = mod(angle, starangle)/starangle; // blend: multiply by 1/starangle

a = mod(angle, starangle)/starangle; // copy through "floor" color table

a = mod(angle, starangle)/starangle; // blend: multiply by starangle

a =mod(angle, starangle)/starangle; // blend: subtract from "angle"

a =mod(angle, starangle)/starangle; // blend: multiply by 1/staranglea = mod(angle, starangle)/starangle; // store in texture named "a" if (a>= 0.5) // load "a" from texture

if (a >= 0.5) // blend: subtract .5

if (a >= 0.5)// alpha test: set stencil mask

a = 1 -a; // load "a" from texture

a =1 - a; // blend: subtract from 1

a = 1 - a; // load "a" & combine with stencila = 1 - a; // store in texture named "a"

d1 = r*(cos(a), sin(a),0) - p0; // load "a" from texture

d1 = r*(cos(a), sin(a),0) - p0; // copy through "cos" color table // store in texture named "ftemp0"

d1 = r*(cos(a), sin(a),0) - p0; // load "a" from texture

d1 = r*(cos(a),sin(a),0) - p0; // copy through "cos" color table // store in texture named "ftemp1"

d1 = r*(cos(a), sin(a),0) - p0; // load constant value of 0

d1 = r*(cos(a), sin(a),0) - p0; // load "ftemp0" into red

d1 = r*(cos(a), sin(a),0)- p0; // load "ftemp1" into green

d1 =r*(cos(a), sin(a),0)- p0; // blend: multiply by texture "r"

d1 =r*(cos(a), sin(a),0) - p0; // blend: subtract uniform p0d1 = r*(cos(a), sin(a),0) - p0; // store in texture named "d1"

in_out = step(0, zcomp(d0^d1)); // load uniform d0 // color matrix: store in yzx order in "ctemp0" // color matrix: store in zxy order in "ctemp1"

in_out = step(0, zcomp(d0^d1)); // load "d1" from texture // color matrix: store in yzx order in "ctemp2"

in_out = step(0, zcomp(d0^d1)); // color matrix: shuffle to zxy order

in_out = step(0, zcomp(d0^d1)); // blend: multiply by "ctemp0" // store back into "ctemp0"

in_out = step(0, zcomp(d0^d1)); // load "ctemp1" from texture

in_out = step(0, zcomp(d0^d1)); // blend: multiply by "ctemp2"

in_out = step(0, zcomp(d0^d1)); // blend: subtract "ctemp0"

in_out = step(0, zcomp(d0^d1)); // blend: subtract "ctemp0"

in_out = step(0,zcomp(d0^d1)); // color matrix: copy z to all channels in_out = step(0, zcomp(d0^d1)); // blend: subtract 0 (to shift step)

in_out =step(0, zcomp(d0^d1)); // copy through "step" color tablein_out = step(0, zcomp(d0^d1)); // store in texture named "in_out"

...mix(Cs, starcolor, in_out)... // load uniform Cs ...mix(Cs, starcolor,in_out)... // load "in_out" into alpha

...mix(Cs, starcolor, in_out)... // blend: mix Cs and starcolor // store in texture named "ctemp0"

...mix(..., bandcolor, step(rmax,r));// load "r" from texture

...mix(..., bandcolor, step(rmax,r));// blend: subtract from rmax

...mix(..., bandcolor,step(rmax,r));// copy through "step" color table // store in texture named "ftemp0"

...mix(..., bandcolor, step(rmax,r));// load "ctemp0" ...mix(..., bandcolor,step(rmax,r));// load "ftemp0" into alpha

...mix(..., bandcolor, step(rmax,r));// blend: mix with bandcolorCt = mix(...); // store in texture named "Ct"

...normalize(faceforward(N,I)); // draw geometry, with 'I' as color // store in texture named "ctemp0"

...normalize(faceforward(N,I)); // draw geometry, with 'Ng' as color

...normalize(faceforward(N,I)); // blend: multiply by texture "ctemp0"

...normalize(faceforward(N,I)); // color matrix: add x+y+z

...normalize(faceforward(N,I)); // copy through "flip" color table

...normalize(faceforward(N,I)); // blend: draw 'N' & multiply // store in texture named "ctemp0"

normal Nf =normalize(...); // blend: multiply (to square)

normal Nf =normalize(...); // color matrix: sum channels

normal Nf =normalize(...); // copy through "invsqrt" color table

normal Nf =normalize(...); // blend: multiply by texture "ctemp0"normal Nf = normalize(...); // store in texture named "Nf"

Ci = ...(... + Kd * diffuse(Nf))... // Lighting passes omitted // store in texture named "ctemp0"

Ci = ...(Ka * ambient()+ ...)... // Lighting passes omitted

Ci = ...(Ka * ambient() + ...)... // blend: add "ctemp0"

Ci = ...Ct * (...)... // blend: multiply by "Ct" // store in texture named "ctemp0"

Ci = ...Ks *specular(...)); // Lighting passes omitted

Ci = ...Ks * specular(...)); // blend: multiply by uniform 'Ks'

Ci = Os * (...); // blend: add "ctemp0" (diffuse & ambient) Ci =Os * (...); // blend: multiply by OsCi = Os * (...); // load "Ci" outside object using stencilCi = Os * (...); // store combined Ci into texture named "Ci"