diff --git a/20070926.html b/20070926.html
new file mode 100644
index 0000000..67b8470
--- /dev/null
+++ b/20070926.html
@@ -0,0 +1,32 @@
+
+
20070926 - Drawing in Reverse
+
+
+
+On the Topic of Alpha Blending
+
+
+I had a theory that only about 8 times of overdraw per pixel would be necessary to render everything in Atom. Currently using something upwards of 32 times overdraw per pixel, so if I could skip 3/4 of the overdraw, this would be a tremendous performance win. So I switched the rendering from back to front, to front to back. Changing the alpha blending equation, and added a stencil test so only the first 8 front most impostors per pixel get drawn. The result worked mostly, with one problem. When the first 8 pixels are all low alpha, there is still some artifacting. Adding in a alpha test to clip out really low alpha pixels so they didn't get included in my 8 pixel limit, helped but didn't fix the problem. A more innovative solution was needed!
+
+
+If you think about it, when a pixel is generated by the overlap of many low alpha sprites, it is usually representing some kind of fog or haze. And this fog or haze usually has a similar color to the surrounding pixels. So if the accumulated coverage of a pixel is very low after drawing 8 pixels, it is probably safe to assume the fog/haze case. Now I had a solution to the problem.
+
+
+The solution is to add one more pass, drawing a 1/2 down-sampled copy (using the GPU's automatic mipmap generation) of the previous frame as the last back-most overdraw pass. The down-sampling blurs the pixels slightly (fog/haze), and fills in the areas of low alpha accumulation. Given a good 30 fps, the convergence of the algorithm is invisible to the eye. And it worked, really really well!
+
+
+Final Step to a Huge Performance Win
+
+Already the stencil test helps quite a lot by skipping the fragment shader (and thus 2 texture reads, and 1 ROP blend). But there is a faster way by eliminate large groups of pixels way before the stencil check. After some research, it looks as if only the newest AMD/ATI GPUs have a hierarchical stencil buffer, enabling the stencil pass to clip out groups of pixels (say 16 or 32) at a time. So the best next option is to use the hierarchical z-cull hardware, which I believe is similar in function in all DX10 type cards.
+
+
+Filling the Z buffer is another subproblem. Looks like to use the z-cull, I'm going to have to draw polygons with alpha test off, and no fragment shader depth write. So my idea is to draw a mini framebuffer (x/4 by y/4) first using the stencil idea, but only drawing Z into a texture instead of color. So the last z drawn is for the 8th pixel drawn into the mini framebuffer. Then using a vertex shader to generate two triangles per pixel of the mini framebuffer, and doing a depth only write of the resulting z values into the full size Z buffer. Then the z-cull hardware should be primed to quickly chop groups of pixels which exceed the overdraw limit.
+
+
+With the stencil optimization alone, I am again CPU bound. So I probably wont get to my z-cull test until I get the CPU side better optimized (need to finish my Atom4th stuff).
+
+
+
+
+
+
+I finally got around to doing the reverse drawing with hierarchical Z buffer Z-Cull, and measuring the performance difference with a static VBO. Well the results are in and it is a draw. The benefit was about 10%.
+
+The extra cost of drawing the x/4 by y/4 32bit scaler float framebuffer using stencil, then turning each of those pixels into a 4x4 pixel quad to render Z into the full size depth buffer, and finally doing the full size drawing pass, is too much extra work. The overhead is something like 25% of the original drawing pass, for only a 35% gain.
+
+However
+After more testing, the performance found previously by drawing front first was simply a side effect of turning on the alpha test and throwing out ROP fragments with alpha under 0.0625. Stencil test wasn't even needed for the performance increase. I need 16x overdraw at a minimum to draw the frame anyway, and had 32x max in some areas but these were minor.
+
+In the end I need front first drawing for the physics scatter passes, so the front first is here to stay, and as it turns out I got a 10% improvement simply using the alpha test.
+
+What is Next
+Still working on the optimization of the engine. I'm taking a 1-2 week gamble on a full rewrite to a new combined overdraw culling and physics algorithm on the GPU. Current CPU time is roughly 16% tree prune, 32% overdraw cull, 16% particle to motion blurred imposter, and 36% generation double precision geometry work (tree traversal, etc).
+
+With the new system I'm moving 50% to the GPU, and optimizing, through simplification, of the rest of the CPU bound code. Also switching my version of the "broad phase" collision detection pass from texture arrays to a mipmaped cubemap (rendering to the various mipmaps seperately). More later when I know if it works or fails!
+
+
+
+
+
+(Lost the Image)
+
+
+What Am I Looking At?
+
+A fisheye projection (270 degree horizontal FOV I think) at 640x480 from a 224x224 cubemap (linear filtered) with a single pixel line pattern on each face. Basically a resolution test, areas of very strong moire patters are over-sampled compared to screen space, and areas of the flat line pattern are 1:1 or under-sampled. One more very important note, 640x480=300K and 224x224x6=294K.
+
+
+A Fresh Idea
+
+I've always been a fan of fisheye and wide angle projections, and the ability to see behind yourself in a game, especially a FPS, is just awesome. Like many good ideas, it has been done before, checkout Fisheye Quake. But it isn't done often. There is no projection transform in OpenGL which can output a fisheye projection. Fisheye projections also removes the ability to do a flat screen image space motion blur (the projection curves straight lines). Bottom line is that fisheye projections are cool, but deemed impractical.
+
+
+
+However, with the ever faster GPU, rendering into a cubemap first, then projecting the fisheye is possible. And as can be seen above, for the equivalent number of pixels (single screen vs cube pixels), the output resolution is similar for ultra wide angles.
+
+
+Pros and Cons
+
+First obvious advantage of having a cubemap of the entire view surrounding a player is that now there is a free accurate environment map to use in lighting. And if the mipmap levels for the cubemap are generated, a LOD bias can be used in the environment map as a surface property for sharp or diffuse reflections. Another huge win with the cubemap in Atom is that I am planning on extending my physics to use cubemaps, so the geometry passes could be merged between the physics and drawing pass.
+
+
+
+There are some serious challenges with cubemaps however. First the cubemap must be seamless for visual rendering. This is a serious problem for Atom. Atom's current rendering implementation uses many incorrect optimization hacks to basically composite motion blurred particles which reflect, bend, and emit light, all in screen space. And since these effects are not raytraced, rendering to the sides of the cubemaps would generate very bad seams where a particle crossed between two different image space planes.
+
+
+Now For the Guts
+
+I have an idea, which might work, and if it does it will be spectacular. The basic concept is to use ideas from the physics engine to make a O(1) time lookup for ray intersections in cubemap space (single cubemap lookup), then raytrace the first intersection between the eye ray and particles.
+
+
+
+Now for the even stranger part, what I am going to try compositing (sorted alpha blending) into the cubemap is going to be particle center position, radius, and other properties. Also I'm going to be splitting up the particles by projected size, larger particles in smaller mipmap layers in the cubemap (very important, more on this later). The alpha blending serves to blend particles into more of a meta-ball like surface, and if I draw lines into the cubemap along the motion of the particle, I will have free motion blur!
+
+
+
+Yep that's right, I'm alpha blending Z. Sure it is a no-no, but in my case not a problem (I've been doing this for a while now). My blending is front first (reverse painters), thus I have the alpha coverage value for each pixel. So it is easy to take non-full coverage Z values and correct them.
+
+
+
+Atom by its very structure has a hierarchical metaball like surface, where layers are blended in and out for LOD control. Previously I had some problems with Z ordering changing between parent and child particles in the hierarchy, causing visible popup (can be seen on one of the videos on this site). Now what I am going to do is a set of pyramid rendering passes, rendering the different meta surface hierarchies in different mipmap levels. The less detailed particles are computed in smaller resolution mipmap levels. Should save a tremendous (4x) amount of computation time and remove my overdraw problems...
+
+
+
+The key to this hierarchical rendering is to only render certain properties at the reduced size (planning on ray intersection detection, normal generation, and alpha computation). Then do one full size (mipmap level 0) pass where I read from the eight smaller mipmap layers, Z sort and do both emmitive and environment reflective lighting for each layer. With proper Z ordered alpha blending between the results of each layer.
+
+
+
+Another trick I'm already doing is re-circulating the environmental light from the previous frame into the current frame. In a way it is like fake radiosity. The motion blur tends to hide the fact that it take a few frames to converge, based on the LOD factor in the environmental lighting pass. But the results are awesome, and no one has yet noticed how the lighting "converges" in a few milliseconds as the view changes.
+
+
+
+Will this major change work? Perhaps, will take a while to find out.
+
+
+What About Physics
+
+I read that quote on your blog - Collisons via mipmapped cubemaps - and was intrigued as to what you're planning. I'm somehow not imaging an algorithm that would fit the description, but I am super curious about what you're thinking there. If you feel inspired, a few paragraphs in your blog would be cool :-)
+
+
+
+First off, ultimately for any physics/CFD interaction there is a problem of a large world space, and sparsely grouped items to interact with (the "broad phase" problem). Options are, spacial hash function, uniform grid, or something else to figure out what items are close enough to interact. Subdivision algorithms suffer from a O(ln) run time. So might as well toss all of those out, with many objects composed of particles, O(1) is the only way to go. Uniform grid breaks down for large spaces, (BTW, great example of uniform grid in Chapter 29 of GPU Gems III). So lets toss that out as well. What is left?
+
+
+Something New
+
+Subdivision for collision detection I've tossed out. However Atom already has all particles in a hierarchical tree structure, and each child particle is in the coordinate space of the parent, and thus each child is automatically effected by the movement of the larger parent particle. So in this way I have a free (from the physics engine's standpoint) form of subdivision which is not used for collision, but which has a O(ln) reduction in the complexity of the physics code.
+
+
+
+Now one really important observation, as the number of particles or objects increase, a persons ability to find incorrect particle interactions decreases. In Atoms case, there are about 65536 particles active at a given time, and not all of those have to be 100% correctly interacting. What is important is a few key properties. First that what is hidden requires a much less accurate interaction than what is visible. Likewise higher energy interactions need to be much more accurate than lower energy interactions.
+
+
+
+Sounds like a great hash function to me!
+
+
+
+Exactly. To implement this idea, the hash function is simply the same cubemap used for the view rendering, with larger (projected radius) particles in smaller mipmap levels, and with particles drawn in a very specific order. Ordering is front first (once a bin, or "texel", is filled, it is no longer written to), with a energy level override so that high energy particles can fluidly have a higher priority than the lower energy front most particles. Essentially the viewing projection itself is a major component of the spacial hash. To recap, first render the particles (or particle properties in my case) for each particle in the cubemap, then check for "collisions" by looking up the particles in the cubemap around your particle and check other mipmap layers for larger and smaller particle interactions.
+
+
+
+Sure some particles get lost in this hashing, it is a contracting hash which is not reversible. If this was a problem the idea could be extended with a stencil select binning algorithm to allow multiple particles per bin, but I'm not going this route. I'm already blending my physics CFD particle properties much like what I am planning on doing with my raytracing idea above.
+
+
+Still Reading?
+
+I'm usually done when I don't see good screen shots. Well, I will be posting as I work this idea from concept to completion ... care to take a stab at the number of vertex, geometry, fragment shaders, and drawing passes that are going to be needed to get this new pipeline working? Might take a while!
+
+
+
+
+Motion Card Drawing to Cubemap Prototype
+
+I decided to try porting my older raster based image compositing pipeline (sorted rendering of motion cards, basically motion stretched billboards), and get it working with cubemaps. And it works, but with a few problems.
+
+As I hinted before, Z aligned motion cards wouldn't work because of the seams. So I had to switch to actual 3D geometry for the cards. Getting eye perpendicular cards drawn wasn't too much of a problem, and this did fix the seams. Since I'm not using a Z buffer (pre-sorted), and I wanted to have infinite detail both near and far, I cooked my own projection for each motion card. This insured that I would not have precision issues for clipping near and infinitely far.
+
+All my billboards are stretched in the direction of motion, and also can be non-square. Computing and generating the proper bounding geometry took me a few days to figure out. What I ended up with was a quick simple algorithm which outputs a quad divided into 4 triangles (the point at the center insures proper interpolation for fragment shader).
+
+Problems
+Unlike my working engine, I tried to switch my generation of motion card geometry to a geometry shader. Combined this with output to six sides of a cubemap at once, and the GPU slows to a crawl with 64K motion cards per cubemap face. Switching to rendering to one face and outputing 6x the number of motion cards actually performed much much better. So apparently the single pass render to cubemap idea doesn't work all that well. I'm going to need to go back to my previous methods. Geometry shader usage is way too slow.
+
+Future
+I have a feeling that drawing 6 passes, one to each cubemap face, is many times faster than trying to use a geometry shader. This might be good news for getting this ported to SM3.0. Speaking of SM3.0 and creation of geometry, Gernot Ziegler's HistoPyramids looks like a really good alternative to geometry shader usage for a variety of situations...
+
+
+
+
+
+(Lost all the Images)
+
+
+
+Here is a shot from todays work. It is of a 360 degree fisheye projection of a few thousand motion cards rotating around the camera really really fast.
+
+
+Triangle Reduction, From 4 to 1
+
+Today I rewrote the motion card engine again, this time with a single triangle per motion card instead of 4. The aim here is to increase the efficiency of the geometry side of the engine now that I am planning on rendering 6 sides of a cubemap per frame. One thing I am guessing on is that when the GPU rasterizes small triangles which only cover a few pixels, that a chunk of SPUs are shading pixels which are not even in the polygon (since the GeForce 8 series has something like 8x4 fragment shader granularity). So changing from four tiny triangles per particle to one should provide somewhat of a performance boost in the fragment shading as well.
+
+
+Ellipsoid Rendering
+
+Anyone remember the Ecstatica game series from Psygnosis in 1997? Here is a screen shot,
+
+
+
+
+
+
+The Atom engine is similar in concept, but taken to the next level. Instead of rendering with polygons, the basic primitive in the engine is an ellipsoid, limited to 2 radii instead of three. The motion card part of the engine composites the motion blurred ellipsoids into the framebuffer, and the rendering part of the engine turns each ellipsoid into a shaded impostor.
+
+
+
+Here is a few flat shaded ellipsoid primatives (fisheye projection curves them).
+
+
+
+Then a little motion.
+
+
+
+Then a lot of motion.
+
+
+
+And finally showing triangle primitives created by a large motion case.
+
+
+
+The engine uses a alpha falloff under motion to insure a correct transparency for each moving particle.
+
+
+What's Next
+
+Still need to find a faster output path than the geometry shaders. I'm thinking of trying a trick to use transform feedback on points (one point per motion card) in a vertex shader and then output three interleaved attributes (for the triangle) in a VBO. Then later read in as a non-interleaved array of vertexes for triangles for all my cubemap passes.
+
+
+
+
+
+
+
+Transform feedback + multiple drawing passes is providing to be an excellent solution to the problem of the Geometry Shader pipe being too slow to be useful!
+
+
+Transform feedback basically is a SM4.0 feature which allows the output of a vertex shader to be written into one or more VBOs (vertex buffer objects). On my GeForce 8600 GTS up to 4 VBOs can be written to in one transform feedback pass. Furthermore up to 16 FP32 values can be written to each of those four VBOs. So this enables a transform feedback pass to output up to 16 new vec4 points per point input. Easy data expansion, and a very quick way to turn a single particle into an output triangle.
+
+
+So with transform feedback solving the geometry expansion issues, I tried separate drawing passes to each side of the cubemap (instead of using gl_Layer in a Geometry Shader). This new method is almost 20 times faster than using the Geometry Shader!
+
+
+Now to avoid re-calculating flat varyings (per primitive values, instead of per vertex) in the vertex shaders, and to keep these values well cached between vertexes of the same triangle, texture buffer objects should do just fine. So one early point to point VS pass to generate an interleaved VBO with per primitive values. Then map this VBO as a texture buffer object, and use gl_PrimitiveID to build an index into the texture buffer object in future vertex shaders. I believe this is the absolute fastest path on the GPU for what I am doing.
+
+Other Optimization Progress
+
+So I've managed to offload a large part of the CPU time by getting the motion card pass on the GPU. For the sake of getting this done, I'm archiving my ray tracing ideas for some future project. So the drawing pipeline is doing to be very similar to what I have already working, except now I have extra environmental lighting from the cubemap.
+
+
+I've also gone back through my stencil based reverse drawing code again, and found that turning off the alpha test and using the stencil test actually works quite well. Much better than turning off the stencil and turning on the alpha test. This almost makes me wonder if the GeForce 8 series has some block based stencil hardware to reject blocks of fragments (the AMD/ATI HD card has a hierarchical stencil buffer). Perhaps with the alpha test on, this hardware was disabled. One bonus of having the stencil test is that now I have another method for frame rate control, using the stencil to limit the number of times of overdraw per pixel.
+
+Tossing the HDR Code
+
+That is right, I'm no longer using it. First off the lower-end GeForce 8 cards take 2 times longer to fetch a bilinear filtered FP16 pixel, and 2 times longer to blend FP16 output in the ROP than the same operations with 8bit values. Not to mention the extra memory bandwidth and texture cache misses. With the amount of overdraw I use, this cost just wasn't worth it.
+
+
+Second, I don't like overblown overexposure. From a fine art photography perspective, HDR like extreme overexposure easily ruins an otherwise good photograph. Highlights should near clip or perhaps only clip a little at a point light source like say the sun. Otherwise highlights should have detail.
+
+
+Turns out with my mix of atmospheric lighting (I render atmospheric spaces in-between surfaces), it is just too easy to limit lighting and lighting feedback to values under the clipping point. I can still get near bloom with the added bonus of having detail there, and with colored lights, they still bleed to surrounding objects.
+