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