Light Corona

Started by
16 comments, last by szecs 13 years, 12 months ago
Hello, I'm planning to add a corona effect to some of my lights. I guess the most straightforward way, is to use a textured billboard. What I'm curious about, is how to choose it's size ect. Because it should grow somehow if I move away from the light, right? Another thing that influences size, is how much of the light source is visible or something like that. If the light-source is occluded there is no corona although the billboard could be so big as to be seen despite the occluder. Is this generally handled with occlusion queries? Thanks for any tips.
Advertisement
I can tell you only one thing. Look into the real life behavior. (That's the base of all effects).

How does corona behave? For example, if a light is occluded entirely, I think there is no corona at all. Corona is a lens effect (if I'm talking about the same thing as you are), and lens effects only occur, when the light source is visible, and of course, the effect is not occluded, since it arises "inside" the lens. And the strength of the effect depends on the amount of light that reaches the lens. So the less the (apparent) luminosity, the more "transparent" the effect is. For the size: That's an other question. My guess is that the size of the corona depends of luminosity (I would try something like this: radius = apparent_luminosity * constant1 + constant2). But since the transparency affects the visible size of the corona, I don't know. Try to look at films, real life, whatever to track down the behavior, and enchant your effect until it looks like that (or simply looks good enough).

And yup, occlusion test can be used for that.

I hope that helps.
Yes, I think we are talking about the same thing. First I thought there might be some best practices for coronas or something like that. But you are right that it all probably depends on the lens involved.
But I'm sure there must exist some info on how to determine how much light reaches the lens. The part about occlusion queries I mean. How would/do you do it?
I haven't used occlusion yet, but AFAIK it (or at least an extension of it) can be used to actually count the pixels, that pass the test. So draw a small sphere, or camera aligned circle during the test to the position of the light (size can be the same as the light-bulb, or just make it look/feel good), after everything else is drawn. The test will return the number of pixels that passed the test. This is not very precise of course and will produce a popping effect, but if you use some kind of interpolation between the frames, you can make it look good enough. I can't really think of more precise solutions.

And an important thing, the size of the effect (not the one used in the occlusion test) is in screen coordinates. Lens effect sizes are always in screen coordinates (since they arise inside the lens). So the distance of the light doesn't matter directly. All that matters is the apparent luminosity.
Anybody who has used occlusion queries for this kind of thing?

Quote:Original post by szecs
And an important thing, the size of the effect (not the one used in the occlusion test) is in screen coordinates. Lens effect sizes are always in screen coordinates (since they arise inside the lens). So the distance of the light doesn't matter directly. All that matters is the apparent luminosity.

Hm, I suppose you are right. But somehow I have this idea, that it would look right to have the size be dependent on the distance.

Quote:Original post by B_old
Anybody who has used occlusion queries for this kind of thing?


I've never implemented something like this before, but I'd imagine that occlusion queries are the way to go. They're pretty straightforward to use...you just may need to double buffer to avoid having to flush.

Humus has a sample on using occlusion queries to fade in/out coronas.
Thanks for the tips and the link!

Quote:Original post by MJP
They're pretty straightforward to use...you just may need to double buffer to avoid having to flush.

Hm, how do I find out whether a flush would be needed? Looking over this quickly, I couldn't find any info on such things.

[Edited by - B_old on April 26, 2010 2:34:09 AM]
I implemented coronas recently using the depth buffer instead of occlusion queries.
I calculate the Z-buffer value of the center of the corona on the CPU, then every pixel of the corona compares this CPU-calculated value with the actual Z-value at the center of the corona. If the actual value is smaller, then the center is occluded and I use clip/texkill instruction to make the PS fail the alpha test and not draw anything.

On the CPU:
  copy depth buffer, bind to sampler  for each corona sprite    pos = center of the corona sprite    screenPos = pos * viewProjection    centerTexCoord = convert screenPos from post-proj space into texture space    centerDepth = screenPos.z / screenPos.w    put centerTexCoord and centerDepth into a uniform float4    draw the corona sprite
In the VS
  pos = usual billboard sprite stuff
In the PS
  color = usual PS stuff... get diffuse texture  expectedDepth = centerDepth uniform  actualDepth = tex2d( depthBuffer sampler, centerTexCoord uniform )  if( actualDepth < expectedDepth )    fail alpha test, i.e. don't draw this pixel
Hodgman, it sounds like you either fully draw the coronas or you don't at all. There is no fading. Is that true, or did I get the wrong impression?

Also, in case anyone jumps aboard this thread, I'm still very much interested in the occlusion query stuff. I generally don't have a good grasp about the details. For example, do most people wait for the result in the current frame, or do they gather them later. I don't understand how that would work in case you use occlusion queries for culling, as the result might be worthless by the time it arrives.

This topic is closed to new replies.

Advertisement