Questions to help clarify fragment to framebuffer process

I am reading the OpenGL 4.6 spec and am confused by a few points regarding fragments and framebuffers.

  1. If an RGBA color value is written to a non-zero draw framebuffer (i.e. a framebuffer object), the mapping of the components to the framebuffer image (e.g. could be RGBA to RGB) is defined in section 9.6. Why does it exclude the default framebuffer here (i.e. only non-zero) and what defines this same process for the default framebuffer, if anything?

  2. If the logical operation fragment stage is enabled then it states “The result replaces the values in the framebuffer at the fragment’s (xw,yw) coordinates”. If the stage is disabled, is the color value still written to the framebuffer at this point - surely it must be?

  3. At what stage is the fragment shader output converted to the fixed-point framebuffer format, if applicable? It mentions it in the blending fragment stage but that suggests conversion relies on blending being enabled.

  4. How does blending work on a framebuffer without an alpha component - is the existing alpha color value assumed to be 1, 0, or unspecified? I am assuming 1 based on section 9.7 but again this says non-zero framebuffers only.

Thanks in advance!

Because that section specifically relates to framebuffer objects.

If anything, it will be covered by the platform-specific specification (e.g. glX, wgl, egl).

If logic ops are disabled, then the colour which would be used for the logic op is written directly to the framebuffer as if the logic op was GL_COPY.

After blending and sRGB conversion, but before dithering.

The framebuffer’s alpha component is only relevant if the blending function uses GL_DST_ALPHA or GL_ONE_MINUS_DST_ALPHA. If the framebuffer lacks an alpha channel, the alpha value is constant one. In general, any operation which converts a value with a variable number of components to a value with four components fills in missing components with zero for the second and third components and one for the fourth component. This applies to colours, spatial coordinates and texture coordinates.

1 Like

Thanks for helping clarify that - it helped me find the references I needed.

For anyone else interested, 17.3 (fragments are written after logical ops if not discarded), 17.3.7 (fixed-point conversion occurs after sRGB conversion), and 17.3.6.6 (alpha value for no-alpha buffer is 1).

I took a look at both the GLX and EGL specs but it isn’t well defined how a value is mapped to 0 bits anywhere. Unless you have any other ideas, I can only guess it is implementation defined. It feels like something that should be in a spec though.

Everything that’s in the spec can be implemented faithfully in software if needed. The physical framebuffer is the one thing that cannot be implemented in software. E.g. the SGI Indigo had an 8-bpp indexed-colour framebuffer and emulated true-colour (RGB) visuals with a colour-cube palette and ordered dithering.

Very interesting, that makes sense. I have one last question about fixed-point conversion.

The spec seems to contradict itself in regards to the conversion for signed fixed-point buffers:

15.2.3 Shader Outputs

If the color buffer has a signed or unsigned normalized fixed-point format, color values are assumed to be floating-point and are converted to fixed-point as described in equations 2.4 or 2.3, respectively; otherwise no type conversion is applied.

17.3.7 sRGB Conversion

If the color buffer is fixed-point, each component is clamped to the range [0,1] and then converted to a fixed-point value using equation 2.3.

15.2.3 says signed fixed-point uses equation 2.4 but 17.3.7 does not discriminate between signed and unsigned and only mentions fixed-point conversion always “using equation 2.3”.

Is this because the result is the same in binary either way, or is it a discrepancy?

sRGB is always unsigned. Also, the only sRGB texture (and renderbuffer) formats mentioned in the standard are fixed-point, so the only way you can have a sRGB framebuffer which isn’t fixed point is either via a (as-yet non-existent) extension or if the default framebuffer is floating-point sRGB (which seems rather unlikely).

I agree, and that makes total sense for sRGB formats, however it states that this unsigned conversion applies to non-sRGB (i.e. traditional RGB-like) formats as well.

17.3.7 full quote is:

If FRAMEBUFFER_SRGB is disabled or the value of FRAMEBUFFER_-
ATTACHMENT_COLOR_ENCODING is not SRGB, then

cs = cl.

The resulting cs values for R, G, and B, and the unmodified A form a new
RGBA color value. If the color buffer is fixed-point, each component is clamped
to the range [0,1] and then converted to a fixed-point value using equation 2.3. The
resulting four values are sent to the subsequent dithering operation.

Unless I am reading this wrong, it suggests that a signed fixed-point color buffer will always use the unsigned equation (2.3) for floating to fixed-point conversion and not the signed equation (2.4).

I’m fairly sure that’s a specification bug. I suspect that it originally only described the case where sRGB conversion was actually performed, then when it was updated to describe the no-conversion case the final paragraph was overlooked.

For comparison, the description of equation 2.4 says

That explains my confusion - thanks again for answering my questions!