Jump to content
  • Advertisement
Sign in to follow this  
coderchris

problems with antialiasing on floating point surfaces

This topic is 3815 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

Im working on my HDR system, and im having some problems related to antialiasing As long as the range of colors im rendering to the floating point surface is between 0 and 1, antialiasing works just as you would expect. However, when I render my HDR skybox, with ranges approaching 100, and then have another object that is dimly lit (maybe 0.5), the antialiasing basically isnt antialiased anymore.. It seems like any rendered pixel that has a contrasting color greater than 1, the antialiasing basically goes away.. Is this a fundamental limitation of antialiasing on floating point surfaces or is there something I can do to fix this? Here is an image that shows the problem: Example

Share this post


Link to post
Share on other sites
Advertisement
It's a fundamental problem with the way HDR is usually implemented. This is the common approach:

-Render multi-sampled HDR buffer
-Resolve
-Tone-map

However as you've noticed, this doesn't give effective results in high-contrasts areas. The correct approach is this:

-Render MS HDR buffer
-Tone-map sub-samples
-Resolve

But of course, doing this requires having access to sub-samples in the pixel shader, which is only possible in D3D10 AFAIK. The only other alternative is to do what Valve does in the source engine, which is to tone-map in the pixel-shader rather than as a post-process.

Share this post


Link to post
Share on other sites
Thanks a bunch for the reply, thats been troubling me for quite a while, and your explanation makes perfect sense; its not exactly good news for me though lol

So, basically if i want proper antialiasing here, im going to have to go with valve's approach, since the correct approach isnt really an option for me

Im concerned about performace though; At the moment, my HDR and tonemapping is done entirely on the GPU; if i implemented the valve approach, i think the only two options i have are performing a texture read to get luminance for EVERY pixel that gets rendered, OR read back the luminance to the CPU and pass it as a shader constant...

I like the read-back option, but im pretty sure that would induce a significant stall, though i dont know much about read-backs to draw a good conclusion

Which of these two do you think you be better for performance? or is there another way to implement valves approach that im missing?

Share this post


Link to post
Share on other sites
Reading the luminance as a texture is definitely the way to go. Even though you'd be reading from it for every pixel rendered, you have to remember it's only a 1x1 texture. This means it will most likely stay in the texture cache, and you won't have to worry about bandwidth too much. If you did decide to try some sort of CPU readback, the key would be to properly double or triple-buffer your luminance texture so that when the CPU reads from a texture its not reading from the texture the GPU is currently writing to. Also as an alternative to explicitly calculating luminance you could try to use some sort of heuristic to make an estimate. Perhaps it could be based on screen coverage of the light sources.

Also if you're worried about shader complexity after adding in tone-mapping, I would try using z-only prepass to prevent overdraw.

Share this post


Link to post
Share on other sites
Thanks a bunch for the advice; I implemented the tone mapping in the object's shaders using the texture approach, and it definately looks a ton better with antialiasing. Since i switched to a non-floating point surface, its now much faster as well!

However, im now trying to figure out how to do some kind of bloom, but, since I no longer have an HDR color value, anything thats remotly whitish in color tends to get bloomed which looks nasty. I only want really, really bright things like the sun to get bloomed, but since it gets dumbed down to just plain white, it bets bloomed the same as any other white.

Since i dont have the HDR data, I also cant properly blend in transparent objects.

So, im wondering if there are any tricks or work-arounds for allowing for bloom using the pre-tonemapped data and for rendering transparent objects correctly?

Share this post


Link to post
Share on other sites
Well for the bloom you could perhaps store some kind of intensity value in the alpha channel. That would give you an HDR value you could work with. But of course that could potentially screw up your alpha-blending, at least if you have multiple blended objects on top of one another.

Aside from that I don't really know of any tricks off-hand. It doesn't seem to be a terribly popular technique, although I'd bet there are a few PS3 devs who have used it. Hopefully you can find someone who knows a few, or you come up with some of your own!

Share this post


Link to post
Share on other sites
Ok, so i tried a few different things to get the bloom and transparency to work with doing the tonemapping in the material shaders, and here are my results for anyone tackling the same problem:

First, if you perform the tone mapping the your object's material shaders that means a couple of things right off the bat:
1) if you saturate the tone mapped color, you can store it on a plain old integer surface, allowing antialiasing and HDR even on older hardware
2) if you saturate, you essentially loose the HDR color, meaning it will be more difficult to do proper bloom
3) transparent objects look ok, but since your blending against colors in the 0 - 1 range and not full range, its not as visually accurate as it should be

Now, heres the 3 things i tried to get around the bloom/transparency problem:

1) As MJP suggested, i tried storing a scaled luminance in the alpha channel. This allows very accurate (essentially correct) bloom only on very bright areas. However, as soon as you render any kind of transparent object, it screws up the luminance stored in the alpha and really mangles the image.

2) The next thing i tried is a bit odd; Basically, i do a high pass filter in the object's material shaders at the same time as the tone mapping. When i finally write out the color, I do one of two things; If it did not qualify as bright enough for bloom, I clamp the color between 0 and 0.99. However, if it did qualify as bright enough for bloom, I clamp it between 0 and 1. Then, in the post process bloom shader, when reading the color from the frame texture, I check if any of the components are 1. If so, that means its bright enough that it should be bloomed. This works surprisinly well and gives a near accurate representation of bloom, while still allowing transparent objects because the alpha channel is unused. Transparency still isnt completely right though.

3) The final thing I tried was not saturating the output from the material shaders and going back to a floating point surface, but still doing the tone mapping inside the material shaders. This means that I still essentially have the full HDR data to work with (just need to "un-tonemap" it). Transparency works correctly in this case, and bloom works correctly also. However, because I dont saturate, I can still get the original aliasing problems in high contrast areas, though the aliasing is MUCH less visible since I tone map in the material shaders. However, I found that if bloom is enabled, it basically hides any aliasing that existed. Also, the hardware must support MSAA on floating point surfaces for this to work. THis is the one i ended up using.

Anyway, hopefully this helps anyone that comes across this problem in the future

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!