Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


D3D9 High Dynamic Range Rendering Example


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
20 replies to this topic

#1 jollyjeffers   Crossbones+   -  Reputation: 1542

Like
0Likes
Like

Posted 15 September 2005 - 03:44 AM

For reference purposes, a more up-to-date version is now available as part of the DirectX 9 SDK: HDRPipeline [caution] Warning: This is a fairly long announcement/article type thread, I hope you like it and remember - I really appreciate any comments/feedback!
Introduction
This thread is about a piece of research that was originally for my own personal amusement, but part way through I decided that it might well be of interest/use to you guys. So, here it is.. [smile] Whilst HDR rendering is not the most complicated process to work with, it can be quite confusing. As shown by this sample there are a large number of connected steps that go into the final image - each of these steps is straight-forward, but it is the system as a whole that can be confusing. What I planned to do with this sample that I hadn't seen in any of the other samples I've looked at was show all of these individual steps as part of the GUI. All of the elements are updated each frame, so it should make it easier to understand the system as a whole if you can see what is actually stored/computed in each step. There are four main sections:
  1. Rendering the original HDR image. This is the "traditional" part of the pipeline, with the difference that we can use images outside the 0.0 to 1.0 range (or 0..255 range).
  2. Computing the average luminance for the scene. The result of this is a value indicating how bright (or how dark) the scene is.
  3. Performing any post-processing on the image. The lens on a camera (as well as the human eye) can "scatter" some of the incoming light and lead to various blurring effects around particularly bright objects.
  4. Compositing these steps together to create the final result. Taking the results from the previous 3 sections we can create a final image, mapped back down to a regular 32bit (or even 16bit) XRGB texture that is suitable for being displayed to the end user.
Overview
To interpret the GUI correctly, following the arrows in the red circles. Starting from the HDR image in the middle-left, through to the large image (bottom-right).
(Click To Enlarge)
In the above screenshot the application is displaying a regular image that is contained entirely within the 0.0 to 1.0 range (note that there the 4 cells at the top are all black).
(Click To Enlarge)
This image shows the view having been rotated around (Drag with RMB). The three faces of the cube are being rendered with colours above 1.0 - that is, they are particularly bright. Because the average luminance (Explained further down..) is much brighter the final image is adjusted such that it is much darker. This is best observed by looking at the background around the cube - the surrounding geometry and the blue background are darker than in other images. The bright pass at the top is now "active", and is simulating the way that the bright (over exposed) parts of the image are being blurred by the lens.
(Click To Enlarge)
The above screenshot shows a more typical scene - where you'd have a combination of "over bright" and "normal" colours. Due to the luminance calculations, the bright areas of the scene lead to a darkening of the image, but not as much as in the previous image. Because there is still a substantial part of the scene that isn't bright it draws the luminance average down, leading to the bright areas being over-exposed (and appearing nearly white).
Luminance Path
The luminance calculations are shown in the bottom-left part of the GUI:
Luminance is computed in a GPU-friendly manner - by using multiple (down sampled) render targets and pixel shaders the work can be offloaded to the GPU rather than use the CPU. If we were to measure luminance using the CPU it would require a lot of data to be transferred back across the AGP/PCI-E bus, which is A Bad Thing™.
Post-Processing Path
The post processing is displayed via the four cells along the top of the GUI:
As previously mentioned, the lens used to capture an image often has particular optical properties - one of which is that it can, even very slightly, scatter/reflect/refract the incoming light. The brighter this light is, the more pronounced the effect will be. Depending on the lens you can get different types of effects - a regular "bloom" (as in this sample) or a variety of star/cross filters. The first part of post-processing is picking the pixels that should contribute. To be physically accurate, all should be processed, but for a bit of "artistic licence" most implementations only consider pixels above a certain threshold. There is a slider in the main GUI that allows you to change this to see what effect it has - around 0.5-0.6 works well. The actual post-processing can be quite a performance-heavy piece of code (lots of texture reading), so the original image is subjected to two down-sampling steps. This reduces the number of pixels that are processed by 64x. To achieve a 2D blur effect, it can be quite efficiently approximated using two passes - one for a horizontal blur and one for a vertical blur. The combination gives the desired 2D effect. These two passes are seen as the final two steps in the above image.
Final Image Composition
The final result can be seen as the largest image in the GUI:
In a real/production HDR pipeline, the above image is all that you would show to the end-user. All of the other intermediary steps shown in this sample would be kept "behind the scenes". The pixel shader that outputs this particular image, takes (as shown by the arrows in the GUI) the original HDR image, the final post-processing result and the luminance calculation as inputs. The key part is the luminance input - the value read from this texture is used to "luminance map" the original HDR image and the post-processing results. The net result is that if the scene is deemed to be fairly bright, all the colours are scaled down; if the scene is fairly dark, the colours are scaled up.
Using The Sample
You can download the source code and required files here (505kb). Unzip the archive to a folder on your machine and refer to the 'readme.txt' included - it has all of the important details. An obvious requirement is to have hardware that supports 'Shader Model 2.0' and floating-point textures (either 64bit or 128bit). Also, I developed the code using the August 2005 DirectX SDK - so some people may well require the d3dx9_27.dll to run the sample. In this case I suggest you have a look here or here [smile]
References
What I've presented in this sample/thread is far from ground-breakingly original work. In truth, it is just my adaptation and interpretation of a lot of other peoples work. Hopefully it'll be useful to people though I can't find links to every single source, but the following list is my recommended further reading: Articles Real-Time Glow High Dynamic Range Rendering High Dynamic Range Environment Mapping On Mainstream Graphics Hardware Samples/Demos HDRLighting HDRFormats RTHDRIBL (Real-Time High Dynamic Range Image-Based Lighting) [Edited by - jollyjeffers on March 2, 2006 6:56:55 AM]
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Sponsor:

#2 Nik02   Crossbones+   -  Reputation: 3077

Like
0Likes
Like

Posted 15 September 2005 - 05:45 AM

I like it, another practical demo from Jolly [smile]

Good work!

Niko Suni


#3 SirKnight   Members   -  Reputation: 316

Like
0Likes
Like

Posted 15 September 2005 - 06:15 AM

Cool demo. I like how it shows all the steps. But the weird thing is it only works for me in debug mode. I have a 6800GT (drivers 77.77) w/ the august runtimes installed. In release mode the app crashes instantly.



-SirKnight

#4 vidalsasoon   Members   -  Reputation: 100

Like
0Likes
Like

Posted 15 September 2005 - 08:16 AM

awesome.

i've been SOL trying to implement something similar and it was getting me depressed to try and fix it. now I can take another happy stab at it :P

#5 circlesoft   Members   -  Reputation: 1178

Like
0Likes
Like

Posted 15 September 2005 - 12:07 PM

Freakin sweet man, nice job [grin]

#6 noaktree   Members   -  Reputation: 734

Like
0Likes
Like

Posted 15 September 2005 - 07:57 PM

Looks beautiful!

#7 jollyjeffers   Crossbones+   -  Reputation: 1542

Like
0Likes
Like

Posted 16 September 2005 - 02:32 AM

Thanks for the positive feedback everyone - greatly appreciated [grin]

Quote:
In release mode the app crashes instantly.

I don't suppose you're running an AMD processor are you? Simon O'Connor (S1CA) ran an earlier version that was built using SSE2 -that tripped up on his AMD... I was pretty sure I turned off those optimizations though [oh]

Cheers,
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

#8 Nik02   Crossbones+   -  Reputation: 3077

Like
0Likes
Like

Posted 16 September 2005 - 04:24 AM

My AMD runs the program just fine :)

I have Athlon 2800+ @home.

Niko Suni


#9 jollyjeffers   Crossbones+   -  Reputation: 1542

Like
0Likes
Like

Posted 17 September 2005 - 02:11 AM

Quote:
Original post by Nik02
My AMD runs the program just fine :)

I have Athlon 2800+ @home.

Interesting - so I guess I did turn off the SSE stuff like I thought I did..

Seems that Evil Steve's crashed as well, so maybe there's something else going wrong [sad]

Anyone got any further details as to what/why it's going tits up?

Cheers,
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

#10 Evil Steve   Members   -  Reputation: 1986

Like
0Likes
Like

Posted 17 September 2005 - 02:38 AM

It only seems to work in Debug mode (And you get a warning that the device has a non-zero reference count [wink]). I get that illegal instruction exception in release mode. I'm running an AMD 2600XP, GeForce 4 Ti 4400.

I'll see if I can find out what's going wrong...

Edit: The illegal instruction is:
0040BDEB movsd mmword ptr [eax+8],xmm0
Looks fine to me :/


#11 vidalsasoon   Members   -  Reputation: 100

Like
0Likes
Like

Posted 17 September 2005 - 02:42 AM

I crashed also in Release mode.

AMD 2500+ Geforce 6600

#12 Evil Steve   Members   -  Reputation: 1986

Like
0Likes
Like

Posted 17 September 2005 - 02:45 AM

Ah ha: "Project Options -> C/C++ -> Code Generation -> Enable Enhanced Instruction Set" is set to SSE2. Changing it to SSE works fine.

Edit: Looks really nice, but I had to change the code slightly to get it to use the reference rasterizer. To quote your code:
Quote:
//we don't support 128bit render targets :-(
//we don't support 128 or 64 bit render targets. This demo
//will not work with this device.


#13 SirKnight   Members   -  Reputation: 316

Like
0Likes
Like

Posted 17 September 2005 - 12:50 PM

Oh SSE2, that's why. Yeah I'm running an AMD XP 2600+. :)


-SirKnight

#14 jollyjeffers   Crossbones+   -  Reputation: 1542

Like
0Likes
Like

Posted 18 September 2005 - 09:21 AM

Quote:
Original post by Evil Steve
Ah ha: "Project Options -> C/C++ -> Code Generation -> Enable Enhanced Instruction Set" is set to SSE2. Changing it to SSE works fine.

Aaah, thanks for solving that one [grin]

I was aware of the SSE/SSE2 thing before hand - and I was sure that I went into the project settings to change it to "blended" (works across all CPU's). Maybe I included the wrong file in the archive [oh]

I'll see about changing the file in the archive later [smile]

Cheers,
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

#15 sirob   Members   -  Reputation: 1181

Like
0Likes
Like

Posted 18 September 2005 - 09:26 AM

Downloaded it, and I think it's great. I like the way it shows off the proccess.

I have one question though: I got 12fps. Is this the kind of performance to be expected on my card (FX5200), or is this simply because it's wasting time showing us the whole proccess?
I was thinking about attempting to implement HDR, but if all I'll get is 12fps I won't even be able to test it out right.

Again, looks amazing, really.

#16 Muhammad Haggag   Moderators   -  Reputation: 1358

Like
0Likes
Like

Posted 18 September 2005 - 09:41 AM

Quote:
Original post by sirob
I have one question though: I got 12fps. Is this the kind of performance to be expected on my card (FX5200), or is this simply because it's wasting time showing us the whole proccess?
I was thinking about attempting to implement HDR, but if all I'll get is 12fps I won't even be able to test it out right.

It's expected - the 5200 was never good at ps2.


#17 sirob   Members   -  Reputation: 1181

Like
0Likes
Like

Posted 18 September 2005 - 09:44 AM

Yeah, my environmental water never passes the 40fps mark, and it is only doing half of the screen :).

Thanks!

#18 jollyjeffers   Crossbones+   -  Reputation: 1542

Like
0Likes
Like

Posted 18 September 2005 - 10:59 AM

Quote:
Original post by sirob
is this simply because it's wasting time showing us the whole proccess?

It does spend a lot of time doing the presentation/GUI side of things, and in general I went for clear/concise code over high-performance and efficiency.

If you have a look in my journal... it was the HDRI demo that I got my data from, and it seemed to be indicating (I haven't investigated fully) that the GUI/presentation was taking up around 45-50% of the frame time [oh]

Quote:
Original post by sirob
I was thinking about attempting to implement HDR, but if all I'll get is 12fps I won't even be able to test it out right.

Try running the "HDRFormats" and "HDRLighting" samples in the SDK - they'll probably give you a better idea of the raw performance to expect from HDR+FX5200. But, as Coder said, your hardware is probably at the very minimum of what can actually handle HDR [smile]

Thanks for the feedback!
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

#19 DrGUI   Members   -  Reputation: 402

Like
0Likes
Like

Posted 18 September 2005 - 09:08 PM

A jolly excellent article there old chap!

I have a GeForce FX 5200 and if I put the number of bloom passes on my game up beyond 2 or 3, the fps goes to about 12, so I guess it is to be expected. Especially as Jack's demo actually finds the luminance and performs tone mapping as well!
(Mine's a sort of faked HDR pipeline as you have a glow shader as well as the normal one. It works well and that's all that matters, muwhahaha)

#20 jasonsa   Members   -  Reputation: 384

Like
0Likes
Like

Posted 19 September 2005 - 12:51 PM

Very cool stuff. I really like the graphical flow of what's happening. Our HDRLighting sample isn't nearly as slick :)

Jason,
DXSDK dev lead




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS