6
\$\begingroup\$

I'm making a neon style game where everything is glowing but the glow I have is kinda small and I want to know if there's an efficient way to increase the size of it other than increasing the pixel sample iterations.

Right now I have something like this:

float4 glowColor = tex2D(glowSampler, uvPixel);

//Makes the inital lines brighter/closer to white
if (glowColor.r != 0 || glowColor.g != 0 || glowColor.b != 0)
{
    glowColor += 0.5;
}

//Loops over the weights and offsets and samples from the pixels based on those numbers
for (int i = 0; i < 20; i++)
{
    glowColor += tex2D(glowSampler, uvPixel + glowOffsets[i] + 0.0018) * glowWeights[i];
}

finalColor += glowColor;

for the offsets it moves up, down, left and right (5 times each so it loops over 20 times) and the weights just lower the glow amount the further away it gets.

The method I was using before to increase it was to increase the number of iterations from 20 to 40 and to increase the size of the offset/weight array but my computer started to have FPS drops when I was doing this so I was wondering how can I make the glow bigger/more vibrant without making it so CPU/Gcard intensive?

\$\endgroup\$
5
\$\begingroup\$

There are two common approaches, both of which can be used together or independently. The first assumes you have some kind of "bright pass" that renders the "glow" texture. Because blurring inherently produces low-frequency results, you should be able to reduce the resolution of this pass, so the same number of samples cover a larger fraction of the screen area.

The second approach is to take advantage of the fact that blur is typically separable. You can therefore use a two-pass approach, blurring in only one direction in the first pass (e.g. horizontal), then in another in the second pass (vertical). This reduces the total number of samples from N^2 to 2N, though there is some overhead for multi-pass in general.

There is a third approach, but it does not seem like it would work for your case (since it looks like you're doing colored blurs). This option involves using the Gather method to get 4 samples from one call, reducing the total number of samples required by a factor of 4. This only works for single-channel color, however.

\$\endgroup\$
  • \$\begingroup\$ The first approach sounds quite nice, what exactly would I have to do? Just lower the size/resolution of the initial render texture that gets passed into the glow shader? My math isn't that great so I'm not sure how big a difference N^2 to 2N would make, but if I separated it into multiple passes (including the overhead of a multi-pass shader) would it make a big difference or would it only improve it a tiny bit? \$\endgroup\$ – user1157885 Oct 22 '13 at 14:12
  • 1
    \$\begingroup\$ There's a tutorial here: gamerendering.com/2008/10/11/gaussian-blur-filter-shader \$\endgroup\$ – dsilva.vinicius Oct 22 '13 at 14:40
1
\$\begingroup\$
if (glowColor.r != 0 || glowColor.g != 0 || glowColor.b != 0)
{
    glowColor += 0.5;
}

could be written as

>  if (any(glowColor.rgb))  
>  {
>      glowColor += 0.5;  
>  }

I did't try but this also could work:

glowColor += 0.5 * sign(any(glowColor.rgb));
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.