Name OES_shader_multisample_interpolation Name Strings GL_OES_shader_multisample_interpolation Contact Daniel Koch, NVIDIA Corporation (dkoch 'at' nvidia.com) Contributors Pat Brown, NVIDIA Eric Werness, NVIDIA Graeme Leese, Broadcom Contributors to ARB_gpu_shader5 Members of the OpenGL ES working group Notice Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at http://www.khronos.org/registry/speccopyright.html Specification Update Policy Khronos-approved extension specifications are updated in response to issues and bugs prioritized by the Khronos OpenGL ES Working Group. For extensions which have been promoted to a core Specification, fixes will first appear in the latest version of that core Specification, and will eventually be backported to the extension document. This policy is described in more detail at https://www.khronos.org/registry/OpenGL/docs/update_policy.php Status Complete. Ratified by the Khronos Board of Promoters on 2014/03/14. Version Last Modified Date: February 11, 2014 Revision: 10 Number OpenGL ES Extension #172 Dependencies OpenGL ES 3.0 and GLSL ES 3.00 required. This extension is written against the OpenGL ES 3.0.2 (April 8, 2013) and the OpenGL ES Shading Language Specification Revision 4 (March 6, 2013) specifications. This extension requires OES_sample_variables. This extension interacts with OES_sample_shading. Overview In standard multisample rendering, an implementation is allowed to assign the same sets of fragment shader input values to each sample. This can cause aliasing where the fragment shader input values are used to generate a result that doesn't antialias itself, for example with alpha-tested transparency. This extension adds the "sample" qualifier that can be used on vertex outputs and fragment inputs. When the "sample" qualifier is used, the fragment shader is invoked separately for each covered sample and all such qualified interpolants must be evaluated at the corresponding sample point. This extension provides built-in fragment shader functions to provide fine-grained control over interpolation, including interpolating a fragment shader input at a programmable offset relative to the pixel center, a specific sample number, or at the centroid. IP Status No known IP claims. New Procedures and Functions None New Tokens Accepted by the parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetInteger64v: MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D Additions to Chapter 2 of the OpenGL ES 3.0 Specification (OpenGL Operation) None Additions to Chapter 3 of the OpenGL ES 3.0 Specification (Rasterization) Modify Section 3.3, Multisampling, p. 95 (add new paragraph as the second-last paragraph, at the end of the section, p. 96) If the value of SAMPLE_BUFFERS is one and the current program object includes a fragment shader with one or more input variables qualified with "sample in", the data associated with those variables will be assigned independently. The values for each sample must be evaluated at the location of the sample. The data associated with any other variables not qualified with "sample in" need not be evaluated independently for each sample. Modify Section 3.9.1, Shader Variables, p. 161 (modify the second last paragraph of the section to be as follows, p. 161) When interpolating input variables, the default screen-space location at which these variables are sampled is defined in previous rasterization sections. The default location may be overriden by interpolation qualifiers. When interpolating variables declared using "centroid in", the variable is sampled at a location within the pixel covered by the primitive generating the fragment. When interpolating variables declared using "sample in" when the value of SAMPLE_BUFFERS is one, the fragment shader will be invoked separately for each covered sample and the variable will be sampled at the corresponding sample point. (add the following paragraph immediately after the above, p. 161) Additionally, built-in fragment shader functions provide further fine-grained control over interpolation. The built-in functions interpolateAtCentroid() and interpolateAtSample() will sample variables as though they were declared with the "centroid" or "sample" qualifiers, respectively. The built-in function interpolateAtOffset() will sample variables at a specified (x,y) offset relative to the center of the pixel. The range and granularity of offsets supported by this function is implementation-dependent. If either component of the specified offset is less than MIN_FRAGMENT_INTERPOLATION_OFFSET_OES or greater than MAX_FRAGMENT_INTERPOLATION_OFFSET_OES, the position used to interpolate the variable is undefined. Not all values of may be supported; x and y offsets may be rounded to fixed-point values with the number of fraction bits given by the implementation-dependent constant FRAGMENT_INTERPOLATION_OFFSET_BITS_OES. Additions to Chapter 4 of the OpenGL ES 3.0 Specification (Per-Fragment Operations and the Framebuffer) None. Additions to Chapter 5 of the OpenGL ES 3.0 Specification (Special Functions) None. Additions to Chapter 6 of the OpenGL ES 3.0 Specification (State and State Requests) None. Additions to Appendix A of the OpenGL ES 3.0 (Compatibility Profile) Specification (Invariance) None. Additions to the EGL Specifications None. Modifications to The OpenGL ES Shading Language Specification, Version 3.00.04 Including the following line in a shader can be used to control the language features described in this extension: #extension GL_OES_shader_multisample_interpolation : where is as specified in section 3.3. New preprocessor #defines are added to the OpenGL ES Shading Language: #define GL_OES_shader_multisample_interpolation 1 Modify Section 3.7, Keywords, p. 15 (add to the keyword list) sample (remove from the reserved keywords list) sample Modify Section 4.3, Storage Qualifiers, p. 33 (add to first table on the page) Qualifier Meaning -------------- ---------------------------------------- sample in linkage with per-sample interpolation sample out linkage with per-sample interpolation (modify third paragraph, p. 33) These interpolation qualifiers may only precede the qualifiers in, centroid in, sample in, out, centroid out, or sample out in a declaration. ... Modify Section 4.3.4, Input Variables, p. 35 (modify first paragraph of section) Shader input variables are declared with the in, centroid in, or sample in storage qualifiers. ... Variables declared as in, centroid in, or sample in may not be written to during shader execution. ... (modify the last paragraph, p. 35) ... It is an error to use "centroid in", "sample in" or the interpolation qualifiers in a vertex shader input. ... (modify third paragraph, p. 36) ... Fragment shader inputs get per-fragment values, typically interpolated from a previous stage's outputs. They are declared in fragment shaders with the in, centroid in, or sample in storage qualifiers. ... (add to examples immediately below) sample in vec4 perSampleColor; (replace the last paragraph of section, specifying that "sample" only need be used in the fragment shader) The output of the vertex shader and the input of the fragment shader form an interface. For this interface, vertex shader output variables and fragment shader input variables of the same name must match in type and qualification, with a few exceptions: The storage qualifiers must, of course, differ (one is in and one is out). Also, the "sample" qualifier may differ. When the "sample" qualifier does not match, the qualifier declared (if any) in the vertex shader is ignored. Modify Section 4.3.6, Output Variables, p. 37 (modify first paragraph of section) Shader output variables are declared with the out, centroid out, or sample out storage qualifiers. ... (modify third paragraph of section) Vertex output variables output per-vertex data and are declared using the out, centroid out, or sample out storage qualifiers. ... (add to examples immediately below) sample out vec4 perSampleColor; (modify last paragraph, p. 37) Fragment outputs output per-fragment data and are declared using the out storage qualifier. It is an error to use "centroid out" or "sample out" in a fragment shader. ... Modify Section 4.3.9, Interpolation, p. 44 (modify first paragraph of section, add reference to sample in/out) The presence of and type of interpolation is controlled by the storage qualifiers centroid in, sample in, centroid out, and sample out, by the optional interpolation qualifiers smooth, and flat. When no interpolation qualifier is present, smooth interpolation is used. ... (modify second paragraph) ... A variable may be qualified as flat centroid or flat sample, which will mean the same thing as qualifying it only as flat. (replace last paragraph, p. 44) When single-sampling, or for fragment shader input variables qualified with neither "centroid in" nor "sample in", the value is interpolated to the pixel's center and a single value may be assigned to each sample within the pixel, to the extent permitted by the OpenGL ES Specification. When multisampling, "centroid" and "sample" may be used to control the location and frequency of the sampling of the qualified fragment shader input. If a fragment shader input is qualified with "centroid", a single value may be assigned to that variable for all samples in the pixel, but that value must be interpolated at a location that lies in both the pixel and in the primitive being rendered, including any of the pixel's samples covered by the primitive. Because the location at which the variable is interpolated may be different in neighboring pixels, and derivatives may be computed by computing differences in neighboring pixels, derivatives of centroid-sampled inputs may be less accurate than those for non-centroid interpolated variables. If a fragment shader input is qualified with "sample", a separate value must be assigned to that variable for each covered sample in the pixel, and that value must be sampled at the location of the individual sample. Modify Section 8.9, Fragment Processing Functions, p. 99 (add new functions to the end of section, p. 101) Built-in interpolation functions are available to compute an interpolated value of a fragment shader input variable at a shader-specified (x,y) location. A separate (x,y) location may be used for each invocation of the built-in function, and those locations may differ from the default (x,y) location used to produce the default value of the input. For the interpolateAt* functions, the call will return a precision qualification matching the precision of the "interpolant" argument to the function call. float interpolateAtCentroid(float interpolant); vec2 interpolateAtCentroid(vec2 interpolant); vec3 interpolateAtCentroid(vec3 interpolant); vec4 interpolateAtCentroid(vec4 interpolant); float interpolateAtSample(float interpolant, int sample); vec2 interpolateAtSample(vec2 interpolant, int sample); vec3 interpolateAtSample(vec3 interpolant, int sample); vec4 interpolateAtSample(vec4 interpolant, int sample); float interpolateAtOffset(float interpolant, vec2 offset); vec2 interpolateAtOffset(vec2 interpolant, vec2 offset); vec3 interpolateAtOffset(vec3 interpolant, vec2 offset); vec4 interpolateAtOffset(vec4 interpolant, vec2 offset); The function interpolateAtCentroid() will return the value of the input sampled at a location inside the both the pixel and the primitive being processed. The value obtained would be the same value assigned to the input variable if declared with the "centroid" qualifier. The function interpolateAtSample() will return the value of the input variable at the location of the sample numbered . If multisample buffers are not available, the input varying will be evaluated at the center of the pixel. If sample does not exist, the position used to interpolate the input varying is undefined. The function interpolateAtOffset() will return the value of the input variable sampled at an offset from the center of the pixel specified by . The two floating-point components of give the offset in pixels in the x and y directions, respectively. An offset of (0,0) identifies the center of the pixel. The range and granularity of offsets supported by this function is implementation-dependent. For all of the interpolation functions, must be an input variable or an element of an input variable declared as an array. Component selection operators (e.g., ".xy") may not be used when specifying . If is declared with a "flat" qualifier, the interpolated value will have the same value everywhere for a single primitive, so the location used for the interpolation has no effect and the functions just return that same value. If is declared with the "centroid" qualifier, the value returned by interpolateAtSample() and interpolateAtOffset() will be evaluated at the specified location, ignoring the location normally used with the "centroid" qualifier. Modify Section 9, Shading Language Grammar, p. 92 !!! TBD !!! Dependencies on OES_sample_shading This extension builds upon the per-sample shading support provided by OES_sample_shading to provide a new "sample" qualifier on a fragment shader input that forces per-sample shading, and specifies that the value of the input be evaluated per-sample. There is no interaction between the extensions, except that shaders using the features of this extension seem likely to use features from OES_sample_shading as well. Errors None. New State None. New Implementation Dependent State Add to table 6.28 (Implementation Dependent Values) Min. Get Value Type Get Command Value Description Sec. ---------------------- ---- ----------- ----- -------------------------- ----- MIN_FRAGMENT_INTERP- R GetFloatv -0.5 furthest negative offset 3.9.1 OLATION_OFFSET_OES for interpolateAtOffset() MAX_FRAGMENT_INTERP- R GetFloatv +0.5 furthest positive offset 3.9.1 OLATION_OFFSET_OES for interpolateAtOffset() FRAGMENT_INTERPOLATION_ Z+ GetIntegerv 4 subpixel bits for 3.9.1 OFFSET_BITS_OES interpolateAtOffset() Issues (0) This extension is based on parts of ARB_gpu_shader5. What are the major differences? 1- rebased to ES 3.0 2- edits for consistency with GL 4.4/GLSL 440 specs 3- removed mention of 'noperspective' interpolation qualifier 4- removed mention of multisample enable 5- retained tighter interpolation requirements from ES3.0 6- moved gl_SampleMaskIn to OES_sample_variables 7- added precision statement for the interpolateAt* functions. For historical issues, please see Issues 1, 2, 9, 11, and 12 in ARB_gpu_shader5. (1) What should we call this extension? RESOLVED: It will be called OES_shader_multisample_interpolation since it allows the shader to explicitly control the interpolation used for multisample interpolation. (2) "sample" and "centroid" have been split out as "Auxiliary Storage Qualifiers" in GLSL 4.xx specs. Should we follow the way the extension spec was written, or modify it to be more like GLSL 4.40? RESOLVED. Leave it as the original extension was written. The changes in the core spec are related to spec re-ordering which it makes no sense to try to replicate via an extension. (3) For Section 4.9.3 when multisample is disabled the ES 300 spec says "the value is interpolated at the pixel's center", however GLSL 440 says "the value may be interpolated anywhere within the pixel. Which behaviour do we want to incorporate? RESOLVED. We retain the tighter ES 300 requirement which specifies that the pixel's center must be used. (4) What to do with the MULTISAMPLE enable language? RESOLVED. OpenGL ES does not support MULTISAMPLE enable. This is determined by the buffer properties, aka the value of SAMPLE_BUFFERS. (5) Do we need precision qualifiers on the interpolatAt* functions? RESOLVED. Yes. A statement was added for the interpolateAt* functions to clarify that the the precision is taken to from the 'interpolant' argument to the functions. (6) Should the shading language built-ins have OES suffixes? RESOLVED: No. Per Bug 11637, the WG made a policy decision that GLSL ES identifiers imported without semantic change or subsetting as OES extensions from core GLSL do not carry suffixes. The #extension mechanism must still be used to enable the appropriate extension before the functionality can be used. Revision History Rev. Date Author Changes ---- ---------- -------- ----------------------------------------- 10 2014-02-12 dkoch remove GLSL suffixes per Issue 6. 9 2014-01-31 pbrown Add language explicitly not requiring that "sample" qualifier match between stages (bug 11189), where the fragment qualifier wins. 8 2014-01-30 dkoch rename to OES, clean editing notes 7 2013-10-03 dkoch rewrote overview and dependecies 6 2013-09-16 dkoch renamed to shader_multisample_interpolation 5 2013-09-10 dkoch Mark issue 5 as resolved. 4 2013-09-09 dkoch Require OES_sample_variables Move gl_SampleMaskIn interaction base extension. Add precision statement for interpolateAt fn's. Add a couple new edits for ESSL spec. 3 2013-09-03 gleese Moved sample variables to OES_sample_variables 2 2013-08-26 dkoch resolved issues 2-4 & supporting edits. 1 2013-08-13 dkoch port to ES 3.0 0 2013-08-07 dkoch reduced ARB_gpu_shader5 to sample-related features