Stencil Buffer
What is a Stencil Buffer
The stencil buffer is a buffer in the graphics rendering pipeline, alongside the color buffer and depth buffer. It stores an integer value for each pixel (typically 8-bit, range 0-255) to control rendering operations. The stencil buffer can be used to mark specific areas, restrict rendering, implement shadows, mirror reflections, and other effects.
The stencil buffer is often stored in the same memory as the depth buffer, e.g., in a 32-bit depth/stencil buffer, 24 bits are used for depth and 8 bits for stencil.
How the Stencil Buffer Works
The stencil buffer controls whether a pixel is written through the stencil test. The basic process is as follows:
- For each fragment, read the current value in the stencil buffer at the corresponding position.
- Compare the current value with a reference value (set by the application) using a configurable comparison function (e.g., Always, Equal, Less).
- If the comparison passes, the fragment continues processing; otherwise, it is discarded.
- Regardless of pass or fail, the stencil buffer value can be updated based on stencil operations (e.g., Keep, Increment, Decrement, Replace).
- **Shadow Volume**: Uses stencil buffer to mark shadow areas, with algorithms like Depth-fail or Depth-pass.
- **Mirror Reflections**: When rendering reflective scenes, use stencil buffer to mark the mirror area, restricting reflective objects to appear only within the mirror.
- **Decals**: Use stencil buffer to prevent decals from being rendered on unwanted surfaces.
- **Custom Clipping**: For example, clipping scrollable areas in UI, or rendering to a specific shape viewport.
- **Ray Marching Markers**: Mark visited areas in volume rendering.
- **Multi-pass Effects**: Pass markers between different rendering stages.
- **Data Type**: Depth buffer stores floating-point depth values, stencil buffer stores integer markers.
- **Purpose**: Depth buffer is for visibility determination, stencil buffer is for controlling rendering regions and special effects.
- **Precision**: Depth buffer usually 24-bit or 32-bit, stencil buffer usually 8-bit.
- **Update**: Depth buffer is automatically updated by depth test, stencil buffer requires application-set operations.
- **Clearing**: The stencil buffer should be cleared at the beginning of each frame (usually set to 0).
- **Bandwidth**: The stencil buffer shares bandwidth with the depth buffer, so additional operations may impact performance.
- **Format**: On mobile platforms, stencil buffer may be unavailable or have lower precision; check support.
- **Order**: Stencil test can occur before the fragment shader (Early Stencil), allowing early fragment discard and performance optimization.
These operations enable complex rendering logic.
Common Applications of Stencil Buffer
Difference Between Stencil Buffer and Depth Buffer
Considerations When Using Stencil Buffer
Conclusion
The stencil buffer is a powerful rendering control tool. Mastering its usage enables a variety of advanced effects.
FAQ
Can stencil buffer and depth buffer be used simultaneously?
Yes, they are often stored in the same buffer (e.g., 24-bit depth + 8-bit stencil), and depth test and stencil test are performed together.
What are typical applications of stencil buffer?
Shadow volumes, mirror reflections, decals, custom clipping, UI masking, etc. Any per-pixel marking and testing scenario can use it.
Do mobile devices support stencil buffer?
Most modern mobile GPUs support stencil buffer, but precision may be 8-bit. On some older devices, it may not be supported, requiring fallbacks.
How to clear the stencil buffer?
At the start of a frame, use clear commands to reset the stencil buffer to 0 (or another specified value). In OpenGL, use `glClearStencil` and `glClear`; similar in DirectX.
Does stencil test happen before fragment shader?
Modern GPUs support Early Stencil Test, which can run the stencil test before the fragment shader; if the test fails, the shader is skipped, saving computation. However, in some cases (such as fragment shader modifying stencil values), it may not be possible to run early.