Point-Based Ambient Occlusion
Hello, this is my first post and I’m going to talk about ambient occlusion, also known as geometric exposure, with Renderman. The approach I’m going to describe is called Point-Based Ambient Occlusion and uses a point cloud to compute the occlusion. If you read my “About” you know I use 3Delight to do my personal research and tests.
This approach is done in two passes. In the first pass we need to convert the scene’s geometry to a point cloud, and in the second pass the point cloud is used to compute the occlusion effect.
Why using this?
Well, it’s much faster than ray-traced occlusion, doesn’t produce any noise, uses less memory, and displacements that usually are a very costly operation when using ray-tracing, don’t have any additional cost when using the point-based approach.
There are also disadvantages. For example, as it is a two-pass approach, it can become a bit daunting when setting up its pipeline. Also, it is not numerically accurate as the ray-tracing approach, but we are not aiming to have numerically accurate results, but instead, having visually accurate approach. In other words we want it to look as good as the ray-tracing approach, and if it takes less time and resources, we’ve achieved our goal.
Now, the steps.
First we need to create a point cloud. This pass is very simple. We only need to use a shader that will convert the geometry into a point cloud. This shader will use the bake3d shadeop to convert each micropolygon to a point, thus creating the point cloud. I use a shader that comes with 3Delight, it is in the $DELIGHT/examples/ptc_occlusion/ folder and is called ptc_write.
In order to get this right, we must do some things first. We need to make sure to turn off the culling operations to make sure that the backfacing and hidden faces are taken into account by the renderer when creating the occlusion pass(second pass of this approach). We also need to use a dicing method that is independent from the camera view:
Attribute “cull” “hidden” [0]
Attribute “cull” “backfacing [0]
Attribute “dice” “rasterorient” [0]
As in this pass we only care about creating the point cloud, and not having a high quality result, we can use low Pixel Samples:
PixelSamples 1 1
This way the creation of the point cloud will be faster. However, if we are aiming to have a very dense point cloud we should lower the Shading Rate. A value of 0.5 should be enough to have a very dense point cloud, but the point cloud creation will be slower.
Now, to the occlusion creation:
Here we use a shader that reads back the point cloud file to compute the occlusion. It can get a bit tricky to get good and fast results. Regarding the occlusion shadeop used in this shader, my experience, and hearing opinions from others, is that we need to have a good balance between the bias and the max solid angle. A bias value of 0.1 should be enough. As for the max solid angle if we use higher values, the rendering time will be faster but the quality decreases and vice-versa. So a good range is 0.01 to 0.5.
We should also set “hitsides” to “both” so that each side of the point cloud’s samples will produce occlusion.
Usually we’ll also want to set “clamp” to 1, as this creates results similar to the ray-tracing approach, but at the cost of speed.
The shader that comes with 3Delight that reads the point cloud to create the occlusion, is very simple, so I made some modifications in order for me to able to control the parameters of the occlusion shadeop. You can get it here if you’d like.
Finally we need to set the quality of the render, such as Pixel Samples, etc, as we want.
When you render it, you’ll notice it is much faster than the ray-tracing approach. Here you can see two renders I did with the purpose of showing you the render times. Higher Resolution image is here. The Ray-Tracing approach took me 13 minutes and the Point-Based only 4 minutes and 40 seconds. Less than half time.

I hope you find this useful, and please, leave me a comment if you think I did something wrong or if you have something to add.
March 8th, 2009 at 2:53 am
thank you, this is very useful and comprehensible.
March 9th, 2009 at 9:24 pm
Great tutorial, very useful.
March 31st, 2009 at 6:15 am
Hello!
Very Interesting post! Thank you for such interesting resource!
PS: Sorry for my bad english, I’v just started to learn this language
See you!
Your, Raiul Baztepo
April 8th, 2009 at 2:01 pm
Hi !!!
My name is Piter Kokoniz. oOnly want to tell, that I’v found your blog very interesting
And want to ask you: is this blog your hobby?
Sorry for my bad english:)
Tnx!
Your Piter Kokoniz, from Latvia
April 14th, 2009 at 2:56 pm
Hello Piter. This Blog is kind of my hobby yes, but I don’t write in it everyday. Only when I have something useful to show.
Thanks a lot.
June 4th, 2009 at 6:04 pm
Hi, cool post. I have been wondering about this topic,so thanks for writing.
June 17th, 2009 at 4:47 pm
Hey Nice tut there.. BTW could u tell me what the clamp option does.. ?
a brief tutorial on how to autobake will also be helpful..frame by frame point cloud occ.
thanks
May 30th, 2010 at 8:24 pm
@Fan: By default, the point-based algorithm creates excessive occlusion, and by setting it to 1 it tries to reduce it a bit but it also gets slower.
Does this make sense?
Jorge
August 8th, 2009 at 11:07 am
Hi Jorge,
Did you use the 3delight geometry attribute to switch off back face culling or you injected that manually into the rib? My point cloud seems to ignore the faces away from camera even though I turned off raster orientation in the geometry attributes (opening the ptc file in the viewer confirms that). I could bake multiple point clouds from different angles but doing it at one go would have been great.
-Sachin
May 30th, 2010 at 8:30 pm
@Sachin: Yes I used the geometry attribute node in 3Delight for Maya. Make sure you do that and it will take into account the faces facing away from camera.
Jorge
May 7th, 2010 at 12:26 pm
hm, very technical, and exactly the same illegible explanation as the one found in the manual. I’m an experienced maya user, fairly knowledgeable with renderman, but new to 3delight, and I was trying to understand what’s with the pc-based occ, or if there are any spherical harmonics implemented in 3delight.
so… I don’t understand for example what – Attribute “dice” “rasterorient” [0] – means, where exactly would you edit or create this attribute. nor what to do with the .sl file, how is it used by maya or 3delight?? I tried to compile it to .sdl but it doesn’t compile with shaderdl.
May 30th, 2010 at 8:24 pm
@anon: Sorry for that. You either add those lines in your RIB or you create a Geometry Attribute Node with the culling options and attach it to the desired geometry. For more information on dicing cameras please refer to 3Delight’s Manual on page 160, 7.12. here: http://www.3delight.com/en/uploads/docs/3delight/3Delight-UserManual.pdf
The .sl file is the source code of the shader that you need to compile in order to be able to use it.
Jorge
May 9th, 2010 at 5:49 pm
Hi Jorge,
i followed your tutorial, and what ever i do, i always get a white line in any 90 degree corners. Is there anyway to get rid of that?
ps: nice blog. congrats.
May 30th, 2010 at 8:23 pm
@mBort: If I understand you correctly this paragraph I wrote on the tutorial takes care of that:
Here we use a shader that reads back the point cloud file to compute the occlusion. It can get a bit tricky to get good and fast results. Regarding the occlusion shadeop used in this shader, my experience, and hearing opinions from others, is that we need to have a good balance between the bias and the max solid angle. A bias value of 0.1 should be enough. As for the max solid angle if we use higher values, the rendering time will be faster but the quality decreases and vice-versa. So a good range is 0.01 to 0.5.
You just need to come up with the right values for you and find a good compromise between render times and quality.
May 30th, 2010 at 7:48 pm
Hi Guys, I just had the time to answer to your questions. Sorry for taking so long.
Jorge
June 3rd, 2010 at 8:09 pm
Just wanted to let you know this info was useful for me. Thank you
June 9th, 2010 at 8:55 pm
this worked great jorge
thanks for making these tutorials
-
does anyone know a good way of applying this to animation?
if objects were moving around, then Id want to bake each frame, and load each frame. I could probably do a mel script to adapt the paths, but wondered if there was a better solution?
June 9th, 2010 at 9:19 pm
Hey Tom,
Go ahead and render a frame range. You should have a point cloud created for each frame. Just make sure you put $F4, #, or @@@@ in the file name, which ever works. For example, occlusion.$F4.ptc and then in the shader to read it as well. I haven’t tried it but it should work. You might also have some problems with moving objects and motion blur, becasuse ambOcc needs to be baked accordingly, but we’ll get back to it later.
Hope this helps,
Jorge
June 25th, 2010 at 3:38 pm
Hi everyone
Ive been playing with all the factors involved in the point cloud occlusion
Im having problems with white artifacts, you can see them if you look near the feet of my characters
they are caused by the bias settings, only when clamp is on. I guess the floor is ignored by the bottom of the feet, so they are unoccluded by the floor?
http://www.bigman3d.com/3del/aoTest_artifact.jpg
-
is there anywhere that documents what each of the parameters in your shader does?
this is my guess……
>bias is the area that each shaded micropolygon searches for point cloud samples
>MaxSolidAngle is the quality controls
>clamp is a 1 or 0 boolean value that attempts to control over darkening
>max dist is the size of the ‘radius’ that is searched for point samples when calculating occlusion, if set to zero, it has no limits
-
I dont know what sampleBase is, doesnt seem to affect my images when I try it
hitSides is just like ‘two-sided’ for regular meshes in maya isnt it?
-
you can see my experiments with different parameters here…
http://www.bigman3d.com/3del/ao_test.jpg
-
any ideas anyone?
June 26th, 2010 at 8:52 pm
Hi Tom, as per what’s in 3Delight’s docs:
“bias” – -1 Specifies a bias for ray’s starting point to avoid potentially erroneous intersections with emitting surface. A value of `-1′ forces 3Delight to take the default value as specified by Attribute “trace” “bias”.
“maxsolidangle” – This is a quality vs speed control when a point cloud is used. Default is 0.1
“clamp” – If set to 1, attempts to reduce the excessive occlusion caused by the point-based algorithm, at the cost of speed. Default is 0.
“maxdist” – Only consider intersections closer than this distance. Default is 1e38.
“samplebase” – Scales the amount of jittering of the start position of rays. The default is to jitter over the area of one micropolygon. Default is 1.0.
“hitsides” – Specifies which side(s) of the point cloud’s samples will produce occlusion. Can take values of “front”, “back” or “both”. Default is “front”.(for example for a sphere you don’t need to calculate occlusion for the inside of it, just use front in that case.
Hope this helps,
Jorge
June 26th, 2010 at 10:55 pm
ok, problem solved!
it was 2 problems rolled into 1
1. the artifacts occur only near where the feet intersect the ground, its a cartoony animation, and the intersection is kinda unavoidable for this. so as a solution I made a second ground under the first one, just to make sure everything gets occluded, even when ‘biased’ underground
2.
I had a problem with my dicing camera
although in my per object attributes I had set the dicing camera to be my special ‘bakeCam’, I hadnt set the renderpass for the baking to be this bakeCam too, so it was defaulting to the render cam for the beauty pass, the point cloud file was coming out as an intersection of the geometry visible only in both the cameras
-
thanks for your help Jorge
June 26th, 2010 at 11:55 pm
Nice one Tom. Always glad to help!
June 29th, 2010 at 9:32 am
hey Ive found that you can control the detail baked into your meshes, on a per object basis by using the shading rate mulitiplier attribute

that has solved my other too problem
thanks