+ // Set intermediate format for framebuffers used when we need to bounce
+ // to a temporary texture. The default, GL_RGBA16F, is good for most uses;
+ // it is precise, has good range, and is relatively efficient. However,
+ // if you need even more speed and your chain can do with some loss of
+ // accuracy, you can change the format here (before calling finalize).
+ // Calculations between bounce buffers are still in 32-bit floating-point
+ // no matter what you specify.
+ //
+ // Of special interest is GL_SRGB8_ALPHA8, which stores sRGB-encoded RGB
+ // and linear alpha; this is half the memory bandwidth og GL_RGBA16F,
+ // while retaining reasonable precision for typical image data. It will,
+ // however, cause some gamut clipping if your colorspace is far from sRGB,
+ // as it cannot represent values outside [0,1]. NOTE: If you construct
+ // a chain where you end up bouncing pixels in non-linear light this
+ // will not do the wrong thing. However, it's hard to see how this
+ // could happen in a non-contrived chain; few effects ever need texture
+ // bounce or resizing without also combining multiple pixels, which
+ // really needs linear light and thus triggers a conversion before the
+ // bounce.
+ //
+ // If you don't need alpha (or can do with very little of it), GL_RGB10_A2
+ // is even better, as it has two more bits for each color component. There
+ // is no GL_SRGB10, unfortunately, so on its own, it is somewhat worse than
+ // GL_SRGB8, but you can set <transformation> to SQUARE_ROOT_FRAMEBUFFER_TRANSFORMATION,
+ // and sqrt(x) will be stored instead of x. This is a rough approximation to
+ // the sRGB curve, and reduces maximum error (in sRGB distance) by almost an
+ // order of magnitude, well below what you can get from 8-bit true sRGB.
+ // (Note that this strategy avoids the problem with bounced non-linear data
+ // above, since the square root is turned off in that case.)
+ void set_intermediate_format(
+ GLenum intermediate_format,
+ FramebufferTransformation transformation = NO_FRAMEBUFFER_TRANSFORMATION)
+ {
+ this->intermediate_format = intermediate_format;
+ this->intermediate_transformation = transformation;
+ }
+