• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Vexal

Question about tone mapping / HDR

9 posts in this topic

I've been trying to implement HDR but have been having some trouble figuring out the correct approach.  I have bloom working, but not tone mapping.  I am using DirectX 11.

 

I have read several sources but they each say different things.  I currently have a shader that takes the texture from the first pass and renders to the luminance texture, then finds the average luminance by generating all of the mip maps.  The final pass applies the luminance scaling (along with the bloom).

 

I am confused why other articles and samples compute the average luminance by downsampling the texture multiple times.  Why is it not enough to just call deviceContext::GenerateMips()?  I saw another article suggesting using the compute shader to do this.

 

I am also confused what I should be storing as the luminance.  This article talks about finding the average log of the pixel color and some color weights http://msdn.microsoft.com/en-us/library/windows/desktop/bb173486(v=vs.85).aspx, but this post says nothing of logarithmic operations when finding the average scene luminance http://www.gamedev.net/topic/532960-hdr-lighting--bloom-effect/, but does use the exponential operator when computing the final color.

 

This paper linked to by the microsoft article goes into more detail on the equations, but doesn't talk about how the relate to the shaders at all http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf

 

I tried looking at the samples in the deprecated directx SDK (the compute shader HDR sample), and that version just averages the color of the pixels directly and weights them by (.299, .587, .114, 0) to get the average luminance, then scales the color of the final pixel linearly.  Running the sample looks decent, but when I run it in my program, because blue is weighted so low, looking at the sky makes everything else extremely bright.  Weighting each RGB value equally just makes the final image darker in most cases and doesn't produce any interesting effect.

 

Which formula should I be using to get the average luminance, and which formula should I be using to convert the unmapped pixel color to the mapped pixel color given the average luminance?

0

Share this post


Link to post
Share on other sites

"I am confused why other articles and samples compute the average luminance by downsampling the texture multiple times.  Why is it not enough to just call deviceContext::GenerateMips()?  I saw another article suggesting using the compute shader to do this." - I suspect this amounts to the same thing, but you don't know for sure how GenerateMips is implemented, it's probably going to use the GPU and downsample the texture multiple times in exactly the same way, but if it happens to do the work on the CPU then that could be a massive performance cost. I suspect you're fine to use GenerateMips if you find it's working for you (although perhaps you should google to check that it behaves how you expect on most devices), but I think it makes sense that articles and papers are more explicit about the required process.

 

"I am also confused what I should be storing as the luminance.  This article talks about finding the average log of the pixel color and some color weights http://msdn.microsoft.com/en-us/library/windows/desktop/bb173486(v=vs.85).aspx, but this post says nothing of logarithmic operations when finding the average scene luminance http://www.gamedev.net/topic/532960-hdr-lighting--bloom-effect/, but does use the exponential operator when computing the final color." - I'm not sure, but I think this probably depends on how you're encoding the HDR. Older implementations would probably do clever things to do HDR with 8888 render targets by encoding some logarithmic scaling factor in the alpha channel. More modern implementations probably just use float or half-float render targets instead. What you need to do depends on your implementation. Most likely you're using half-float render targets and you just need a simple average.

 

"I tried looking at the samples in the deprecated directx SDK (the compute shader HDR sample), and that version just averages the color of the pixels directly and weights them by (.299, .587, .114, 0) to get the average luminance, then scales the color of the final pixel linearly.  Running the sample looks decent, but when I run it in my program, because blue is weighted so low, looking at the sky makes everything else extremely bright.  Weighting each RGB value equally just makes the final image darker in most cases and doesn't produce any interesting effect." - I think it's correct that blue should have a lower weight when converting RGB to luminance. Perhaps your sky just isn't correctly calibrated against the rest of your scene. Probably most of your scene is dynamically lit with your HDR system and your sky is just a pre-baked 8888 skybox texture, I think that you'd need to modify your sky so that it's a lot brighter. You could do that by modifying the shader you use when rendering to force up the values, or by using a sky texture that can contain HDR values (half-float or something) and get your artist to tweak it.

0

Share this post


Link to post
Share on other sites

My sky is just a gradient with pure white (1, 1, 1) at the horizon, and pure blue (0, 0, 1) at the top.  When a large portion of the blue part is in view, the rest of the scene becomes too bright.  Should I be making the sky brighter than one?

 

Also, I still don't understand where the formula for exposure from the other post comes into play in relation to all of the other descriptions of HDR.  

This one: float4 exposed = 1.0 - pow( 2.71, -( vignette * unexposed * exposure ) );

0

Share this post


Link to post
Share on other sites

Hiya,

  You should be using HDR values for your scene, if your colours are in the range [0...1] then you don't need HDR tonemapping.

 

So, as an example, if your brightest pixel is 10,10,10 (instead of 1,1,1) then your blue would be (0,0,10) or higher.

 

n!

0

Share this post


Link to post
Share on other sites

Thanks for the response.  Your clarification on the formulas help.

 

In addition to that, I think I'm actually having an issue generating (or sampling) the mip maps correctly.  

 

Originally I was doing this in the final shader:

 

float4 luminance = luminanceTexture.SampleLevel(g_samPoint, float2(.5f, .5f), 10); //luminanceTexture should have the average luminance at the lowest mip level

 

But sampling at the 10th level is zero for most cases -- it only seems to average the luminance values near the center of the texture.  I tried sampling at other levels in between and it seems to be interpolating or something.  Rendering the luminance texture to the screen with the texture coordinates of the pixel looks like this for different mip levels.

 

The brightness of the texture changes based on the position of the sphere on screen.  When I sample at the lowest level, the screen is correctly all one color, but it changes when I move the circle around.

 

L0vR31k.jpg

 

 

peErGO7.jpg1o91W6P.jpgDiLsNok.jpg

Edited by Vexal
0

Share this post


Link to post
Share on other sites

I figured out that the mip mapping is not correctly averaging the pixels.  Looking at the mip levels in visual studio, it shows this.

 

The color of the final pixel changes based on the position of the objects in the screen.  The closer the objects are to the center, the brighter the final pixel.  In this example, the final pixel ends up being zero and I cannot figure out why.

 

Level 0:

uXZX6v3.png

 

Level 3

 

j9aSeHQ.png

 

Level 5:

 

tyxwdEz.png

 

 

Level 9:

 

KWrQ6AY.png

 

And finally, level 10 is just a single black pixel.  I checked it with the color tool and it's 0,0,0

 

ef9tGZ4.png

0

Share this post


Link to post
Share on other sites

The brightness of the texture changes based on the position of the sphere on screen.  When I sample at the lowest level, the screen is correctly all one color, but it changes when I move the circle around.

This shouldn't happen if the mip-maps are being generated correctly...
Another issue could be the texture format used -- are you using an FP16, or other "higher than 8-bit channels" format?

 

[edit]

Level 9:
And finally, level 10 is just a single black pixel.  I checked it with the color tool and it's 0,0,0

Ok, that shows it jumping from a 3px wide texture to a 1px wide texture. Depending on how they're generating the mip-maps, they might be failing to take the right-most pixel into account (just averaging the two left-most pixels). That's very bad :/

You can work around this by calculating the mip-levels yourself instead of using the automatic method. The performance cost will be the same (assuming you do it the same way as the automatic method does it), but your code will obviously be more complex, and you'll have full control over the calculations.

Edited by Hodgman
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0