Search this blog

03 February, 2008

Pixel VS Vertex VS Screen

Many times, when asked to implement an effect (for example, fog), the rendering engineer has to choose in which space to operate. It's always a matter of balancing the pipeline (performance) and ease of implementation. I'll talk about "features" of a given space instead of pro and cons, as those features turn into pros or cons depending on what you're trying to do.

Object vertex shaders.
  • Dependant on the mesh, decoupled from the pixels (this means that you can have different shading densities on your model!).
  • Does not automatically LOD (but it's usually easy to implement LOD, lots of possible choices)
  • Can alter the geometry (and topology, on DX10 hardware, via geometry shaders).
  • Caching is dependant on the vertex ordering.
  • Culling is not automatic (but with occlusion queries, it's not harder anymore than the one, highly refined, provided by the rasterizer with z-buffering, early-z, hierarchial-z...).
  • Outputs are interpolated on the mesh surface in a linear (and perspective corrected, for texcoord interpolators) fashion.
  • Can access neighbors data only on DX10 hardware (and on DX9.5, read, Xbox360).
This, unfortunately is becoming an infrequent choice, that puts too much pressure on the pixel units. Unified shader units, kinda solve that, but still, doing things per vertex, can be intresting, for example normal mapping is way too frequently used, but for some kinds of applications, where the normalmap is sparse on the model, and/or where you have to encode sharp edges (for example, cars in a racing title), adding detail in the mesh can be a better choice, because it adds complexity only where it's needed.

Material pixel shaders. Features:
  • Dependant on the pixels, decoupled from vertex complexity (usually)
  • Does automatically LOD (as LOD space usually is screen space, smaller objects use less pixels, thus less shading).
  • More LOD can be applied (but it's not easy, i.e. scaling shading features for far away objects, that still can fill a good percentage of the screen).
  • Overdraw is a big problem.
  • Can access to neighbors data (via differential functions, limited to the currently drawn primitive).
  • Powerful access to external data (via textures and samplers, this is also true for vertex shaders in unified shader APIs/hardware, i.e. DX10).
After-effect (screen space) pixel shaders. Features:
  • Not coupled with objects (no need to cull, but that means also no overdraw).
  • Not coupled with materials, no need to write the same code in all the material shaders.
  • Outputs AND Inputs are coupled with the screen pixels (reading data from a screen sized buffer is hugely more expensive than getting the same data from vertex shader interpolators, as inputs are usually way more than the outputs, and have to be written by material pixel shaders too, that easily becomes a bandwidth problem).
  • Can randomly access to neighbors data.
  • Low-frequency effects can be subsampled (kinda easily).
  • Can be difficult to LOD (usually only if you have access to dynamic branching, with all its limits).
  • Does not work with antialiasing.
  • Can only "see" the first layer of visibility - limited geometrical information can be reconstructed. (eye first-hit in raytracing terms, could be solved with more buffers and depth peeling but it's expensive).
  • Precision problems (in inputs, expecially with older hardware that does not have floating point textures and when reconstructing world space positions from zbuffer, tip: always use wbuffers, it's both faster and more accurate to reconstruct world space from them).
This one is becoming more and more a popular choice. I'm not a big fan of fully deferred shading, but many shading effects can be effectively moved from materials to post in a really efficient way.


Anonymous said...

Anti aliasing can be used with screen space effects on newer hardware. (Definitely dx10.1, not sure about dx10)

DEADC0DE said...

I tryied not to link that post to a given hardware, of course that list changes as hardware do, and it's already inaccurate if you have to factor in some older hw. As for the antialiasing in screenspace effects, that requires to resolve the supersampled z-buffer and to do your effects on it, it's possible but very expensive, so what I wrote still mostly applies.