   Super-stupid deferred lighting reversal idea trick algorithm
  I recently was toying around with various methods of reducing G-buffer size, keeping with the idea that memory ops are going to be vastly more expensive than ALU. In entirely unrelated news, I strongly suspect that deferred shading systems are increasingly going to fall out of favor in the near future for this very reason, but I digress.Anyways, I should probably provide readers with the background research, (slides 19-31) as it makes explanation of what I'm considering loads easier.So, where am I going with this? Basically, what I'm proposing is that we do this with forward shading instead of deferred, ending up with this fascinating little bastard child. In essence, we compute the hierarchal min/max Z as per their method after doing a regular old early-Z pass. We can then use this information to categorize lights into tiles via a compute shader or similar, and thus delve into the more interesting bits. Instead of fetching surface data from G-buffers, we can simply upload a big block of light position and color data via a constant buffer and segregate the contents out as belonging to specific tiles. In theory, all you would need is an offset and a light count stored into a very low-resolution texture (i.e. number of light screen 'tiles' high by number of light screen 'tiles' wide) and indexed into by fragment position on the screen. From there you iterate through all influencing lights as per normal tiled deferred shading, though obviously using surface data calculated via forward shading methods over retrieving from G-buffer temp storage.Good, bad and ugly time!Good- It's really just fancy forward shading, so MSAA works very naturally/correctly.- Light categorization can be run independently on the GPU while things such as rasterization state sorts/additional bookkeeping can be carried out on the CPU, etc. simultaneously.- Back-of-the-envelope calculations say you've like quartered your fillrate consumption and halved total texture read bandwidth by factoring G-buffers out of the equation. This is A Good Thing. Plus, you don't have to store G-buffers at all! Thus, more space for object textures *and* it fits in EDRAM!- Kiss object/light influence combinatorics hell goodbye. It's all screen space, baby!- Extending things off the previous point, lit transparents are now about as free as they can get. Things can get hairy with regards to depth bounds, but even then you can probably get away with doing a side-by-side bounds test for particle effect extents, etc. with an alternate depth buffer and a couple custom prisms.- Single-pass lighting also means Valve-style in-shader tone mapping and/or NAO32-style fixed-point HDR encoding are a very big go.- You probably could get away with doing light binning/sorting on the CPU if you really have to. Sphere vs. axis-aligned plane tests are super-duper cheap.- Since we're in forward shading land again, there are no restrictions/limitations regarding all surfaces using the same lighting model, etc. Surface variety and blatant lighting model hacks abound!Bad- Things like decals modifying their parent surfaces are back to their forward-shading equivalents. Whether this is even a disadvantage is debatable depending on whether or not you were using a deferred system initially, and even then if you actually used such features.- This also does a relatively poor job handling situations where there are a billion lights in one small area of the screen, though this is probably a pretty rare scenario to begin with. Something like LightCuts or fancy spherical harmonics tricks could be employed here if need be.- You're also doing a guaranteed 2 geometry passes for every object. Depending on scene/tessellation, this could be a show-stopper. Granted, this isn't really much different from standard early-Z forward shading anyways, but here you're somewhat strongarmed into performing this for every object and not just ones with relatively low overhead (i.e. skipping early-Z for highly-tessellated and/or super-complex objects)Ugly- Using something like this means you need to employ dynamic branching *heavily.* Unless you're clever with pixel quads, efficiency is going to be completely f**ked with a capital K. On the bright side, aligning light tiles along pixel quad boundaries should probably mitigate most (but probably not all) of this.- The process of skipping lights that make no contribution to the current fragment is also a bit on the hairy side. The effects of this are obviously going to be very scene-dependent and the solution will certainly involve a lot more than just a simple clip()/texkill dependent on attenuation.Anyways, thoughts? One interesting little optimization idea is using a primitive kind of RLE involving the storage of light indices in the tile influence buffers and storing things like position/color data in separate textures. Performance benefits are somewhat dubious, but you could save a little space.   
  Hi,This sounds a lot like Light Indexed Deferred rendering. I dug that technique up again recently after reading the frostbite talk you mentioned, but hit the same issues you highlight above. The big issue for me was dealing with lights that have gobos/projected textures attached to them, as that adds an extra bit of branching complexity.T   