<p>At CEDEC and GDC in the early 2000s, Masaki Kawase has presented a series of fast post-processing based lens effects, including large bloom.</p>

<p>This presentation from GDC 2003, <a href="http://www.daionet.gr.jp/~masa/archives/GDC2003_DSTEAL.ppt">Frame Buffer Postprocessing Effects in DOUBLE-S.T.E.A.L (Wreckless)</a> (see slides 15 and upwards: <em>"Bloom"</em>), gives a first version of the bloom. It consists in doing a Gaussian blur by sampling at exponentially increasing distances.</p>

<p>In this presentation from GDC 2004, <a href="http://www.daionet.gr.jp/~masa/archives/GDC2004/GDC2004_PIoHDRR_EN.ppt">Practical Implementation of High Dynamic Range Rendering</a> (see slides 44 and upward: <em>"Glare generation"</em>), he updates the technique. Instead of varying the sampling distance, he uses downsized versions of the original image, using a carefully crafted equation to achieve a large yet spiky Gaussian blur.</p>

CC BY-SA 3.0
2017-01-28T04:24:46.707Z
Is there a fast way to downscale a texture? I generally create an offscreen FBO of the smaller size and then have the most generic full-screen texture renderer render onto the smaller FBO. After that I have the original texture and a FBO with the smaller texture. Is that the proper way to do it?
J.Doe
CC BY-SA 3.0
2017-01-28T06:53:05.113Z
@J.Doe: That's how I do it too.
Julien Guertault
CC BY-SA 3.0
2017-01-28T13:00:43.373Z
If memory usage is not an issue, you can use summed area tables to get arbitrary sized box filtering in just two lookups. I don't have the links right here, but if I'm not mistaken, people have extended that to approximate Gaussian blur with a small series of SAT lookups.
Stefan Werner
CC BY-SA 3.0
2017-01-27T03:06:37.117Z
2017-01-27T03:12:40.317Z
2017-01-27T03:12:40.317Z
Julien Guertault
<p>One way to speed things up if you're doing this on a mobile GPU is to avoid indirect texture look-ups. This is where you calculate the texture coordinates then use the results of that calculation in the call to sample the texture. So it might be natural to write a 3-tap blur fragment shader doing something like this:</p>

<pre><code>sample1 = texture2D(inputTexture, gl_TexCoord [ 0 ] - vec2(1.0, 0.0));
sample2 = texture2D(inputTexture, gl_TexCoord [ 0 ]);
sample3 = texture2D(inputTexture, gl_TexCoord [ 0 ] + vec2(1.0, 0.0));
</code></pre>

<p>You can get around this by doing the calculation in the vertex shader or on the CPU. You can use multi texturing to get around this when you have very straightforward situations like above. You can set texture coordinates for textures 1 and 2 to be offset by 1 pixel in either direction from those in texture 0. Your fragment shader then becomes:</p>

<pre><code>sample1 = texture2D(inputTexture, gl_TexCoord [ 0 ]);
sample2 = texture2D(inputTexture, gl_TexCoord [ 1 ]);
sample3 = texture2D(inputTexture, gl_TexCoord [ 2 ]);
</code></pre>

<p>Now you're not doing any calculations to figure out texture coordinates.</p>

CC BY-SA 4.0
2019-09-24T21:18:52.320Z
I'd argue that sending the extra data from vertex to fragment shader is not worth it. Additionally, sampling a texture is way more expensive than the arithmetic of adding 2 vectors. Have you measured performance and concluded that your proposed method is indeed faster?
Paul Houx
CC BY-SA 4.0
2019-09-25T00:59:39.953Z
I have absolutely measured it and shown a significant performance increase. The slowdown isn't from the time it takes to do the arithmetic. Apparently the shader compiler can optimize away a bunch of stuff if there's no math, so that's where the speedup comes in. This is probably less true of modern desktop GPUs, but the last time I checked mobile GPUs (which was probably around 2017 when I wrote this answer), it was still a win.
user1118321
CC BY-SA 3.0
2017-01-27T06:38:04.500Z
2017-01-27T06:38:04.500Z
user1118321
<p>I am in awe at <a href="https://play.google.com/store/apps/details?id=com.volutopia.forgeofneon3d&amp;hl=en" rel="nofollow noreferrer">this app</a> I just found. It was actually one of the first things I installed when I first bought my iPad 2 but now they have updated it to add an HDR effect.</p>

<p>I have never seen a real-time glow effect that looked quite this amazing. I have no clue how the developer pulled off such a large radius in realtime graphics.</p>

<p><a href="https://i.sstatic.net/fTjVa.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/fTjVa.png" alt="enter image description here"></a></p>

<p>I have a game with similar unprocessed graphics to his. I have been trying to get a glow effect like this working but it has been near impossible. I am currently using separable convolution gaussian blur methods in addition to downscaling my blur mask. Still, it barely runs in real-time. It is nowhere near as big as a radius as this app pulls off and it certainly isn't as good of quality.</p>

<p>Is there some method I am not thinking of?</p>

<p>I am open to the possibility (but doubtful) that they are using really large textures with a falloff distance or that lighting is computed from the distance from a fragment to light sources. If you play with it and notice when the FPS drops it it just doesn't seem to have the right FPS to particle amount and HDR on/off quality to it to be that.</p>

CC BY-SA 3.0
2017-01-27T02:26:02.647Z
The effect is typically called "bloom". Here's [a previous question on bloom implementation](http://computergraphics.stackexchange.com/questions/4221/bloom-in-directx), and [another related question](http://computergraphics.stackexchange.com/questions/3706/tweaking-a-glow-shader-to-make-it-look-better).
Nathan Reed
CC BY-SA 3.0
2017-01-27T02:32:40.660Z
Heh, I just noticed that second one was one you posted. :) Anyway, the key to getting large bloom radius is to do repeated steps of downsampling and blurring—kind of like making a mip chain—then summing together all the blurred textures in the final pass.
Nathan Reed
CC BY-SA 3.0
2017-01-27T05:18:36.323Z
@NathanReed Yah! Still working on it. Using that technique got me something quite good looking but it can't run real-time. I have however added a button that freezes the game and then exports it with all the pretty post processing using that technique.
J.Doe
<lighting><gaussian-blur>
How does this app pull off fast, high radius HDR
J.Doe
# How does this app pull off fast, high radius HDR

(Asked by: username_0 on 2017-01-27)

I am in awe at [this app](https://play.google.com/store/apps/details?id=com.volutopia.forgeofneon3d&hl=en) I just found. It was actually one of the first things I installed when I first bought my iPad 2 but now they have updated it to add an HDR effect.

I have never seen a real-time glow effect that looked quite this amazing. I have no clue how the developer pulled off such a large radius in realtime graphics.

[![enter image description here](https://i.sstatic.net/fTjVa.png)](https://i.sstatic.net/fTjVa.png)

I have a game with similar unprocessed graphics to his. I have been trying to get a glow effect like this working but it has been near impossible. I am currently using separable convolution gaussian blur methods in addition to downscaling my blur mask. Still, it barely runs in real-time. It is nowhere near as big as a radius as this app pulls off and it certainly isn't as good of quality.

Is there some method I am not thinking of?

I am open to the possibility (but doubtful) that they are using really large textures with a falloff distance or that lighting is computed from the distance from a fragment to light sources. If you play with it and notice when the FPS drops it it just doesn't seem to have the right FPS to particle amount and HDR on/off quality to it to be that.

**Tags:** lighting, gaussian-blur

> **Comments:**
> **username_1**: The effect is typically called "bloom". Here's [a previous question on bloom implementation](http://computergraphics.stackexchange.com/questions/4221/bloom-in-directx), and [another related question](http://computergraphics.stackexchange.com/questions/3706/tweaking-a-glow-shader-to-make-it-look-better).  
> **username_1**: Heh, I just noticed that second one was one you posted. :) Anyway, the key to getting large bloom radius is to do repeated steps of downsampling and blurring—kind of like making a mip chain—then summing together all the blurred textures in the final pass.  
> **username_0**: @username_1 Yah! Still working on it. Using that technique got me something quite good looking but it can't run real-time. I have however added a button that freezes the game and then exports it with all the pretty post processing using that technique.  

---

## 2 answers

### Answer by username_2 on 2017-01-27. Score: 4

At CEDEC and GDC in the early 2000s, Masaki Kawase has presented a series of fast post-processing based lens effects, including large bloom.

This presentation from GDC 2003, [Frame Buffer Postprocessing Effects in DOUBLE-S.T.E.A.L (Wreckless)](http://www.daionet.gr.jp/~masa/archives/GDC2003_DSTEAL.ppt) (see slides 15 and upwards: *"Bloom"*), gives a first version of the bloom. It consists in doing a Gaussian blur by sampling at exponentially increasing distances.

In this presentation from GDC 2004, [Practical Implementation of High Dynamic Range Rendering](http://www.daionet.gr.jp/~masa/archives/GDC2004/GDC2004_PIoHDRR_EN.ppt) (see slides 44 and upward: *"Glare generation"*), he updates the technique. Instead of varying the sampling distance, he uses downsized versions of the original image, using a carefully crafted equation to achieve a large yet spiky Gaussian blur.

> **Comments:**
> **username_0**: Is there a fast way to downscale a texture? I generally create an offscreen FBO of the smaller size and then have the most generic full-screen texture renderer render onto the smaller FBO. After that I have the original texture and a FBO with the smaller texture. Is that the proper way to do it?  
> **username_2**: @username_0: That's how I do it too.  
> **username_3**: If memory usage is not an issue, you can use summed area tables to get arbitrary sized box filtering in just two lookups. I don't have the links right here, but if I'm not mistaken, people have extended that to approximate Gaussian blur with a small series of SAT lookups.  

---

### Answer by username_4 on 2017-01-27. Score: 2

One way to speed things up if you're doing this on a mobile GPU is to avoid indirect texture look-ups. This is where you calculate the texture coordinates then use the results of that calculation in the call to sample the texture. So it might be natural to write a 3-tap blur fragment shader doing something like this:

```
sample1 = texture2D(inputTexture, gl_TexCoord [ 0 ] - vec2(1.0, 0.0));
sample2 = texture2D(inputTexture, gl_TexCoord [ 0 ]);
sample3 = texture2D(inputTexture, gl_TexCoord [ 0 ] + vec2(1.0, 0.0));

```

You can get around this by doing the calculation in the vertex shader or on the CPU. You can use multi texturing to get around this when you have very straightforward situations like above. You can set texture coordinates for textures 1 and 2 to be offset by 1 pixel in either direction from those in texture 0. Your fragment shader then becomes:

```
sample1 = texture2D(inputTexture, gl_TexCoord [ 0 ]);
sample2 = texture2D(inputTexture, gl_TexCoord [ 1 ]);
sample3 = texture2D(inputTexture, gl_TexCoord [ 2 ]);

```

Now you're not doing any calculations to figure out texture coordinates.

> **Comments:**
> **username_5**: I'd argue that sending the extra data from vertex to fragment shader is not worth it. Additionally, sampling a texture is way more expensive than the arithmetic of adding 2 vectors. Have you measured performance and concluded that your proposed method is indeed faster?  
> **username_4**: I have absolutely measured it and shown a significant performance increase. The slowdown isn't from the time it takes to do the arithmetic. Apparently the shader compiler can optimize away a bunch of stuff if there's no math, so that's where the speedup comes in. This is probably less true of modern desktop GPUs, but the last time I checked mobile GPUs (which was probably around 2017 when I wrote this answer), it was still a win.  

---

