Let’s illustrate this process in a step by step fashion.
1.
(先正常渲染场景)
We render a scene filled with 4 bright light sources visualized as colored cubes. The colored light cubes have a brightness values between 1.5 and 15.0. If we were to render this to an HDR colorbuffer the scene looks as follows:
2.
(通过一个阈值,输出亮度超过阈值的颜色值,保存到一张brightness texture 中)
/ check whether result is higher than some threshold, if so, output as bloom threshold color
float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722));
if(brightness > 1.0)
BrightColor = vec4(result, 1.0);
else
BrightColor = vec4(0.0, 0.0, 0.0, 1.0);
We take this HDR colorbuffer texture and extract all the fragments that exceed a certain brightness. This gives us an image that only shows the bright colored regions as their fragment intensities exceeded a certain threshold:
3.
(模糊 brightness texture ,得到 blur texture)
We then take this thresholded brightness texture and blur the result. The strength of the bloom effect is largely determined by the range and the strength of the blur filter used.
4.
(把 blur texture 和 第一个步骤的正常渲染的图进行叠加,而且还会涉及到tone mapping得到下图结果)
void main()
{
const float gamma = 2.2;
vec3 hdrColor = texture(scene, TexCoords).rgb;
vec3 bloomColor = texture(bloomBlur, TexCoords).rgb;
if(bloom)
hdrColor += bloomColor; // additive blending
// tone mapping
vec3 result = vec3(1.0) - exp(-hdrColor * exposure);
// also gamma correct while we're at it
result = pow(result, vec3(1.0 / gamma));
FragColor = vec4(result, 1.0);
}
The resulting blurred texture is what we use to get the glow or light-bleeding effect. This blurred texture is added on top of the original HDR scene texture. Because the bright regions are extended in both width and height due to the blur filter the bright regions of the scene appear to glow or bleed light.