- New variable types
- Arrays
- New texture mapping tokens
- New built-in functions
- Message passing
- Scoping changes
In addition to point, RenderDotC defines vector and normal types. All three have x, y, and z components. They only behave differently when being automatically transformed from one coordinate system to another. Vectors transform the same was as points except translation is ignored. Normals are transformed such that they remain perpendicular to a plane undergoing the same transformation. More specifically, normals are mutiplied by the inverse transpose of the transformation matrix.
Shader parameters may be declared point, vector or normal using RiDeclare. When triples are passed to the shader, they are automatically transformed to the current space. The details of this transformation depend upon the type.
In addition, triples may be implicitly transformed from within the shader. For example:
vector up = vector "shader" (0, 1, 0);This projects the vector (0, 1, 0) from "shader" space to "current" space.
To explicitly transform a point, vector, or normal from one space to another, use the transform, vtransform, or ntransform function, respectively. The vtransform and ntransform functions are shading language extensions documented below.
uniform string months[12] = {"january", "february", "march", ...};
An array element may be used in any exression where a single variable of the same base type is allowed. If an element of an array is used as an actual parameter to a function which returns a value in that parameter, this sets that element to the return value. In other words, array elements are call-by-reference, just like other function arguments in RenderMan shading language.
If an array of strings is used as the first argument to texture(), then it's ambiguous whether square brackets indicate an array subscript or a channel number. If two sets of square brackets are present, the first is the array subscript and the second is the channel number. If only one set of square brackets appear, then they are interpreted as an array subscript. The channel number will default to 0 in this case.
SL: | Defaults |
texture(mapname, "width", x) | 1.0 |
texture(mapname, "fill", x) | 0.0 |
texture(mapname, "lerp", b) | 1.0 |
texture(mapname, "filter", "s") | "box" |
texture(mapname, "blur", x) | 0.0 |
texture(mapname, "sblur", x) | 0.0 |
texture(mapname, "tblur", x) | 0.0 |
shadow(mapname, "bias", x) | (bias0 + bias1) / 2 |
shadow(map1,map2,map3) | - none - |
shadow(mapname, "source", p1, p2, p3, p4) | P |
shadow(mapname, "gapbias", x) | (bias0 + bias1) * 5 |
C = texture("map.tex"[0], "fill", 0);
A = texture("map.tex"[3], "fill", 1);
If the texture map has an alpha channel it will be used. Otherwise, it will default to opaque (1).
The "fill" token is not recognized by the shadow() function.
Note that this flag may be overridden by the enable lerp option.
The "lerp" token is not recognized by the shadow() function.
Note that this flag may be overridden by the enable gaussian option.
The shadow() function honors only the "box" and "gaussian" filters.
totalds = swidth * ds + sblur
totaldt = twidth * dt + tblur
where ds and dt are the actual dimensions of the area being textured in texture coordinates. Values for sblur and tblur are usually small, such as 0.001, because 1.0 covers the entire width of the texture.
The "blur" token may be used to conveniently set "sblur" and "tblur" to the same value.
The "bias" token is only honored by the shadow() function.
Consecutive pixels in a shadow map whose values differ by gapbias or less are inferred to be generated by the same object. For more information, see the tutorial on creating soft shadows.
vector vtransform(string tospace; vector v)These are corrolaries to the original transform() functions. Where transform() works correctly on points, vtransform is for vectors and ntransform is for normals. Vectors and normals transform differently than points. Care should be taken to choose the form that is correct for the application.
vector vtransform(string fromspace, tospace; vector v)
normal ntransform(string tospace; normal n)
normal ntransform(string fromspace, tospace; normal n)
If fromspace is not specified, "current" is the default.
float ptlined(point P0, point P1, point Q)Returns the euclidean distance from point Q to the nearest point on the line segment from P0 to P1. Note that if the point nearest Q on the infinite line through P0 and P1 does not lie between P0 and P1, it will be clamped to that range before the distance is taken. In other words, ptlined() does not return the distance between Q and an infinite line.
float cellnoise(float x)Returns a pseudorandom value that depends upon the floor of all its arguments. The random values are uniformly distributed over the range from 0 to 1. The results are repeatable: given the same input (or input similar enough that the floor of all arguments is identical) cellnoise will return the same value.
float cellnoise(float s, float t)
float cellnoise(point pt)
float cellnoise(point pt, float t)
point cellnoise(float x)
point cellnoise(float s, float t)
point cellnoise(point pt)
point cellnoise(point pt, float t)
color cellnoise(float x)
color cellnoise(float s, float t)
color cellnoise(point pt)
color cellnoise(point pt, float t)
float min(float a, b, ...)The min and max functions can now take two or more arguments. The min/max of all arguments is returned.
point min(point a, b, ...)
point min(vector a, b, ...)
point min(normal a, b, ...)
color min(color a, b, ...)
float max(float a, b, ...)
point max(point a, b, ...)
point max(vector a, b, ...)
point max(normal a, b, ...)
color max(color a, b, ...)
float clamp(float a, min, max)The clamp and mix functions now operate on all of the scalar data types. Those with more than one component are computed separately on each component.
point clamp(point a, min, max)
point clamp(vector a, min, max)
point clamp(normal a, min, max)
color clamp(color a, min, max)
float mix(float fg, bg; float value)
point mix(point fg, bg; float value)
point mix(vector fg, bg; float value)
point mix(normal fg, bg; float value)
color mix(color fg, bg; float value)
float noise(point pt, float t)Four dimensional noise is now supported. The return value is repeatable and depends on all four input values. A common application is to use time as the fourth dimension.
color noise(point pt, float t)
point noise(point pt, float t)
float pnoise(float v, uniform float period)Periodic noise behaves the same as regular noise but with the additional property that the return value repeats itself with the frequency given by the period argument. In other words, pnoise(v, period) == pnoise(v + period, period) For best results, all periods should be specified with integers.
float pnoise(float u, float v, uniform float uperiod, uniform float vperiod)
float pnoise(point pt, uniform point period)
float pnoise(point pt, float t, uniform point pperiod, uniform float tperiod)
point pnoise(float v, uniform float period)
point pnoise(float u, float v, uniform float uperiod, uniform float vperiod)
point pnoise(point pt, uniform point period)
point pnoise(point pt, float t, uniform point pperiod, uniform float tperiod)
color pnoise(float v, uniform float period)
color pnoise(float u, float v, uniform float uperiod, uniform float vperiod)
color pnoise(point pt, uniform point period)
color pnoise(point pt, float t, uniform point pperiod, uniform float tperiod)
In the first form, the range is automatically computed as abs(Du(s1)*du) + abs(Dv(s1)*dv), resulting in a smooth step over the size of one surface element. The usual warning about not using "area operators" inside of varying conditionals apply to the first form of filterstep. In the second form, the range equals abs(s2 - s1). This form may be used inside varying conditionals.
The parameter list may contain token-value pairs. To specify which filter kernel to use, include the token "filter" followed by "box", "triangle", "catmull-rom", or "gaussian". For example, to select the Gaussian filter kernel:
filterstep(edge, s1, "filter", "gaussian");The default filter is "catmull-rom".
To adjust the amount of overfilter, use the token "width" (or "swidth" synonymously) followed by a floating point number indicating a factor to multiply the filter width by. For example, to double the filter size:
filterstep(edge, s1, "width", 2.0);Each filter kernel has an inherent width of support. Outside of that area of support, filterstep returns either 0 or 1. For reference:
filterstep(x, 0, 1, "filter", "box") is defined over the range x = -0.5 to 0.5 (width 1).Increasing the difference between s0 and s1 or increasing the amout of overfilter with the "width" token will increase the area of support for all of the filter kernels. In other words, the total support width of a filter is the product of its inherent width, the overfilter factor, and the range (either abs(Du(s1)*du) + abs(Dv(s1)*dv) or abs(s2 - s1)).
filterstep(x, 0, 1, "filter", "triangle") is defined over the range x = -1 to 1 (width 2).
filterstep(x, 0, 1, "filter", "catmull-rom") is defined over the range x = -2 to 2 (width 4).
filterstep(x, 0, 1, "filter", "gaussian") is defined over the range x =-1.5 to 1.5 (width 3).
All of the filters used by filterstep() change their shape to match the width. Contrast that with the pixel filters RiCatmullRomFilter() and RiSincFilter() which retain their shape but are merely windowed by xwidth and ywidth.
The difference between this form and the standard one from the RenderMan spec is that the basis of the spline may be specified. The old form is still supported with the implied basis "catmull-rom". With the new form, the basis may be "catmull-rom", "bezier", "hermite", "linear", or "bspline" (note: not "b-spline"). The "linear" basis needs some further explanation. The first and last control vertices are completely ignored. Points on the spline are linearly interpolated between the nearest two control vertices.
float displacement(string varname; {float|point|color|string}
value)
float lightsource(string varname; {float|point|color|string}
value)
float surface(string varname; {float|point|color|string}
value)
float atmosphere(string varname; {float|point|color|string}
value)
The name of the function matches the type of shader from which you wish to receive a message. The first argument is a string containing the name of a variable that may be exported from the sending shader. If the sending shader exists, and it has an output parameter varname, and it's the same type as value, then the value of the output parameter is stored in value and the function returns 1. Otherwise, the function returns 0 and value is left unchanged. If the parameter is uniform and value is varying, then it is promoted. The lightsource() function may only be called within an illuminance loop.
It makes more sense to pass messages "downstream" to shaders that have not yet been evaluated. For a given piece of geometry, the order of evaluation of shaders in RenderDotC is displacement, all of the lights, surface, and atmosphere. Attempting to pass messages "upstream" will yield the default value from the parameter initializer.
displacement waves(float ampl = 1;
output varying vector displaced = 0;)
As a convenience, all parameters whose names begin with a double underscore are automatically flagged as output.
The output keyword may be used in shader parameter lists for the purpose of sending messages.
Variable declarations beginning with extern are completely ignored.
This keyword exists only for compatibility with other renderers.
In RenderDotC, globals and variables declared in outer scopes are always
available to user-defined functions, provided that they are not hidden
by local variables of the same name.