GL_EXT_shader_framebuffer_fetch

Supported Hardware

Series5XT, Series6, Series6XE, Series6XT

Valid APIs

OpenGL ES 2.0, 3.x

Description

This extension allows an application to access the previously written fragment colour from a fragment instance. The main use for this is to implement a custom blending technique, allowing developers to perform techniques beyond the standard fixed function blending modes available.

As well as being useful for programmable blending, it can be used in conjunction with multiple render targets to enable fully on-chip deferred shading. Typical deferred shading techniques involve computing a number of values and storing them out to multiple render targets. A second pass then reads these render targets back and computes a final colour.

By using shader framebuffer fetch on PowerVR hardware, values can be written to these fragment locations in one shader, then use these values directly in a full screen resolve pass - only writing out the final colour to main memory.

The steps to achieve this are as follows:

  • Clear the framebuffer at the start of the frame
  • Draw all your geometry as in a traditional deferred shading technique
  • Draw a full screen quad to the same framebuffer
    • The shader used should read values by using this extension, rather than from textures
    • The shader otherwise does the same as it would in a normal deferred shading resolve.
  • Discard all framebuffer attachments, other than the final colour, at the end of the frame

Registry Link

https://www.khronos.org/registry/gles/extensions/EXT/EXT_shader_framebuffer_fetch.txt

Example

void main() 
{ 
	// This is a placeholder for doing the normal calculations in your shader. 
	shaderColour = calculateColourResult(); 
	/*  
	Blend by sampling the previous fragment colour value. This example is  
	effectively equivalent to using glBlendFunc(GL_SRC_ALPHA,  
	GL_ONE_MINUS_SRC_ALPHA) and glBlendEquation(GL_FUNC_ADD). 
	*/ 
	gl_FragColor = mix(gl_LastFragData[0], shaderColourResult, shaderColour.a); 
}

Example (version 300 es)

// Specify a fragment output as an input also – note “inout” instead of “out” 
layout(location = 0) inout lowp vec4 colourAttachmentZero; 
void main() 
{ 
	// This is a placeholder for doing the normal calculations in your shader. 
	shaderColour = calculateColourResult(); 
	/*  
	Blend by sampling the previous fragment colour value. This example is  
	effectively equivalent to using glBlendFunc(GL_SRC_ALPHA,  
	GL_ONE_MINUS_SRC_ALPHA) and glBlendEquation(GL_FUNC_ADD). 
	*/ 
	colourAttachmentZero = mix(colourAttachmentZero, shaderColour, shaderColour.a); 
}