Name ARB_sample_shading Name Strings GL_ARB_sample_shading Contact Eric Werness, NVIDIA Corporation (ewerness 'at' nvidia.com) Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) Contributors Murat Balci, AMD Pierre Boudier, AMD Pat Brown, NVIDIA Greg Roth, NVIDIA Graham Sellers, AMD Eric Werness, NVIDIA Notice Copyright (c) 2009-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 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. Approved by the ARB on July 3, 2009. Version Last Modified Date: 02/02/2010 Revision: 8 Number ARB Extension #70 Dependencies OpenGL 2.0 is required. OpenGL Shading Language 1.30 is required This extension is written against the OpenGL 2.0 specification and version 1.30 of the OpenGL Shading Language Specification. Overview In standard multisample rendering, an implementation is allowed to assign the same color and texture coordinate values to each sample, which then allows the optimization where the shader is only evaluated once and then distributed to the samples that have been determined to be covered by the primitive currently being rasterized. This can cause aliasing where the input color and texture coordinates are used to generate a result that doesn't antialias itself, for example with alpha-tested transparency. This extension adds the ability to explicitly request that an implementation use a minimum number of unique set of fragment computation inputs when multisampling a pixel. Specifying such a requirement can reduce aliasing that results from evaluating the fragment computations too few times per pixel. This extension adds new global state that controls the minimum number of samples for which attribute data is independently interpolated. When enabled, all operations that were traditionally executed per-fragment operate independently on each sample. This also extends the shading language to allow control over the sample being processed. This includes built-in fragment input variables identifying the sample number and position being processed when executing fragment shaders per sample. New Procedures and Functions void MinSampleShadingARB(clampf value); New Tokens Accepted by the parameter of Enable, Disable, and IsEnabled, and by the parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev: SAMPLE_SHADING_ARB 0x8C36 Accepted by the parameter of GetBooleanv, GetDoublev, GetIntegerv, and GetFloatv: MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation) None. Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization) Modify Section 3.2.1 Multisampling p. 93 (add a new paragraph at the end of the section, p. 95) Sample shading can be used to specify a minimum number of unique samples to process for each fragment. Sample shading is controlled by by calling Enable or Disable with the symbolic constant SAMPLE_SHADING_ARB. If MULTISAMPLE or SAMPLE_SHADING_ARB is disabled, sample shading has no effect. Otherwise, an implementation must provide a minimum of max(ceil(MIN_SAMPLE_SHADING_VALUE_ARB*SAMPLES),1) unique color values and sets of texture coordinates for each fragment. These are associated with the samples in an implementation-dependent manner. The value of MIN_SAMPLE_SHADING_VALUE_ARB is specified by calling void MinSampleShadingARB(clampf value); with set to the desired minimum sample shading fraction. is clamped to [0,1] when specified. The sample shading fraction may be queried by calling GetFloatv with pname set to MIN_SAMPLE_SHADING_VALUE_ARB. When the sample shading fraction is 1.0, a separate set of colors and other associated data are evaluated for each sample, each set of values are evaluated at the sample location. Modify section 3.11, Fragment Shaders, p. 193 Add the following paragraph to the section Shader Inputs, p. 196 The built-in read-only variable gl_SampleID is filled with the sample number of the sample currently being processed. This variable is in the range 0 to gl_NumSamples-1, where gl_NumSamples is the total number of samples in the framebuffer, or one if rendering to a non-multisample framebuffer. Using this variable in a fragment shader causes the entire shader to be evaluated per-sample. When rendering to a non-multisample buffer, or if multisample rasterization is disabled, gl_SampleID will always be zero. gl_NumSamples is the sample count of the framebuffer regardless of whether multisample rasterization is enabled or not. The built-in read-only variable gl_SamplePosition contains the position of the current sample within the multi-sample draw buffer. The x and y components of gl_SamplePosition contain the sub-pixel coordinate of the current sample and will have values in the range zero to one. The sub-pixel coordinate of the center of the pixel is always (0.5, 0.5). Using this variable in a fragment shader causes the entire shader to be evaluated per-sample. When rendering to a non-multisample buffer, or if multisample rasterization is disabled, gl_SamplePosition will always be (0.5, 0.5). Add the following paragraph to the section Shader Outputs, p. 196 The built-in integer array gl_SampleMask[] can be used to change the sample coverage for a fragment from within the shader. The number of elements in the array is ceil(/32), where is the maximum number of color samples supported by the implementation. If bit of element in the array is set to zero, sample *32+ should be considered uncovered for the purposes of multisample fragment operations (Section 4.1.3). Modifying the sample mask in this way may exclude covered samples from being processed further at a per-fragment granularity. However, setting sample mask bits to one will never enable samples not covered by the original primitive. If the fragment shader is being evaluated at any frequency other than per-framgent, bits of the sample mask not corresponding to the current fragment shader invocation are ignored. Add the following prototypes to the list of built-in variables accessible from a fragment shader: in int gl_SampleID; in vec2 gl_SamplePosition; out int gl_SampleMask[]; Add the following prototype to the list of built-in uniforms accessible from a fragment shader: uniform int gl_NumSamples; Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment Operations and the Frame Buffer) Modify Section 4.1.3, Multisample Fragment Operations, p. 200 (modify first paragraph of section) This step modifies fragment alpha and coverage values based on the values of SAMPLE_ALPHA_TO_COVERAGE, SAMPLE_ALPHA_TO_ONE, SAMPLE_COVERAGE, SAMPLE_COVERAGE_VALUE, SAMPLE_COVERAGE_INVERT, and an output sample mask optionally written by the fragment shader. No changes to the fragment alpha or coverage values are made at this step if MULTISAMPLE is disabled, or if the value of SAMPLE_BUFFERS is not one. (insert new paragraph after second paragraph, p. 201) Next, if a fragment shader is active and statically assigns to the built-in output variable gl_SampleMask, the fragment coverage is ANDed with the bits of the sample mask. If such a fragment shader did not assign a value to gl_SampleMask due to flow control, the value ANDed with the fragment coverage is undefined. If no fragment shader is active, or if the active fragment shader does not statically assign values to gl_SampleMask, the fragment coverage is not modified. Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions) None. Additions to Chapter 6 of the OpenGL 2.0 Specification (State and State Requests) None. Additions to the AGL/GLX/WGL Specifications None GLX Protocol TBD Errors None. New State Get Value Get Command Type Initial Value Attribute --------- ----------- ---- ------------- --------- SAMPLE_SHADING_ARB IsEnabled B FALSE multisample/enable MIN_SAMPLE_SHADING_VALUE_ARB GetFloatv R+ 0 multisample New Implementation Dependent State None. Modifications to The OpenGL Shading Language Specification, Version 1.10.59 Including the following line in a shader can be used to control the language features described in this extension: #extension GL_ARB_sample_shading A new preprocessor #define is added to the OpenGL Shading Language: #define GL_ARB_sample_shading 1 Add to section 7.2 "Fragment Shader Special Variables" The built-in output array gl_SampleMask[] sets the sample mask for the fragment being processed. Coverage for the current fragment is ANDed with the value of gl_SampleMask. Bit B of mask gl_SampleMask[M] corresponds to sample 32*M+B. This array must be sized in the fragment shader either implicitly or explicitly to be the same size as the implementation dependent maximum sample mask words determined by the maximum number of samples. If the fragment shader statically assigns a value to gl_SampleMask[], the sample mask will be undefined for any array elements of any fragment shader invocations that fails to assign a value. If a shader does not statically assign a value to gl_SampleMask, the sample mask has no effect on the processing of a fragment. The built-in read-only variable gl_SampleID is filled with the sample number of the sample currently being processed. This variable is in the range 0 to gl_NumSamples-1, where gl_NumSamples is the total number of samples in the framebuffer, or one if rendering to a non-multisample framebuffer. Using this variable in a fragment shader causes the entire shader to be evaluated per-sample. The built-in read-only variable gl_SamplePosition contains the position of the current sample within the multi-sample draw buffer. The x and y components of gl_SamplePosition contain the sub-pixel coordinate of the current sample and will have values in the range zero to one. Using this variable in a fragment shader causes the entire shader to be evaluated per-sample. ... The built-in variables that are accessible from a fragment shader are intrinsically given types as follows: int gl_SampleID; vec2 gl_SamplePosition; int gl_SampleMask[]; Issues 1) Do we need both an enable and state? RESOLVED. Yes - that's just the way GL rolls 2) How many times is the fragment shader run? RESOLVED. The shader must be run at least once for each unique set of texture coordinates and colors, so max(MIN_SAMPLE_SHADING_VALUE_ARB*SAMPLES,1) times. 3) What cases can benefit from enabling this? RESOLVED. Something like alpha-tested rendering using textures don't benefit from multisampling right now - using this extension to run the fragment shader or fixed-function texturing multiple times per pixel can significantly improve quality. 4) What do KIL and discard do? RESOLVED. They terminate a single invocation of the shader, so a single fragment may have some threads that discard and some that don't. 5) Should there be an option to specify that all fragment shader inputs be interpolated at per-sample frequency? If so, how? RESOLVED: Yes. Via the enable 6) Should the ability to specify per-sample or per-fragment interpolation on a per-varying basis be added via the language? RESOLVED: Not in this extension. 7) Does gl_SampleMask belong here? RESOLVED: Yes, it's sample related and conteporary with the hardware required for the rest of this extension. Thematically it might match better with ARB_texture_multisample, but that extension targets hardware that cannot support gl_sampleMask. 8) How should gl_SampleMask mask samples above the first 32? RESOLVED: By being an array with enough entries to encompass all the implementation-dependent maximum number of samples. 9) Is per-sample shading ever triggered by properties of the fragment shader? RESOLVED: Yes. The variables "gl_SampleID" and "gl_SamplePosition" can be used to read properties of the current sample, which wouldn't make much sense if the fragment shader were run at a lower frequency than per-sample. 10) Does gl_SamplePosition need to support layout() qualifiers such as "pixel_center_integer" in GLSL 1.50? RESOLVED: Not in this extension. "pixel_center_integer" was added in part for compatibility with shaders originally targeting Direct3D version 9.0 or earlier, where pixel centers were specified to be (X.0, Y.0) instead of OpenGL's (X.5, Y.5). However, Direct3D 9.0 doesn't support anything like "gl_SamplePosition", and Direct3D versions that do support this functionality have adopted OpenGL's (X.5, Y.5) conventions. Revision History Rev. Date Author Changes ---- -------- -------- ----------------------------------------- 8 02/02/2010 pbrown Clarify that use of gl_SamplePosition triggers per-sample shading (bug 5911). 7 01/20/2010 Jon Leech Add rounding rule for computing number of samples used depending on min sample shading setting. 6 10/22/2009 pdaniell Specify that gl_NumSamples should return the sample count for the framebuffer regardless of whether MULTISAMPLE is enabled or not. This matches the API-level queries. 5 09/17/2009 pbrown Clean up some language on MinSampleShading. Add a clarification requiring variables to be sampled at sample locations when doing full per-sample shading. Add some more details on the gl_SampleMask array and its operation in the multisample fragment ops. Rename gl_MaxSampleId to gl_NumSamples and adjust language. 4 08/02/2009 Jon Leech Reformat to 80 columns and assign ARB extension number 3 06/25/2009 groth Restore missing explanations of MIN_SAMPLE_SHADING_VALUE_ARB 2 05/15/2009 groth Restore gl_sampleMask as an array 1 05/13/2009 groth Merge from NV_sample_shading_control, NV_gpu_shader4_1, and AMD_sample_rate_shader