Reinhard operator and HDR

Started by
12 comments, last by Bacterius 11 years, 7 months ago
Ok, let's call it the Serr Tone Mapping operator than biggrin.png

I've just tweaked some settings so that it matches the Uncharted 2 Tone Mapping operator exactly. With [eqn]a=5.6[/eqn] and [eqn]b=1[/eqn] you get the exact same tone mapping operator. Here's a plot:

serr_tonemapping_operator_comparison.gif

The thing is that it's way lighter on the GPU than the one from Uncharted 2 smile.png
With these settings it's basically just [eqn]\frac {4.6x}{3.6x+5.6}[/eqn]
Advertisement
That is pretty simple once you collapse the non-per-pixel math!
N.B. I compared it against Hable's and your instruction count actually comes out higher in SM3.0, because it assumes that most operations can be done in 4-wide SIMD, but that pow must be scalar. SM5 asm has a SIMD version of exp/log so the instruction count beats Hable there.
However, this is pretty meaningless, as HLSL asm isn't at all representative of the GPU, and different instructions have different latencies...

Anyway, the code does look good ;)
//optimized hable
float3 f = (BC*x-B*x+DEsubDF)/(A*x*x+B*x+DF)-EsubFdivF;

ps_3_0
def c2, 1, 0, 0, 0
dcl_texcoord v0.xyz
mul r0.xyz, c0.z, v0
mad r1.xyz, c1.x, v0, -r0
add r1.xyz, r1, c1.z
mul r2.xyz, v0, v0
mad r0.xyz, r2, c0.y, r0
add r0.xyz, r0, c1.y
rcp r2.x, r0.x
rcp r2.y, r0.y
rcp r2.z, r0.z
mad oC0.xyz, r1, r2, -c1.w
mov oC0.w, c2.x

ps_5_0
dcl_globalFlags refactoringAllowed
dcl_constantbuffer cb0[2], immediateIndexed
dcl_input_ps linear v0.xyz
dcl_output o0.xyzw
dcl_temps 2
mul r0.xyz, v0.xyzx, v0.xyzx
mul r1.xyz, v0.xyzx, cb0[0].zzzz
mad r0.xyz, r0.xyzx, cb0[0].yyyy, r1.xyzx
mad r1.xyz, cb0[1].xxxx, v0.xyzx, -r1.xyzx
add r1.xyz, r1.xyzx, cb0[1].zzzz
add r0.xyz, r0.xyzx, cb0[1].yyyy
div r0.xyz, r1.xyzx, r0.xyzx
add o0.xyz, r0.xyzx, -cb0[1].wwww
mov o0.w, l(1.000000)
ret
//optimized Serr
float3 XpowB = pow(x,B);
float3 f = (ApowBsub1*XpowB)/(ApowBsub2*XpowB+ApowB);

ps_3_0
def c1, 1, 0, 0, 0
dcl_texcoord v0.xyz
log r0.x, v0.x
log r0.y, v0.y
log r0.z, v0.z
mul r0.xyz, r0, c0.w
exp r1.x, r0.x
exp r1.y, r0.y
exp r1.z, r0.z
mul r0.xyz, r1, c0.x
mad r1.xyz, c0.y, r1, c0.z
rcp r2.x, r1.x
rcp r2.y, r1.y
rcp r2.z, r1.z
mul oC0.xyz, r0, r2
mov oC0.w, c1.x


ps_5_0
dcl_globalFlags refactoringAllowed
dcl_constantbuffer cb0[1], immediateIndexed
dcl_input_ps linear v0.xyz
dcl_output o0.xyzw
dcl_temps 2
log r0.xyz, v0.xyzx
mul r0.xyz, r0.xyzx, cb0[0].wwww
exp r0.xyz, r0.xyzx
mul r1.xyz, r0.xyzx, cb0[0].xxxx
mad r0.xyz, cb0[0].yyyy, r0.xyzx, cb0[0].zzzz
div o0.xyz, r1.xyzx, r0.xyzx
mov o0.w, l(1.000000)
ret
Ok, thanks everyone for your help smile.png
I have a couple final questions. I've done good progress on the path tracer and I'm now at the stage where each of my pixels in my final image have a spectral power distribution, which is basically a list of sampled wavelengths along with their respective radiance. I can convert this distribution to a color (but not a shade) easily, however I am a little confused on how to calculate the shade. Can I use the raw per-pixel radiance as luminance in my tone-mapper and scale the final RGB values by the radiance scaling factor, or should I first convert all my CIE colors to RGB, multiply them by their radiance, and tonemap that?

Basically I feel I should be able to do better than the CIE luminance approximation given that I already have the true radiance value for each per-pixel, but I am unsure if they are the same thing.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

Update: scaling the RGB values with the total measured radiance and tonemapping that seems to be the right thing to do, anything else produces garbage. For future reference, since I had a hard time "getting it": the absolute per-wavelength radiance in your spectral power distribution is irrelevant in determining the resulting perceived color - all that matters is the relative radiance between wavelengths (the "shape" of the distribution). However, this will only give you the color, which is fundamentally different from what you would think a "color" is because it does not encode luminance information at all - the luminance (shade) is the area under the spectral power curve (e.g. the total radiance over the visible spectrum) and this is where the absolute measurements are used. This will give you a wide luminance range to work with, which you can then tone map at your leisure.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

This topic is closed to new replies.

Advertisement