{"id":138,"date":"2009-10-26T21:41:08","date_gmt":"2009-10-27T04:41:08","guid":{"rendered":"http:\/\/www.venzon.org\/?p=138"},"modified":"2009-10-26T21:41:08","modified_gmt":"2009-10-27T04:41:08","slug":"baking-ambient-occlusion-maps-on-the-gpu","status":"publish","type":"post","link":"http:\/\/www.venzon.org\/?p=138","title":{"rendered":"Baking Ambient Occlusion Maps on the GPU"},"content":{"rendered":"<p>Despite the trend toward screen-space ambient occlusion, static ambient occlusion maps are handy for improving the realism of non-deformable objects like cars or spaceships for free. However, baking them in Blender is a chore because raytracing a proper solution using the CPU takes ages. I&#8217;ve been toying with the idea of using the GPU to speed this up for a while now, but only recently figured out how to put it all together and make it work. Here&#8217;s how it works at a high level.<\/p>\n<p>I iterate over the following steps many times from different camera positions along a hemisphere (to emulate the sky). First pass, I render the object from the camera position, writing depth values to a depth texture. This will be used to cast shadows in the next step. Second pass, I render the object again but this time I have my vertex shader set up to transform the verts into the UV map&#8217;s layout. However in the fragment shader, I check the expected (non-uv-map-layout) vertex position against my depth texture to determine occlusion. I write the value of the z component of the screenspace normal (or zero if I determined the pixel was occluded using my depth texture) to a color texture. Third pass, I accumulate the value of the color texture (times 1 \/ number of iterations) into an encoded RGB color texture (I could have used a float texture instead here).<\/p>\n<p>The result is a nice looking 1024&#215;1024 ambient map that takes 3.9 seconds to generate using my aging nvidia 7900GT. I performed 784 iterations, which seems to be the &#8220;sweet spot&#8221; for this method. Larger outputs are easy, up to whatever size your graphics card supports. I&#8217;ve attached an example. Notice how the left and right doors have darker areas around where the side mirrors attach. Neat!<\/p>\n<p><a href=\"http:\/\/www.venzon.org\/wp-content\/uploads\/2009\/10\/body.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.venzon.org\/wp-content\/uploads\/2009\/10\/body.png\" alt=\"GPU generated ambient occlusion map\" title=\"GPU generated ambient occlusion map\" width=\"300\" height=\"300\" class=\"alignnone size-full wp-image-140\" srcset=\"http:\/\/www.venzon.org\/wp-content\/uploads\/2009\/10\/body.png 1024w, http:\/\/www.venzon.org\/wp-content\/uploads\/2009\/10\/body-150x150.png 150w, http:\/\/www.venzon.org\/wp-content\/uploads\/2009\/10\/body-300x300.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Despite the trend toward screen-space ambient occlusion, static ambient occlusion maps are handy for improving the realism of non-deformable objects like cars or spaceships for free. However, baking them in Blender is a chore because raytracing a proper solution using the CPU takes ages. I&#8217;ve been toying with the idea of using the GPU to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-138","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/www.venzon.org\/index.php?rest_route=\/wp\/v2\/posts\/138","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.venzon.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.venzon.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.venzon.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.venzon.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=138"}],"version-history":[{"count":5,"href":"http:\/\/www.venzon.org\/index.php?rest_route=\/wp\/v2\/posts\/138\/revisions"}],"predecessor-version":[{"id":144,"href":"http:\/\/www.venzon.org\/index.php?rest_route=\/wp\/v2\/posts\/138\/revisions\/144"}],"wp:attachment":[{"href":"http:\/\/www.venzon.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.venzon.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=138"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.venzon.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}