Jump to content
  • Advertisement
Sign in to follow this  
Piyush Verma

OpenGL Texture Masking for Pseudo-Lens Flares

This topic is 885 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've implemented John Chapman's Pseudo lens-flare in my OpenGL project and the result somewhat looks like this:

 

 

rLVuppV.png

 

 

What I'm trying to figure out is, how can I use a simple hexagonal or a circle texture to mask each lens flare "ghost" to make look somewhat more like this:

 

 

flareset3.jpg

 

 

Here's a fragment shader snippet where I'm calculating the lens flare ghosts and adding them to the sun shafts: 

 

vec3 texture2DDistorted(sampler2D Texture, vec2 TexCoord, vec2 Direction, vec3 Distortion)
{
    return vec3(
        texture2D(Texture, TexCoord + Direction * Distortion.r).r,
        texture2D(Texture, TexCoord + Direction * Distortion.g).g,
        texture2D(Texture, TexCoord + Direction * Distortion.b).b
    );
}

// Calculate Lens flare ghosts
// this is inside main()
texCoord = vec2(1.0) - uv;
vec2 texelSize = 1.0 / vec2(textureSize(lightScene, 0));
vec3 Distortion = vec3(-texelSize.x * distortion, -texelSize.y * distortion, texelSize.x * distortion);
vec2 ghostVec = (vec2(0.5) - texCoord) * dispersal;
direction = normalize(ghostVec);
vec3 result = vec3(0.0);
for (int i = 0; i < ghosts; i++)
{
	vec2 offset = fract(texCoord + ghostVec * float(i));
	float weight = length(vec2(0.5) - offset) / length(vec2(0.5));
	result += texture2DDistorted(lightScene, offset, direction, Distortion) * weight;
}

// Radial gradient of 1D rainbow color texture
result *= texture(lensColor, length(vec2(0.5) - texCoord) / length(vec2(0.5))).rgb;

I add the result to the final color value in the shader. Is there a way to mask the color value of these ghosts with the hexagon texture so that they look more shaped like an actual lens flare rather than just blurred out blobs? I feel like it should be pretty straight forward, but at the same time I'm pretty much stumped about how to do it. 

Edited by pslayer89

Share this post


Link to post
Share on other sites
Advertisement

>> I've implemented John Chapman's Pseudo lens-flare in my OpenGL project and the result somewhat looks like this:

 

you are aware that lens flare is a real world graphic artifact of images viewed though lenses, right?

 

and that it should not occur unless the image is viewed though a lens, IE on a view screen, and never when as seen by the human eye.

 

but it does look cool - doesn't it? <g>.

 

FYI, the characteristics of a lens flare (shape etc) are a function of the geometry of the lens in question.  so two different lenses will produce two different flares under identical conditions.

Edited by Norman Barrows

Share this post


Link to post
Share on other sites

Blurring one image using another image is a convolution filter. The straightforward way of doing it is extremely expensive - it's O(N * M), where N is your pixels to be blurred, and M is the pixels in the shape image.

So a 64x64 pixel shape requires your blur pixel shader to perform four thousand texture fetches, which obviously isn't practical :wink:

 

Instead of using a "gather" based technique, it's much more efficient to use a "scatter" based technique.

i.e. instead of:

  for each pixel, gather pixels within the shape-blur area if this area contains a flare source.

to use:

  for each pixel, if a flare source, scatter blur shape to the surrounding areas.

 

These kind of scatter-based effects can't be done with simple post-processing shaders. You need to use UAV's/SSBO's for read-write access, or more likely: you need a two-pass technique, where the first pass generates some geometry (stream out / transform feedback / compute to generate vertices), and then the second pass renders that geometry to draw the blur sprites.

 

The same problem is faced with DOF effects that want to use a custom/textured "bokeh" shape. You might find something by searching for Bokeh shaders.

 

However, instead of doing a fancy modern GPU based scatter blur shader, you can just go old-school instead. Modern GPU-based lens flares have the advantage of allowing any bright pixels to create a lens flare, but, in your screenshots it looks like you only need the sun to create a lens flare.

On the CPU, you can determine where the sun is going to be on the screen, and then define a 2D line that passes through this sun position and the centre of the screen. Along this 2D line, you can then place several different sprites of your lens flare shapes, and you're done :)

Share this post


Link to post
Share on other sites

@Hodgin

 

I am not really aware of how SSBOs work yet, but I'll definitely take a look at that. But regarding the other approach you mentioned, wouldn't it be an expensive task to calculate the vector between the sun and the center of the camera, and rendering sprites based on the vector? Also, would using a uniform buffer object for sprites help with the performance? 

Also, if I understand correctly, according to the GPU technique, we get the bright spots and calculate the flare geometry (positions) in the shader, and read that using the SSBO, and then render the flares using that data? 

Please feel free to correct me if I interpreted your solution wrongly. 

 

Thanks a lot for the suggestions. :)

Share this post


Link to post
Share on other sites

But regarding the other approach you mentioned, wouldn't it be an expensive task to calculate the vector between the sun and the center of the camera, and rendering sprites based on the vector? Also, would using a uniform buffer object for sprites help with the performance?

No, it's ridiculously cheap!
You can probably do it on the CPU in less than a microsecond. Any sprite rendering technique can be used, such as creating dynamic vertex data from the CPU, etc...
Last time I used this technique, we had a static VBO containing half a dozen quads. Each quad's vertex had an attribute to identify which corner it was ([0,0] to [1,1]), and an attribute identifying which quad it belonged to (0,1,2...). The vertex shader then received the sun position from a UBO, computed the line, and then placed the quads at the appropriate positions.
This will be a thousandfold cheaper than any technique based on actually analyzing the framebuffer for bright areas :) It's how every 90's game achieved lens flares :lol:
 

Also, if I understand correctly, according to the GPU technique, we get the bright spots and calculate the flare geometry (positions) in the shader, and read that using the SSBO, and then render the flares using that data?

Yep. This gives automatic flares on any bright surface, but is very complex.

Share this post


Link to post
Share on other sites

 

 

No, it's ridiculously cheap!
You can probably do it on the CPU in less than a microsecond. Any sprite rendering technique can be used, such as creating dynamic vertex data from the CPU, etc...
Last time I used this technique, we had a static VBO containing half a dozen quads. Each quad's vertex had an attribute to identify which corner it was ([0,0] to [1,1]), and an attribute identifying which quad it belonged to (0,1,2...). The vertex shader then received the sun position from a UBO, computed the line, and then placed the quads at the appropriate positions.
This will be a thousandfold cheaper than any technique based on actually analyzing the framebuffer for bright areas  :) It's how every 90's game achieved lens flares  :lol:

 

Thanks a lot for explaining it in detail. I think I should be able to implement it based on the info you provided. 

 

 

Yep. This gives automatic flares on any bright surface, but is very complex.

 

I was actually planning on implementing something that is used in games/engines currently and would be a bit more flexible. That said, I think both techniques have their own uses based on the current scenario. I think I'll implement both eventually haha. Thanks again, for putting in the time to explain the solutions. 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!