   HDR Questions
  Hi,With my new card, I could finally play around with HDR. It seems to work but I have a couple of questions so I can understand the technique better. Not all the code I've written is clear to myself and the framerate... sucks.First of all, all the HDR demo's I've seen require FBO and use floating point textures. My code as well, but I don't know exactly why. The way I see it, HDR basically performs the following steps while rendering: 1- Render a LDR and HDR portion to 2 floating point textures directly.    In my case the HDR texture is a smaller one because it needs to be blurred. 2- Blur the HDR portion (if you like). I use a horizontal and vertical gaussian blur. 3- Combine the LDR and HDR texture, simply by adding them. Render the result on a screen-filling HUD sprite for example.That's cute but couldn't it be done much simpler (suitable for older hardware) by: 1- Render the scene in smaller viewport. 2- Make a snapshot of that small scene 3- Render the normal scene and take another snapshot of it 4- Render a screen-filling HUD sprite. You could enlarge the contrast of the small snapshot and take multiple samples for a blur. Finally add the normal snapshot to the blurred one.It takes a few snapshots and the contrast stuff might be a little bit tricky for nice results. But you could also enable special shaders in the blur render pass for that. Anyway, this would be how the goold-old glow works right? What's so much better about HDR comparing it to 'usual' glow? Why does it need FBO and floating point textures?The Halflife2 Lost Coast demo told about a trick so that the HDR overbrighting affects the screen center most, the borders didn't take much of the HDR extra. I think they used this for the 'eye-lens-adjustment' effect, is that right? How to implement it? Now I have a alpha texture where each pixel tells how much HDR to take on that position. So the borders of that texture are dark while the center is pretty bright? Is this the right way to do it?Last question. My framerate is seriously low. The scene itself uses complex shaders (bumpmaps, cubemap reflections, caustics etcetera), but without HDR, it still reaches 150 frames per second. With HDR, only ~17 frames. I reduced the gaussian blur effect by taking only 6 samples in total, instead of 18. Also the HDR blurred screen is smaller, but both tricks didn't help much. The first time I tried the same code on a very simple scene(a cube without textures), full-screen, and then it reached above the 100. So, I applied a very simple material to the complete scene but that didn't work either... Weird, the resolution is lower and the polygon count is <1000. What could be a real bottleneck?Maybe some buffer was initialized wrong?Thanks for taking the time!!Rick   
  I think that you (and many others) are confusing HDR with a bloom effect, these are two very different things imo.HDR simply means that you have more then 8 bits per component (RGB) and preferable an "unbounded" range of values.When you have your HDR surface rendered, you need a way to present it to the display which is LDR (even though some LCD tv's etc have 10 or 12 bits per component the interface is still only 8 bits).The easiest way is to clip the HDR components to LDR with some scaling/offset.This process is called tone mapping and Reinhart (spelling?) have come up with some nice fast ways to do this (I had no trouble implementing it on the GPU).Until now I've only talked about a fixed mapping from HDR to LDR, the interesting part is to "simulate" how the eye reacts to light, thus adjusting the scaling according to the current brightness of the HDR surface.That's HDR, and that alone looks alot better than LDR imo.Blooming is an effect that actually happens in your eye as well, when a tap in your eye gets "saturated" with energy (looking at a bright spot for instance), some of it's energy is "spilled" over to neighbour taps, i.e they are "seeing" light as well.This could easily be simulated by blurring bright spots on screen to bleed "energy" to neighbour pixels.It's fully possible and quite frequently used, to use blooming on LDR targets, normally you store an extra brightness factor in the destination alpha during the normal rendering pass or having a fixed cut off.To make things even worse people tend to mix in gamma corrected lighting when talking about HDR, this is also an "effect" that can be used together with the other two or in it's own.Using gamma corrected lighting requires more than 8 bits to avoid banding, but using pixel shaders 2.0 it's fully possible to have source textures and destination targets in 8 bits and still perform gamma corrected lighting.What you described is the combined effect of using HDR + Blooming.In my engine this is done like this:1. Render scene to a HDR render target (atleast 16 bits per channel), this is stored in linear gammma.2. Determine scene luminosity (scaling down to 1x1 pixels by averaging).3. Use scene luminosity to tone map the HDR target (to another HDR target), this typically get's all values into the range zero to one.4. Create a scaled copy of the tone-mapped surface, cutting away any thing that isn't bright enought to produce a glow (I scale it by a fourth in both width and height).5. Blur the scaled down version.6. Merge the tone mapped HDR buffer and the blurred version onto the LDR backbuffer (with gamma correction, from linear to the display device gamma, 2.2 for instance).;  Thanks for the detailed info!Ok, lets forget about blooming because the blurring stuff is pretty obvious how it works for me now. But HDR itself... Lets see what I understand and what not. If I understand it right, normal textures/buffers can only hold a very limited amount of data per color channel(255). So if I create a shader that gives '2' as a color result, it will be capped off to 1 (and the same for <0), right? When putting stuff in a buffer with a bigger storage resolution, I can put higher (or lower) values in it ('2' will stay 2).In the end however, it needs to be converted back to LDR because pixels outside the range can't be displayed on a casual monitor anyway. Now here's my question, what happens if you convert it back with a technique like tone-mapping like you mentioned? For example, I have a white wall (value is 1) and another overbrightened wall with value 2. What happens now? Or maybe that's a bad example?And why does it need FBO? Maybe I'm wrong, but floating point textures already existed for older cards as well. Normally you use a snapshot to capture a screen (glTexImage2D or something). But that doesn't work because the rendered data is already capped of to LDR? In that case, I understand the FBO usage.Thanks for helping!Rick   ;  About the performance I asked, I think I've found the bad guy. While rendering on the LDR and HDR buffers, it also tooks snapshots for effects like water. Snapshots are taken with OpenGL 'glCopyTexSubImage2D' command. Normally, it goes fast but when those FBO buffers (or maybe some other settings for HDR...) are active, the framerate drops down like a fat grandma.Everything is rendered in the 2 HDR passes, and it seems that taking snapshots is not a good idea. Or maybe not the way like I do, using NPOT textures with GL_TEXTURE_RECTANGLE for some of the screen captures. Is there any way to improve this? Or maybe those textures need another format since were working in 'another range'? Normally those textures have the 'GL_RGB' format.Greetings,Rick   ;This is the paper that made me grasp the concept and the math behind tone mapping.Here's some more images and reading.I can't comment on the OpenGl specifics, since I'm using DirectX.   