Documentation/Point based GI

From PixieWiki

Jump to: navigation, search


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:

Image:Pointbased occlude.png

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

Image:Cornell bake.png

You can see the point cloud channels using show (use q and w to switch channels):

Image:Cornell ptc.png

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

Image:Cornell pointbased.png

[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

Personal tools