# Documentation/Point based GI

### From PixieWiki

< Documentation

# [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

Retrieved from "http://www.george-graphics.co.uk/pixiewiki/Documentation/Point_based_GI"

Category: Documentation

##### Views

- Article
- Discussion
- Edit
- History

##### Personal tools

- Log in / create account

##### Search

##### Toolbox

- What links here
- Related changes
- Upload file
- Special pages
- Printable version
- Permanent link