There's more...

There are two interpolation qualifiers within the GLSL that allow the programmer to fine-tune some aspects of multisampling. They are sample and centroid.

Before we can get into how sample and centroid work, we need a bit of background. Let's consider the way that polygon edges are handled without multisampling. A fragment is determined to be inside or outside of a polygon by determining where the center of that pixel lies. If the center is within the polygon, the pixel is shaded, otherwise it is not. The following image represents this behavior. It shows pixels near a polygon edge without MSAA. The line represents the edge of the polygon. Gray pixels are considered to be inside the polygon. White pixels are outside and are not shaded. The dots represent the pixel centers:

The values for the interpolated variables (the fragment shader's input variables) are interpolated with respect to the center of each fragment, which will always be inside the polygon.

When multisample anti-aliasing is enabled, multiple samples are computed per fragment at various locations within the fragment's extent. If any of those samples lie within the polygon, then the shader is executed at least once for that pixel (but not necessarily for each sample).

As a visual example, the following image represents pixels near a polygon's edge. The dots represent the samples. The dark samples lie within the polygon and the white samples lie outside the polygon. If any sample lies within the polygon, the fragment shader is executed (usually only once) for that pixel. Note that for some pixels, the pixel center lies outside the polygon. So, with MSAA, the fragment shader may execute slightly more often near the edges of polygons:

Now, here's the important point. The values of the fragment shader's input variables are normally interpolated to the center of the pixel rather than to the location of any particular sample. In other words, the value that is used by the fragment shader is determined by interpolating to the location of the fragment's center, which may lie outside the polygon! If we are relying on the fact that the fragment shader's input variables are interpolated strictly between their values at the vertices (and not outside that range), then this might lead to unexpected results.

As an example, consider the following portion of a fragment shader:

in vec2 TexCoord; 
 
layout( location = 0 ) out vec4 FragColor; 
 
void main() { 
 vec3 yellow = vec3(1.0,1.0,0.0); 
 vec3 color = vec3(0.0);  // black 
 if( TexCoord.s > 1.0 ) 
  color = yellow; 
 FragColor = vec4( color , 1.0 ); 
}

This shader is designed to color the polygon black unless the s component of the texture coordinate is greater than one. In that case, the fragment gets a yellow color. If we render a square with texture coordinates that range from zero to one in each direction, we may get the results shown in the following image on the left. The following images show the enlarged edge of a polygon where the s texture coordinate is about 1.0. Both images were rendered using the preceding shader. The right-hand image was created using the centroid qualifier (more on this later in this chapter):

The left image shows that some pixels along the edge have a lighter color (yellow, if the image is in full color). This is due to the fact that the texture coordinate is interpolated to the pixel's center, rather than to any particular sample's location. Some of the fragments along the edge have a center that lies outside of the polygon and therefore end up with a texture coordinate that is greater than one!

We can ask OpenGL to instead compute the value for the input variable by interpolating to some location that is not only within the pixel but also within the polygon. We can do so by using the centroid qualifier, as shown in the following code:

centroid in vec2 TexCoord; 

(The qualifier needs to also be included with the corresponding output variable in the vertex shader.) When centroid is used with the preceding shader, we get the preceding image shown on the right.

In general, we should use centroid or sample when we know that the interpolation of the input variables should not extend beyond the values of those variables at the vertices.

The sample qualifier forces OpenGL to interpolate the shader's input variables to the actual location of the sample itself:

sample in vec2 TexCoord;

This, of course, requires that the fragment shader be executed once for each sample. This will produce the most accurate results, but the performance hit may not be worthwhile, especially if the visual results produced by centroid (or without the default) are good enough.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.242.141