Loops through all light sources in the scene, calling the light shader for each light source to set the Cl and L global variables.
Overview
illuminance(position, [axis], [angle], [light_typemask], [lightmask]) { // Here, Cl and L will be set to the value/direction for the // current light source. // To force the shadow shader to be called, use: // shadow(Cl); }
The shadow shader is not called unless you explicitly call it. However, once the shadow shader has been called, the value of Cl will be changed for the duration of the surface shader. The shadow shader is automatically called when using any of the built-in lighting calls (e.g. diffuse, specular, ambient).
See the section on shading contexts for the values of the light mask.
The default value for the axis is the surface normal. The default value for the angle is PI/2. The default value for the light mask is LIGHT_DIFFUSE|LIGHT_SPECULAR (please see shading.h for the light definitions).
The illuminance statement loops through all light sources for which dot(L, axis) > cos(angle).
Categories
You can use the extra "categories" argument to specify the lights to loop over by categories instead of by masks:
illuminance(origin, normal, angle, "categories", "shadow|occlusion") { ... }
Sending information to the light's shader
You can give additional pairs of string/value arguments to illuminance to pass named values to each light’s shader. For example, to pass the value of the N variable as orgN:
illuminance (P, nf, M_PI/2, "orgN", N) { ... }
In the light’s shader, you can receive the value from the illuminance loop with the simport function.
vector orgN; simport("orgN", orgN);
The simport function returns 1 if the import succeeds and 0 otherwise, so you can use it as the condition in an if statement.
Here’s a full example:
surface exporter() { vector nf = frontface(normalize(N), I); Cf = 0; illuminance(P, nf, M_PI/2, "orgN", N) { Cf += Cl; } } light importer() { vector orgN; if (!simport("orgN", orgN)) orgN = N; // Use original N Cl = orgN; }
Message passing
Within the illuminance loop, you can retrieve values from the light shader with the the limport function.
The light shader can retrieve any “keyword” arguments passed to the illuminance statement with the simport function.
For example, to send down the vector variable uv to the light shader...
vector uv = set(s, t, 0); illuminance(P, dir, "uv", uv) { ... }
The light shader would be able to read this using...
vector uv; if (simport("uv", uv)) printf("Imported: %g from surface\n", uv);
lightexport keyword argument
You can supply the extra string argument "lightexport" followed by
a string argument containing the name(s) of the exported variables to
assign within the loop.
In some shaders, multiple illuminance loops are used to define different
light contributions. The lightexport argument is useful in these cases
to specify which variables should be exported from the different
loops.
The lightexport value can be a space-separated list of wildcard
patterns. For example, illuminance(pos, dir, "lightexport", "Front*")
exports variables whose names start with Front.
surface light_export_test(export vector diff=0; export vector spec=0) { vector nn = normalize(frontface(N, I)); vector vv = -normalize(I); vector clr; Cf = 0; // This illuminace loop only exports to the "diff" variable illuminance(P, nn, "lightexport", "diff") { clr = Cl * diffuseBRDF(normalize(L), nn); Cf += clr; diff = clr; } // This illuminace loop only exports to the "spec" variable illuminance(P, nn, "lightexport", "spec") { clr = Cl * specularBRDF(normalize(L), nn, vv, 0.1); Cf += clr; spec = clr; } }