HDR trouble

Started by
21 comments, last by VISQI 12 years, 10 months ago

- In The implementation, why did he fetch it multiple times, shouldn't he calculate the luminance for EACH pixel one pixel at a time??


-The size of the luminance texture doesn't have to be the size of source texture. In my engine the luminance texture is 256x256, so I fetch the source texture multiple times to downscale it.
Advertisement
i got it now. You know after i really looked through the SDK sample, i got it easily. I guess it was easy all along. But i don't see any conversions to CIE Yxy in the SDK sample but it was in the article. Did i miss something or is it really not necessary??
Its not necessary if you just want simple HDR rendering
just one final thing, is there a fixed Tone-mapping function to use??
i once saw this one by [color=#1C2837][size=2][url="http://www.gamedev.net/topic/532960-hdr-lighting--bloom-effect/"]SimonJacoby method.[/url]

float3 Color = 1.0f - pow(2.71, -(Vignette * Original * Exposure);


where Original = the color of the original HDR + the blurred version.
Exposure = the avg luminance value

will this one suffice??
Here you go: http://filmicgames.com/archives/75


Which tonemap operator you use is totally up to you... the most used is Reinhard.

i got it now. You know after i really looked through the SDK sample, i got it easily. I guess it was easy all along. But i don't see any conversions to CIE Yxy in the SDK sample but it was in the article. Did i miss something or is it really not necessary??


You can convert to luminance with a simple dot product of your color with separate RGB weights, which is probably what the SDK sample does.
Ok. I just got it working but i have a couple of concerns:

- I calculate the luminance by converting to a 256x256 texture and taking the average log() of all the pixels from the HDR texture then to ->64x64 ->16x16->4x4->1x1.
Now the problem is that should i render the textures to a quad with the exact dimensions as the texture or can i just render them all to the same quad. I know that it doesn't matter but just reassure me.
also, the luminance calculation is not working, please have a look at it.

Techniques used:
- Init_Lum_Tech - used for downsampling to a 256x256 texture and applying the average log() for all the pixels.
- Iter_Lum_Tech - used three times to downsample to 64x64 -> 16x16 -> 4x4 textures
- Final_Lum_Tech - used to downsample from 4x4 -> 1x1 and finalizing the average luminance calculation.



//Average Luminance Calculation
//========================================================
static const float3 LUMINANCE_VECTOR = float3(0.2125f, 0.7154f, 0.0721f);
static const int MAX_SAMPLES = 16;
uniform extern float4 gLumOffset[MAX_SAMPLES];

//Initial Luminance Tech - used for downsampling to a 256x256 texture and applying the average log() for all
//the pixels
uniform extern texture HDRTexture;

sampler HDR_sTex = sampler_state
{
texture = <HDRTexture>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = POINT;
AddressU = CLAMP;
AddressV = CLAMP;
};

void Init_Lum_VShader(float3 PosL : POSITION0,
float2 TexC : TEXCOORD0,
out float4 oPosH : POSITION0,
out float2 oTexC : TEXCOORD0)
{
oPosH = mul(float4(PosL, 1.0f), gMatWVP);
oTexC = TexC;
}

float4 Init_Lum_PShader(float2 TexC : TEXCOORD0):COLOR
{
float Value = 0;
float3 Tex = 0;
for(int i = 0; i < 9; i++)
{
Tex = tex2D(HDR_sTex, TexC + gLumOffset.xy);
Value += log(dot(Tex, LUMINANCE_VECTOR) + 0.0001f );
}

Value /= 9.0f;
return float4(Value, Value, Value, 1.0f);
}

Technique Init_Lum_Tech
{
Pass p0
{
VertexShader = compile vs_2_0 Init_Lum_VShader();
PixelShader = compile ps_2_0 Init_Lum_PShader();
}
}

//Iterate Luminance Technique - used three times to downsample to 64x64 -> 16x16 -> 4x4 textures.
uniform extern texture ToBeDownSampledTexture;

sampler DownSample_sTex = sampler_state
{
texture = <ToBeDownSampledTexture>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = POINT;
AddressU = CLAMP;
AddressV = CLAMP;
};

void Iter_Lum_VShader(float3 PosL : POSITION0,
float2 TexC : TEXCOORD0,
out float4 oPosH : POSITION0,
out float2 oTexC : TEXCOORD0)
{
oPosH = mul(float4(PosL,1.0f),gMatWVP);
oTexC = TexC;
}

float4 Iter_Lum_PShader(float2 TexC : TEXCOORD0):COLOR
{
float Value = 0;

for(int i = 0; i < 16; i++)
{
Value += tex2D(DownSample_sTex, TexC + gLumOffset.xy).x + 0.0001f;
}

Value /= 16.0f;

return float4(Value, Value, Value, 1.0f);
}

Technique Iter_Lum_Tech
{
Pass p0
{
VertexShader = compile vs_2_0 Iter_Lum_VShader();
PixelShader = compile ps_2_0 Iter_Lum_PShader();
}
}

//Final Luminance Technique - used to downsample from 4x4 -> 1x1 and finalizing the average luminance calculation
void Final_Lum_VShader(float3 PosL : POSITION0,
float2 TexC : TEXCOORD0,
out float4 oPosH : POSITION0,
out float2 oTexC : TEXCOORD0)
{
oPosH = mul(float4(PosL,1.0f),gMatWVP);
oTexC = TexC;
}

float4 Final_Lum_PShader(float2 TexC : TEXCOORD0):COLOR0
{
float Value = 0;

for(int i = 0; i < 16; i++)
{
Value += tex2D(DownSample_sTex, TexC + gLumOffset.xy).x + 0.0001f;
}

Value /= 16.0f;

float AvgLum = exp(Value);

AvgLum = max(AvgLum, 0.0f);

return float4(AvgLum, AvgLum, AvgLum, 1.0f);
}

Technique Final_Lum_Tech
{
Pass p0
{
VertexShader = compile vs_2_0 Final_Lum_VShader();
PixelShader = compile ps_2_0 Final_Lum_PShader();
}
}


- The second problem is that in the SDK samples, they said in the documentation that they are rendering the original scene(ie: the room) in a regular LDR fashion and the Light spheres are the only ones that are getting in the HDR pipeline. How can they achieve rendering a post-processing effect and a regular LDR?? as i know that post-processing effects usually are rendered in a quad and then they are rendered to the back buffer, meaning that it takes all the backbuffer leaving no room for anything else.

Thanks

the luminance calculation is not working, please have a look at it.


Why do you say is not working? Looks correct to me..

EDIT: Why do you transform the quads by a WVP matrix? Since its a full screen quad the vertices should be like this:

//float3 pos, float2 texC
PosTexCVertex vertices[] =
{
PosTexCVertex(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f),
PosTexCVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
PosTexCVertex(1.0f, 1.0f, 0.0f, 1.0f, 0.0f),
PosTexCVertex(1.0f, -1.0f, 0.0f, 1.0f, 1.0f)
};


And this full screen quad works for all sizes of render target, you just have to create different viewports matching the sizes of the render targets...

[quote name='VISQI' timestamp='1306765773' post='4817514']
the luminance calculation is not working, please have a look at it.


Why do you say is not working? Looks correct to me..

EDIT: Why do you transform the quads by a WVP matrix? Since its a full screen quad the vertices should be like this:

//float3 pos, float2 texC
PosTexCVertex vertices[] =
{
PosTexCVertex(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f),
PosTexCVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f),
PosTexCVertex(1.0f, 1.0f, 0.0f, 1.0f, 0.0f),
PosTexCVertex(1.0f, -1.0f, 0.0f, 1.0f, 1.0f)
};


And this full screen quad works for all sizes of render target, you just have to create different viewports matching the sizes of the render targets...
[/quote]

It is slowing the demo like crazy(16 FPS) when it was 150 FPS. I checked the textures from PIX and the luminance textures(yes, all of them) are not getting anything(just an empty texture).

So i just forget about WVP matrix??
And should i do a viewport with the dimensions of EVERY texture i render?? (ie: a 4x4 texture with a 4x4 viewport??)

It is slowing the demo like crazy(16 FPS) when it was 150 FPS. I checked the textures from PIX and the luminance textures(yes, all of them) are not getting anything(just an empty texture).

What formats are you using to create the luminance textures? Have you used PIX to debug some pixels of the luminance textures what see whats happening?
Also, if you are using FP16 formats PIX might not be able to show correctly the textures...


So i just forget about WVP matrix??
And should i do a viewport with the dimensions of EVERY texture i render?? (ie: a 4x4 texture with a 4x4 viewport??)

Why the position I gave you are in screen-space so no need for WVP matrix.

My vertex shader looks like this:

VS_OUT QuadVS(VS_IN vIn)
{
VS_OUT vOut;

vOut.posH = float4(vIn.posL, 1.0f);
vOut.texC = vIn.texC;

return vOut;
}


About the viewports:

mViewports[0].Width = luminanceSizes[0];
mViewports[0].Height = luminanceSizes[0];
mViewports[0].MinDepth = 0.0f;
mViewports[0].MaxDepth = 1.0f;
mViewports[0].TopLeftX = 0;
mViewports[0].TopLeftY = 0;
[...]


and then use RSSetViewport to use the viewport you want...

This topic is closed to new replies.

Advertisement