Original Post
OK I have a project and I'm already doing post-processing for glow and motion blur effects, so I thought that I'd be able to add bloom in pretty simply. And I can, and it works. The problem is it's pretty slow. My basic algorithm is this: * Sample the source image. I sample in a cross shape, so for N steps (I usually use 2-4) I sample 4*N + 1 times. This is the same way I sample the glow map to do glow effects. * Get the intensity of the pixel, and calculate a bloom factor. I've tried: a. Bloom factor = intensity (highest performance, but there's no thresholding at all -- each pixel contributes bloom proportional to its apparent brightness.) b. Bloom factor = (intensity > threshold) ? 1 : 0; (better results, lower performance) c. Bloom factor = a sigmoidal threshold such as an arctan (interesting results, quite slow) * Multiply the sample pixel by its bloom factor by the global bloom weight and add it to my glow calculated for that point. Relevant HLSL. For brevity's sake I cut out the parts relating to the glow map (for incandescent objects) and parts relating to the other post-processing effects. So you can rest assured that variables are properly set up and such; the effect works, it's just pretty slow.
float4 Threshold(float4 pixel)
{
float intensity = dot(pixel, float4(0.30, 0.59, 0.11, 0)); // Linear intensity
//intensity = (atan((intensity-bloomThreshold)*1024) / 3.141592) + 0.5; // Sigmoidal threshold
//intensity = (intensity > bloomThreshold)? 1 : 0; // Simple threshold
return pixel * intensity;
}
float4 PSGlow(float2 TexCoord:TEXCOORD0) : COLOR0 {
// Some setting up variables here
if (bloomWeight > 0)
glow += Threshold(pic) * bloomWeight;
for (int i=0;i < glowSamples;i++) {
offset = i * (glowDisplacement / glowSamples);
float2 samp1, samp2, samp3, samp4;
samp1 = float2(saturate(TexCoord.x+offset),TexCoord.y);
samp2 = float2(saturate(TexCoord.x-offset),TexCoord.y);
samp3 = float2(TexCoord.x,saturate(TexCoord.y + offset));
samp4 = float2(TexCoord.x,saturate(TexCoord.y - offset));
// Some glow calculations here
if (bloomWeight > 0)
{
glow += Threshold(tex2D(inTexture1, samp1)) * bloomWeight;
glow += Threshold(tex2D(inTexture1, samp2)) * bloomWeight;
glow += Threshold(tex2D(inTexture1, samp3)) * bloomWeight;
glow += Threshold(tex2D(inTexture1, samp4)) * bloomWeight;
}
}
// Other processing effects here
}
Is there a better/faster way to do bloom? I think one way in which I can potentially improve it would be by making bloom only from certain textures (such as a sky texture), and just render it straight into the glowmap, so I don't have to sample the glow map and then sample the source frame both (the glow map is sampled by the same kind of loop as the source frame). [Edited by - Goil on July 18, 2008 7:04:48 PM]