GL_EXT_shader_pixel_local_storage#

Supported Hardware#

Series6, Series6XE, Series6XT

Valid APIs#

OpenGL ES 3.x

Description#

Pixel local storage takes advantage of the fact that tile-based renderers use a small, on-chip cache to render images to before writing them to main memory. These registers are actually entirely independent from the final framebuffer, and there’s no real need to reference them in any particular format or have any backing store behind them. This extension exposes these registers to the user and guarantees that they remain coherent between fragment shaders in a single render pass, as long as no operation causing a flush is performed. This allows users to store data in early fragment passes and then access these values in later fragment passes at the same pixel location. The principle behind it is thus similar to that of GL_EXT_framebuffer_fetch, but in a much more flexible way. A number of packing storage qualifiers are also added, to specify how data is written to these registers.

There are two primary expected use cases for this:

  • Deferred Shading

    • Typically, deferred shading uses external textures to store GBuffer values. This consumes a significant amount of bandwidth due to the number of write and read operations performed. Instead, pixel local storage allows applications to store the GBuffer wholly on-chip and avoid this enormous bandwidth cost, only storing out the final evaluated colour.

  • Order Independent Transparency

    • Pixel local storage can also be used to store data representing the colour of multiple pixels, stored in depth order rather than render order, allowing a bandwidth-free linked-list approach for generating order independent blending.

Example#

#extension GL_EXT_shader_pixel_local_storage : require
__pixel_local_inEXT GBufferLocalStorage
{
    layout(rgba8)          lowp  vec4  albedo;
    layout(r11f_g11f_b10f) highp vec3  normal;
    layout(r32f)           highp float depth;
    layout(rgba8)          lowp  vec4  accumulatedColour;
};
uniform highp vec3  uLightColourIntensity;
in highp vec3 vLightDirection;
// Simple directional lighting evaluation
void main()
{
    // Calculate simple diffuse lighting for the current pixel.
    highp float n_dot_l = max(dot(-vLightDirection, normal), 0.0);
    lowp vec4 lightContribution = vec4(albedo.rgb * n_dot_l * uLightColourIntensity, 1.0);
    accumulatedColour += lightContribution;
}