Documentation/Point based GI
From PixieWiki
Contents |
[edit] Point Based Occlusion
Point based occlusion works by first baking out the micropolygon areas of your scene. This is done with the bake3d() shadeop. This results in a point cloud with the areas in it. It is important to bake out the area in a channel called _area.
This point cloud is read in a second pass using the occlusion() shadop, and specifying to use point based occlusion by passing "pointbased",1 in the argument list to occlusion(). The filename of the point cloud is specified by passing "filename","path/to/area.ptc" in the argument list to occlusion(). The first time that Pixie sees this the occlusion shadeop in point based mode, it will process the point cloud to allow for fast point based occlusion to be computed. Quality is controlled with the "maxsolidangle" parameter which is the maximum solid anbgle in steradians that is permitted for computation of the occlusion. Smaller numbers are more accurate but slower.
[edit] baking out area
This rib
DisplayChannel "float _area"
FrameBegin 1
Format 400 300 1
PixelSamples 4 4
ShadingInterpolation "smooth"
Display "ambient occlusion.tiff" "framebuffer" "rgba" # render image to buffer
Projection "perspective" "fov" 22
Translate 0 -0.5 8
Rotate -40 1 0 0
Rotate -20 0 1 0
WorldBegin
# these attributes are important for point based occlusion to work
Attribute "cull" "backfacing" 0
Attribute "cull" "hidden" 0
Attribute "dice" "rasterorient" 0
ShadingRate 5 # You can afford to bake out a higher shading rate
Surface "bake_areas" "filename" "areacloud.ptc"
# White ground plane
AttributeBegin
Color [1 1 1]
Polygon "P" [ -5 0 5 5 0 5 5 0 -5 -5 0 -5 ] "uniform normal N" [0 1 0]
AttributeEnd
# sphere
AttributeBegin
Color 1 1 1
Translate -0.7 0.5 0
Sphere 0.5 -0.5 0.5 360
AttributeEnd
# box
AttributeBegin
Translate 0.3 0.01 0
Rotate -30 0 1 0
Color [1 1 1]
Polygon "P" [ 0 0 0 0 0 1 0 1 1 0 1 0 ] "uniform normal N" [-1 0 0] # left side
Polygon "P" [ 1 1 0 1 1 1 1 0 1 1 0 0 ] "uniform normal N" [1 0 0] # right side
Color [1 1 1]
Polygon "P" [ 0 1 0 1 1 0 1 0 0 0 0 0 ] "uniform normal N" [0 0 -1] # front side
Polygon "P" [ 0 0 1 1 0 1 1 1 1 0 1 1 ] "uniform normal N" [0 0 1] # back side
Color [ 1 1 1]
Polygon "P" [ 0 1 1 1 1 1 1 1 0 0 1 0 ] "uniform normal N" [0 1 0] # top
AttributeEnd
WorldEnd
FrameEnd
With this surface shader:
surface bake_areas(string filename="")
{
normal Nn = normalize(N);
float a = area(P,"dicing");
bake3d(filename,"_area",P,Nn,"interpolate",1,"_area",a);
// Set Ci and Oi
Ci = Cs * Os * (-normalize(I).Nn);
Oi=Os;
}
Will bake out the areas.
[edit] point based occlusion
This rib
DisplayChannel "float _area"
FrameBegin 1
Format 400 300 1
PixelSamples 4 4
ShadingInterpolation "smooth"
Display "ambient occlusion.tiff" "framebuffer" "rgba" # render image to buffer
Projection "perspective" "fov" 22
Translate 0 -0.5 8
Rotate -40 1 0 0
Rotate -20 0 1 0
WorldBegin
Surface "ptocclude" "filename" "areacloud.ptc" "maxsolidangle" 0.1 #0.05 #0.05
# White ground plane
AttributeBegin
Color [1 1 1]
Polygon "P" [ -5 0 5 5 0 5 5 0 -5 -5 0 -5 ] "uniform normal N" [0 1 0]
AttributeEnd
# sphere
AttributeBegin
Color 1 1 1
Translate -0.7 0.5 0
Attribute "dice" "binary" 1
Sphere 0.5 -0.5 0.5 360
AttributeEnd
# box
AttributeBegin
Translate 0.3 0.01 0
Rotate -30 0 1 0
Color [1 1 1]
Polygon "P" [ 0 0 0 0 0 1 0 1 1 0 1 0 ] "uniform normal N" [-1 0 0] # left side
Polygon "P" [ 1 1 0 1 1 1 1 0 1 1 0 0 ] "uniform normal N" [1 0 0] # right side
Color [1 1 1]
Polygon "P" [ 0 1 0 1 1 0 1 0 0 0 0 0 ] "uniform normal N" [0 0 -1] # front side
Polygon "P" [ 0 0 1 1 0 1 1 1 1 0 1 1 ] "uniform normal N" [0 0 1] # back side
Color [ 1 1 1]
Polygon "P" [ 0 1 1 1 1 1 1 1 0 0 1 0 ] "uniform normal N" [0 1 0] # top
AttributeEnd
WorldEnd
FrameEnd
Combined with this shader:
surface ptocclude(string filename="";float maxsolidangle=0.05)
{
normal Ns = faceforward (normalize(N), I);
float occ = 0;
// Compute occlusion
occ = occlusion(P, Ns, 0, "pointbased",1,"filename",filename,"maxsolidangle",maxsolidangle);
// Set Ci and Oi Ci = (1 - occ) * Cs * Os; Oi=Os; }
Will result in this image:
[edit] Point Based color Bleeding
Much like point based occlusion, point based color bleeding is a two-pass technique. A point cloud is baked out using bake3d(), however, this time you must bake both _area and _radiance. The radiance value should be baked out to include the direct lighting contribution.
In a second pass, indirectdiffuse() take "pointbased",1 to enable point based color bleeding. The point cloud is specified using "filename","path/to/radiance.ptc" in the arguments to indirectdiffuse(). Again, the "maxsolidangle" parameter controls quality vs speed.
[edit] Pass 1, the bake
This rib is used to generate the point cloud
FrameBegin 1
Format 400 400 1
ShadingInterpolation "smooth"
PixelSamples 4 4
Display "cornell_a.tif" "framebuffer" "rgba"
Display "+cornell_bake.tif" "file" "rgba"
Projection "perspective" "fov" 30
Translate 0 0 5
ShadingRate 16 # No need to use low shading rate
DisplayChannel "float _area"
DisplayChannel "color _radiosity"
DisplayChannel "color Cs"
WorldBegin
Attribute "cull" "hidden" 0 # Bake out hidden faces
Attribute "cull" "backfacing" 0 # Bake out back faces
Attribute "dice" "rasterorient" 0 # view-independent dicing
LightSource "cosinelight_rts" 1 "from" [0 1.0001 0] "intensity" 4
Surface "bake_radiosity" "displaychannels" "_area,_radiosity"
"bakefile" "cornell_radio.ptc" "Kd" 0.8
# Matte box
AttributeBegin
Color [1 0 0]
Polygon "P" [ -1 1 -1 -1 1 1 -1 -1 1 -1 -1 -1 ] "uniform normal N" [1 0 0] # left wall
Color [0 0 1]
Polygon "P" [ 1 -1 -1 1 -1 1 1 1 1 1 1 -1 ] "uniform normal N" [-1 0 0] # right wall
Color [1 1 1]
Polygon "P" [ -1 1 1 1 1 1 1 -1 1 -1 -1 1 ] "uniform normal N" [0 0 -1] # back wall
Polygon "P" [ -1 1 -1 1 1 -1 1 1 1 -1 1 1 ] "uniform normal N" [0 -1 0] # ceiling
Polygon "P" [ -1 -1 1 1 -1 1 1 -1 -1 -1 -1 -1 ] "uniform normal N" [0 1 0] # floor
AttributeEnd
Attribute "visibility" "int transmission" 1
Attribute "shade" "transmissionhitmode" "primitive" # the spheres cast shadows
# Left sphere (mirror set to black in this pass)
AttributeBegin
color [0 0 0]
Translate -0.3 -0.69 0.3
Sphere 0.3 -0.3 0.3 360
AttributeEnd
# Right sphere (matte)
AttributeBegin
Translate 0.3 -0.69 -0.3
Sphere 0.3 -0.3 0.3 360
AttributeEnd
WorldEnd
FrameEnd
This is the light shader
light
cosinelight_rts(
float intensity = 1;
color lightcolor = 1;
float falloff = 2; // default: inverse square fall-off
point from = point "shader" (0,0,0); // light position
vector dir = (0, -1, 0);
)
{
illuminate(from, dir, PI/2) {
float dist = length(L);
Cl = intensity * lightcolor * pow (dist, -falloff); // fall-off
Cl *= (L.dir) / (length(L) * length(dir)); // cosine term
Cl *= transmission(Ps, from); // ray traced shadow
}
}
Here is the baking shader. Note the use of area(P,"dicing") to save out the micropolygon areas, rather than the snooth shading areas.
surface
bake_radiosity(string bakefile = "", displaychannels = "";
float Ka = 1, Kd = 1)
{
color irrad;
normal Nn = normalize(N);
float a = area(P, "dicing"); // micropolygon area
// Compute direct illumination (ambient and diffuse)
irrad = Ka*ambient() + Kd*diffuse(Nn);
// Compute Ci and Oi
Ci = irrad * Cs * Os;
Oi = Os;
// Store area and Ci in point cloud file
bake3d(bakefile, displaychannels, P, Nn, "interpolate", 1,
"_area", a, "_radiosity", Ci);
}
The resultant image looks like:
You can see the point cloud channels using show (use q and w to switch channels):
[edit] rendering point based color bleeding
This rib
FrameBegin 1
Format 400 400 1
ShadingInterpolation "smooth"
PixelSamples 4 4
Display "cornell_pointbased.tif" "framebuffer" "rgba"
Display "+cornell_pointbased.tif" "file" "rgba"
Projection "perspective" "fov" 30
Translate 0 0 5
WorldBegin
Attribute "visibility" "trace" 1 # make objects visible to refl. rays
Attribute "trace" "bias" 0.0001
Surface "pointbasedcolorbleeding" "filename" "cornell_radio.ptc"
"maxsolidangle" 0.05
# Matte box
AttributeBegin
Color [1 0 0]
Polygon "P" [ -1 1 -1 -1 1 1 -1 -1 1 -1 -1 -1 ] "uniform normal N" [1 0 0] # left wall
Color [0 0 1]
Polygon "P" [ 1 -1 -1 1 -1 1 1 1 1 1 1 -1 ] "uniform normal N" [-1 0 0] # right wall
Color [1 1 1]
Polygon "P" [ -1 1 1 1 1 1 1 -1 1 -1 -1 1 ] "uniform normal N" [0 0 -1] # back wall
Polygon "P" [ -1 1 -1 1 1 -1 1 1 1 -1 1 1 ] "uniform normal N" [0 -1 0] # ceiling
Polygon "P" [ -1 -1 1 1 -1 1 1 -1 -1 -1 -1 -1 ] "uniform normal N" [0 1 0] # floor
AttributeEnd
# Left sphere (chrome)
AttributeBegin
Surface "mirror"
Translate -0.3 -0.69 0.3
Sphere 0.3 -0.3 0.3 360
AttributeEnd
# Right sphere (matte)
AttributeBegin
Translate 0.3 -0.69 -0.3
Sphere 0.3 -0.3 0.3 360
AttributeEnd
WorldEnd
FrameEnd
With this surface shader
normal shadingnormal(normal Ni) {
return faceforward(normalize(Ni),I);
}
surface
pointbasedcolorbleeding (string filename = "";
float maxdist = 1e15,
samplebase = 0,
maxsolidangle = 0.05;)
{
normal Ns = shadingnormal(N);
color irr = indirectdiffuse(P, Ns, 0, "pointbased", 1, "filename", filename,
"maxdist", maxdist,
"maxsolidangle", maxsolidangle);
Ci = Cs*irr*Os;
Oi = Os;
}
And results in this image:
[edit] Overview
Here's a quick summary of how to use point based occlusion / color bleeding in Pixie.
[edit] Baking out
- Use bake3d()
- Bake out at least float _area which should be the result ot area(P,"dicing")
- Optionally bake out color _radiance which is the incoming light for use in color bleeding
- When baking out for point based GI, it's particularly important to use the 'bake attributes'
Attribute "cull" "hidden" 0 # Bake out hidden surfaces
Attribute "cull" "backfacing" 0 # Bake out back faces
Attribute "dice" "rasterorient" 0 # view-independent dicing
[edit] Rendering
- use occlusion(..."pointbased",1,"filename","thepointcloud.ptc")to get point based occlusion
- the "maxsolidangle" parameter control quality vs. speed and is the maximum solid angle of an approximate disc that is allowed to be used for approximating occlusion / color bleeding
- use indirectdiffuse(..."pointbased",1,"filename","thepointcloud.ptc") to get color bleeding - though you have to have saved _radiance in your point cloud.
EXAMPLES TO FOLLOW




