HDR + Tonemapping + Skylight = Fail?

Started by
52 comments, last by riuthamus 11 years, 8 months ago
I'm not sure how to try different tone mapping algorithms or how to even adjust the one we have. I adapted the code from here to work in our project: http://www.xnainfo.com/content.php?content=28. The tone mapping code from that looks like this:


float g_fMiddleGrey = 0.3f;
float g_fMaxLuminance = 16.0f;

static const float3 LUM_CONVERT = float3(0.299f, 0.587f, 0.114f);

float3 ToneMap(float3 vColor)
{
// Get the calculated average luminance
float fLumAvg = SourceTexture1.Sample(PointSampler, float2(0.5f, 0.5f)).r;

// Calculate the luminance of the current pixel
float fLumPixel = dot(vColor, LUM_CONVERT);

// Apply the modified operator (Eq. 4)
float fLumScaled = (fLumPixel * g_fMiddleGrey) / fLumAvg;
float fLumCompressed = (fLumScaled * (1 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1 + fLumScaled);
return fLumCompressed * vColor;
}


I've tried adjusting the constants, nothing seemed to change really. Ive also looked at the code from the DX sample and from this site: http://filmicgames.com/archives/75 but I have no idea how to adapt it to work with what I have
Advertisement
Yeah, so this is more or less the issue... i guess. Our implementation is off or we are stuck with trying to modify it... hm...
On my last game, we just gave our sky dome shader a 'brightness multiplier' so we could tweak it until it looked right. IIRC we went with something like the sky being 10x brighter than our average spot lights, but in real-life the sky is more like 10000x brighter than a light-bulb...
Interesting... that is something we might be able to try. We removed the complicated sky and added in a basic one to see if that was causing the problem but it was not. We will see what doing the brightness, would do. Thanks!
Which tonemapper are you using? I had a lot of trouble getting it to look right for my project, but the uncharted 2 filmic mapping method ended up looking great. The cause could either be the tone mapping algorithm itself, or just incorrect light values in your scene. From your screenshots, it looks like the tone mapper itself isn't set up right.
I think the reason for the problem is a combination of drawing the sky to the gbuffer's color RT (which is a R8G8B8A8_UNORM_SRGB surface) and that the final composite gbuffer RT is also in that format. If I switch them to 64 bit formats everything seems to work then. If I do that though, we end up with 4 (and probably more from the intermediate RTs) of these 64 bit fullscreen RTs, which uses quite a bit of memory. I can avoid that if I use LogLuv encoding, but then the image looks weird when using an _SRGB surface. Does the SRGB gamma correction not work with LogLuv? Is there a way around that?
I think the reason for the problem is a combination of drawing the sky to the gbuffer's color RT (which is a R8G8B8A8_UNORM_SRGB surface)
Usually the GBuffer stores surface albedo, which is a 0-1 fractional/percentage value. A skydome is more like an emissive surface though, than a regular diffuse surface, so yeah, it doesn't make sense to render it into your GBuffer's albedo channels. When adding emissive surfaces to a deferred renderer, the usual approach is to render these surfaces directly into your light-accumulation buffer, instead of into the GBuffer.

Regarding SRGB and LogLUV: when using an SRGB texture, it will go through a linear->gamma transform when writing, and a gamma->linear transform when sampling, so it shouldn't have much of an impact, but it can mean that the value that you sample later is slightly different to the value that you wrote originally. This transform is only designed to be used to store RGB "colour" information in a perceptually efficient way (distributing more bits to darker colours) where it doesn't matter if there is a slight change in the values.
However, LogLUV splits the L component over 2 8-bit channels, and if either of those channels is slightly modified, then when you reconstruct the original 16-bit value, it will be wildly different. This makes it more of a "data" texture than a "colour" texture, and so SRGB encoding should not be used.

[quote name='Telanor' timestamp='1345966702' post='4973421']I think the reason for the problem is a combination of drawing the sky to the gbuffer's color RT (which is a R8G8B8A8_UNORM_SRGB surface)
Usually the GBuffer stores surface albedo, which is a 0-1 fractional/percentage value. A skydome is more like an emissive surface though, than a regular diffuse surface, so yeah, it doesn't make sense to render it into your GBuffer's albedo channels. When adding emissive surfaces to a deferred renderer, the usual approach is to render these surfaces directly into your light-accumulation buffer, instead of into the GBuffer.

Regarding SRGB and LogLUV: when using an SRGB texture, it will go through a linear->gamma transform when writing, and a gamma->linear transform when sampling, so it shouldn't have much of an impact, but it can mean that the value that you sample later is slightly different to the value that you wrote originally. This transform is only designed to be used to store RGB "colour" information in a perceptually efficient way (distributing more bits to darker colours) where it doesn't matter if there is a slight change in the values.
However, LogLUV splits the L component over 2 8-bit channels, and if either of those channels is slightly modified, then when you reconstruct the original 16-bit value, it will be wildly different. This makes it more of a "data" texture than a "colour" texture, and so SRGB encoding should not be used.
[/quote]

Thank you, this is very informative. We got part of it working, once we get the overblur fixed I will show you guys... hell ill show you right now i guess! smile.png just know we got more to fix

Massive Overblur:
gallery_1_371_54240.jpg

Normal Look:
gallery_1_371_15973.jpg

Slight Overblur:
gallery_1_371_12084.jpg
Dont want to bump but not sure if somebody saw my question, any clue as to what would create that? Would it be the bloom maybe? we placed a block that was very light purple and the block more or less lit itself up... was odd.
Hopefully I did not overread something...
Do you stll use the tonemapping function from xnainfo? If so: there is a small error in the shadercode Telanor posted.
Instead of
return fLumCompressed * vColor
it has to be
return fLumCompressed * vColor / fLumPixel
MJP posted it on his blog but it was never corrected on xnainfo.

Makes it look better but I also have a hard time getting it to work and I don't think it helps with your overblur sorry...

This topic is closed to new replies.

Advertisement