Name EXT_texture_swizzle Name Strings GL_EXT_texture_swizzle Contact Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com) Contributors Cass Everitt, Id Software Brian Harris, Id Software Pat Brown, NVIDIA Eric Werness, NVIDIA Status Shipping in October, 2008. Version Last Modified Date: September 9, 2008 Author Revision: 1.0 Number 356 Dependencies Written based on the wording of the OpenGL 2.1 specification. Overview Classic OpenGL texture formats conflate texture storage and interpretation, and assume that textures represent color. In modern applications, a significant quantity of textures don't represent color, but rather data like shadow maps, normal maps, page tables, occlusion data, etc.. For the latter class of data, calling the data "RGBA" is just a convenient mapping of what the data is onto the current model, but isn't an accurate reflection of the reality of the data. The existing texture formats provide an almost orthogonal set of data types, sizes, and number of components, but the mappings of this storage into what the shader or fixed-function pipeline fetches is very much non-orthogonal. Previous extensions have added some of the most demanded missing formats, but the problem has not been solved once and for all. This extension provides a mechanism to swizzle the components of a texture before they are applied according to the texture environment in fixed-function or as they are returned to the shader. IP Status No known IP claims. New Tokens Accepted by the parameters of TexParameteri, TexParameterf, TexParameteriv, TexParameterfv, GetTexParameterfv, and GetTexParameteriv: TEXTURE_SWIZZLE_R_EXT 0x8E42 TEXTURE_SWIZZLE_G_EXT 0x8E43 TEXTURE_SWIZZLE_B_EXT 0x8E44 TEXTURE_SWIZZLE_A_EXT 0x8E45 Accepted by the parameters of TexParameteriv, TexParameterfv, GetTexParameterfv, and GetTexParameteriv: TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 Additions to Chapter 2 of the OpenGL 2.1 Specification (OpenGL Operation) Modify Section 2.15.4 (Shader Execution), p. 84: Texture Access ...and converts it to a texture source color Cs according to table 3.20 (section 3.8.13), followed by application of the texture swizzle as described in section 3.8.13. A four-component vector (Rs,Gs,Bs,As) is returned to the vertex shader. Additions to Chapter 3 of the OpenGL 2.1 Specification (Rasterization) Modify Section 3.8.4 (Texture Parameters), p. 168: (modify table 3.18, p. 169) Name Type Legal Values ---- ---- ------------ TEXTURE_SWIZZLE_R_EXT enum RED, GREEN, BLUE, ALPHA, ZERO, ONE TEXTURE_SWIZZLE_G_EXT enum RED, GREEN, BLUE, ALPHA, ZERO, ONE TEXTURE_SWIZZLE_B_EXT enum RED, GREEN, BLUE, ALPHA, ZERO, ONE TEXTURE_SWIZZLE_A_EXT enum RED, GREEN, BLUE, ALPHA, ZERO, ONE (append to section 3.8.4, p. 170) TEXTURE_SWIZZLE_RGBA_EXT sets the same state as the R, G, B, A enums in a single call. (append to section 3.8.13, p. 184) The values of the texture parameters TEXTURE_SWIZZLE_R_EXT, TEXTURE_SWIZZLE_G_EXT, TEXTURE_SWIZZLE_B_EXT, and TEXTURE_SWIZZLE_A_EXT, are applied after the swizzling described in Table 3.20 (p. 186). The swizzle parameter TEXTURE_SWIZZLE_R_EXT affects the first component of Cs as: if (TEXTURE_SWIZZLE_R_EXT == RED) { Cs'[0] = Cs[0]; } else if (TEXTURE_SWIZZLE_R_EXT == GREEN) { Cs'[0] = Cs[1]; } else if (TEXTURE_SWIZZLE_R_EXT == BLUE) { Cs'[0] = Cs[2]; } else if (TEXTURE_SWIZZLE_R_EXT == ALPHA) { Cs'[0] = As; } else if (TEXTURE_SWIZZLE_R_EXT == ZERO) { Cs'[0] = 0; } else if (TEXTURE_SWIZZLE_R_EXT == ONE) { Cs'[0] = 1; // float or int depending on texture component type } and similarly for Cs'[1], Cs'[2], and As'. Modify Section 3.11.2 (Shader Execution), p. 197: Texture Access ...and converts it to a texture source color Cs according to table 3.20 (section 3.8.13), followed by application of the texture swizzle as described in section 3.8.13. The GL returns a four-component vector (Rs,Gs,Bs,As) to the fragment shader... Additions to the AGL/EGL/GLX/WGL Specifications None Errors The error INVALID_OPERATION is generated if TexParameteri, TexParameterf, TexParameteriv, or TexParameterfv, parameter is TEXTURE_SWIZZLE_R_EXT, TEXTURE_SWIZZLE_G_EXT, TEXTURE_SWIZZLE_B_EXT, or TEXTURE_SWIZZLE_A_EXT, and is not RED, GREEN, BLUE, ALPHA, ZERO, or ONE. The error INVALID_OPERATION is generated if TexParameteriv, or TexParameterfv, parameter TEXTURE_SWIZZLE_RGBA_EXT, and the four consecutive values pointed to by are not all RED, GREEN, BLUE, ALPHA, ZERO, or ONE. New State Changes to table 6.16, p. 277 (Texture, state per texture object) Initial Get Value Type Get Command Value Description Sec. Attribute --------- ---- ----------- ------- ----------- ---- --------- TEXTURE_SWIZZLE_R_EXT Z GetTexParameter RED Red 3.8.4 texture component swizzle TEXTURE_SWIZZLE_G_EXT Z GetTexParameter GREEN Green 3.8.4 texture component swizzle TEXTURE_SWIZZLE_B_EXT Z GetTexParameter BLUE Blue 3.8.4 texture component swizzle TEXTURE_SWIZZLE_A_EXT Z GetTexParameter ALPHA Alpha 3.8.4 texture component swizzle Issues 1) Why not add more new formats instead? RESOLVED: Adding new formats is more implementation burden than one might expect. New formats need to be added to the pixel path, must be considered for FBO support, etc.. This extension avoids those issues by solely affecting the result of a texture fetch. 2) What is the demand for this extension? RESOLVED: There are several independent demands for this, including: - OpenGL 3.0 deprecated support for ALPHA, LUMINANCE, LUMINANCE_ALPHA, and INTENSITY formats. This extension provides a simple porting path for legacy applications that used these formats. - There have been specific requests for (1,1,1,a), or "white alpha" formats that allow a "decal" texture to be used in the same shader as an RGBA texture. This can be accomplished with an OpenGL 2.1 ALPHA texture by doing TexParameteri(target, TEXTURE_SWIZZLE_R_EXT, ONE); TexParameteri(target, TEXTURE_SWIZZLE_G_EXT, ONE); TexParameteri(target, TEXTURE_SWIZZLE_B_EXT, ONE); // TEXTURE_SWIZZLE_A_EXT is already ALPHA or equivalently GLint swiz[4] = {ONE, ONE, ONE, ALPHA}; TexParameteriv(target, TEXTURE_SWIZZLE_RGBA_EXT, swiz); or in OpenGL 3.0 "preview" contexts where ALPHA internal formats are deprecated by using a RED texture: TexParameteri(target, TEXTURE_SWIZZLE_R_EXT, ONE); TexParameteri(target, TEXTURE_SWIZZLE_G_EXT, ONE); TexParameteri(target, TEXTURE_SWIZZLE_B_EXT, ONE); TexParameteri(target, TEXTURE_SWIZZLE_A_EXT, RED); or equivalently GLint swiz[4] = {ONE, ONE, ONE, RED}; TexParameteriv(target, TEXTURE_SWIZZLE_RGBA_EXT, swiz); - This functionality is available on Sony PlayStation 3 and can simplify porting those applications to OpenGL. 3) What names should be used for the components, in both the "source" () and "destination" () enums? RGBA? XYZW? 0123? RESOLVED: RGBA for both source and destination. 0123 could cause confusion with ZERO and ONE. RGBA is a natural choice for source, because the spec describes the values returned by textures as "Color" and "Alpha." There's no particular precedent for destination to be XYZW as this is still part of texture and not the shader, so RGBA it is. 4) How does this interact with depth component textures? RESOLVED: The swizzle is applied after the DEPTH_TEXTURE_MODE. This naturally falls out of specifying the swizzle in terms of Table 3.20. 5) How does this interact with sRGB? RESOLVED: The swizzle is applied after sRGB conversion. 6) How does this interact with NV_register_combiners, NV_texture_shader, and other old "shading" extensions that predate NV/ARB_fragment_program and define their own "interesting" swizzles? RESOLVED: Undefined. Core fixed-function shading (texture_env/combine) are fully supported, but old proprietary "configurable shading" extensions are not. 7) How does the swizzle interact with the fixed-function texture environment referencing the base format? RESOLVED: Note that, by virtue of being defined in terms of Table 3.20, the swizzling occurs *before* the texture environment functions (Table 3.21 and 3.22) are applied. So if you used the first example under Issue (2) with fixed-function, the primary color would "pass through" because the ALPHA base format environment function would still apply. In order to effectively swizzle all four components, an INTENSITY format would give the desired result with the same storage requirements. Revision History Revision 1, 2008/08/21 - Initial draft Revision 2, 2009/01/28 - Add edits to fragment/vertex shader sections to clarify that the swizzle is applied in both.