Sign in to follow this  

HDR trouble

This topic is 2392 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys,
So, i read along many articles about HDR rendering and i just want to summarize what i understood about the pipeline:
- Render the scene to a texture
- apply a bright-pass filter and downsample the texture to half its size
- apply a Gaussian blur in two passes(through x-Axis and Y-Axis)
- additively blend the scene texture with the gaussian blur

I tried to do those steps but apparently i went wrong somewhere.
I did check out the DX SDK sample about HDRLighting but i really didn't understand much of it.

So, did i miss anything??

also, here is the fx file for the demo

[code]

//HDR rendering with bloom effect

struct Mtrl
{
float4 Diff;
float4 Amb;
float4 Spec;

float SpecPower;
};

struct DirLight
{
float4 Diff;
float4 Amb;
float4 Spec;

float3 DirW;
};

uniform extern float4x4 gMatWVP;
uniform extern float4x4 gMatITW;
uniform extern float4x4 gMatW;

uniform extern float3 gEyePosW;

uniform extern Mtrl gMtrl;
uniform extern DirLight gLight;

//Full Texture Technique
//======================================
struct vOut{
float4 PosH : POSITION0;
float2 TexC : TEXCOORD0;
float3 EyeVecW : TEXCOORD1;
float4 NormW: TEXCOORD2;
};

vOut FullVShader(float3 PosL : POSITION0,
float3 NormL : NORMAL0,
float2 TexC : TEXCOORD0)
{
vOut V = (vOut)0;

V.PosH = mul(float4(PosL, 1.0f), gMatWVP);
V.NormW = mul(float4(NormL, 0.0f), gMatITW);

V.TexC = TexC;

float3 PosW = mul(float4(PosL, 1.0f), gMatW);

V.EyeVecW = PosW - gEyePosW;

return V;

};

float4 FullPShader(float3 EyeVecW : TEXCOORD1,
float4 NormW: TEXCOORD2):COLOR
{
EyeVecW = normalize(EyeVecW);

float3 LightVecW = -gLight.DirW;
float3 RefLightVecW = reflect(-LightVecW, NormW);

float d = max(dot(LightVecW, NormW), 0.0f);
float s = pow(max(dot(RefLightVecW, EyeVecW), 0.0f), gMtrl.SpecPower);

float3 Diff = d * (gMtrl.Diff.rgb * gLight.Diff.rgb);
float3 Amb = (gMtrl.Amb * gLight.Amb);
float3 Spec = s * (gMtrl.Spec * gLight.Spec).rgb;

float3 FinalColor = Diff + Amb + Spec;

return float4(FinalColor, gMtrl.Diff.a);
}

Technique FullTech
{
Pass p0
{
VertexShader = compile vs_2_0 FullVShader();
PixelShader = compile ps_2_0 FullPShader();
}
}

//Bright-Pass Filter Tech
uniform extern texture FullTexture;

sampler Full_sTex = sampler_state
{
texture = <FullTexture>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = POINT;
AddressU = WRAP;
AddressV = WRAP;
};

void BP_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 BP_PShader(float2 TexC : TEXCOORD0):COLOR
{
float3 Color = tex2D(Full_sTex, TexC);

Color = Color - float4(0.3f,0.3f,0.3f, 0.0f);

return float4(Color,1.0f);
}

Technique BP_Tech
{
Pass p0
{
VertexShader = compile vs_2_0 BP_VShader();
PixelShader = compile ps_2_0 BP_PShader();
}
}

//Gaussian Blur Tech With 2 Passes. One for the X-Axis and the other for the Y-Axis

uniform extern texture BP_Texture;

sampler BP_sTex = sampler_state
{
texture = <BP_Texture>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = POINT;
AddressU = WRAP;
AddressV = WRAP;
};

static const float2 gBlurXOffset = float2(0.0025f, 0.0f);
static const int gBlurXKernalSize = 10;

static const float2 gBlurYOffset = float2(0.0f, 0.0033333f);
static const int gBlurYKernalSize = 10;

//Blur on The X-Axis
//========================================
void BlurX_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 BlurX_PShader(float2 TexC : TEXCOORD0):COLOR
{
float4 TexColor = tex2D(BP_sTex, TexC);

for(int i = 1; i < gBlurXKernalSize; i++)
{
TexColor += tex2D(BP_sTex, TexC + (i * gBlurXOffset));
TexColor += tex2D(BP_sTex, TexC - (i * gBlurXOffset));
}

return TexColor;
}

//Blur on The Y-Axis
//========================================
void BlurY_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 BlurY_PShader(float2 TexC : TEXCOORD0):COLOR
{
float4 TexColor = tex2D(BP_sTex, TexC);

for(int i = 1; i < gBlurYKernalSize; i++)
{
TexColor += tex2D(BP_sTex, TexC + (i * gBlurYOffset));
TexColor += tex2D(BP_sTex, TexC - (i * gBlurYOffset));
}

return TexColor;
}

Technique BlurTech
{
Pass p0
{
VertexShader = compile vs_2_0 BlurX_VShader();
PixelShader = compile ps_2_0 BlurX_PShader();
}

pass p1
{
VertexShader = compile vs_2_0 BlurY_VShader();
PixelShader = compile ps_2_0 BlurY_PShader();
}
}

//Final Tech
uniform extern texture BlurredTexture;

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

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

}

float4 FinalPShader(float2 TexC : TEXCOORD0):COLOR
{
float4 Original = tex2D(Full_sTex, TexC);
float4 Blurred = tex2D(Blur_sTex, TexC);

float4 FinalColor = Original+Blurred;

return FinalColor;
}

technique FinalTech
{
pass p0
{
VertexShader = compile vs_2_0 FinalVShader();
PixelShader = compile ps_2_0 FinalPShader();
}
}
[/code]

I checked PIX, and apparently only the first texture is getting drawn. From the Bright-pass till the end is blank.

I would really appreciate the help.

Share this post


Link to post
Share on other sites
Yes you missed the most important part of HDR rendering.
You forgot to calculate luminance and to tonemap the final render target.[url="http://wiki.gamedev.net/index.php/D3DBook:High-Dynamic_Range_Rendering"]Check this article[/url]

Imo, HDRLighting example from DXSDK is really easy to follow and produces good results. Try reading it carefully.

So the pipeline should be:

- Render the scene to a texture
-Transform the texture into a luminance texture with a smaller size than the original texture (example 256x256).
-Downsample the luminance texture multiple times until size is 1x1.
- apply a bright-pass filter and downsample the texture to half its size (also uses the luminance value in some calculations)
- apply a Gaussian blur in two passes(through x-Axis and Y-Axis)
- additively blend the scene texture with the gaussian blur
-Tonemap the final scene texture with the 1x1 luminance value.

Share this post


Link to post
Share on other sites
[quote name='TiagoCosta' timestamp='1306482051' post='4816341']
Yes you missed the most important part of HDR rendering.
You forgot to calculate luminance and to tonemap the final render target.[url="http://wiki.gamedev.net/index.php/D3DBook:High-Dynamic_Range_Rendering"]Check this article[/url]

Imo, HDRLighting example from DXSDK is really easy to follow and produces good results. Try reading it carefully.

So the pipeline should be:

- Render the scene to a texture
-Transform the texture into a luminance texture with a smaller size than the original texture (example 256x256).
-Downsample the luminance texture multiple times until size is 1x1.
- apply a bright-pass filter and downsample the texture to half its size (also uses the luminance value in some calculations)
- apply a Gaussian blur in two passes(through x-Axis and Y-Axis)
- additively blend the scene texture with the gaussian blur
-Tonemap the final scene texture with the 1x1 luminance value.
[/quote]

In the past I have performed the tonemap before the bright-pass. This has a couple of advantages that I can think of:
[list][*]the bright pass doesn't need a changing cut off, just set it to 1.[*]more stages of the pipe-line can be done in rgb8 buffers.[/list]Am I missing something?

Share this post


Link to post
Share on other sites
[quote name='TiagoCosta' timestamp='1306482051' post='4816341']
Yes you missed the most important part of HDR rendering.
You forgot to calculate luminance and to tonemap the final render target.[url="http://wiki.gamedev.net/index.php/D3DBook:High-Dynamic_Range_Rendering"]Check this article[/url]

Imo, HDRLighting example from DXSDK is really easy to follow and produces good results. Try reading it carefully.

So the pipeline should be:

- Render the scene to a texture
-Transform the texture into a luminance texture with a smaller size than the original texture (example 256x256).
-Downsample the luminance texture multiple times until size is 1x1.
- apply a bright-pass filter and downsample the texture to half its size (also uses the luminance value in some calculations)
- apply a Gaussian blur in two passes(through x-Axis and Y-Axis)
- additively blend the scene texture with the gaussian blur
-Tonemap the final scene texture with the 1x1 luminance value.
[/quote]

thanks for the input. I just get too frustrated with DX SDK samples framework sometimes.
i did modify the FX file a bit to include what [url="http://www.gamedev.net/topic/532960-hdr-lighting--bloom-effect/"]SimonJacoby method[/url].
He used a const value for luminance as 2.0f.
But in your method, i have a few questions:
1- In step 1, What do you mean by a luminance texture(do you mean just a floating-point texture)?
2- In step 2, how do you do that??
3- In step 3, by a bright pass filter, do you mean something as simple as Color = Color - float3(0.3f,0.3f,0.3); and that is it or is there something more to it??
4- In the final step, by Tonemapping, do you mean just add the Vignette and the luminance code together or is there something a bit more fancy??

Thanks

Share this post


Link to post
Share on other sites
[quote name='VISQI' timestamp='1306508120' post='4816444']
1- In step 1, What do you mean by a luminance texture(do you mean just a floating-point texture)?
2- In step 2, how do you do that??
3- In step 3, by a bright pass filter, do you mean something as simple as Color = Color - float3(0.3f,0.3f,0.3); and that is it or is there something more to it??
4- In the final step, by Tonemapping, do you mean just add the Vignette and the luminance code together or is there something a bit more fancy??
[/quote]

1. [url="http://en.wikipedia.org/wiki/Luminance"]Luminance.[/url] So basically a single value per pixel that represents its brightness.

2. One method would be to first scale down the full texture to a fixed size (e.g 64x64), then draw the texture using a shader that averages 4 adjacent pixels to a single value until the result is a single pixel.
3. Basically yes. This is also the point at which I would recommend applying the exposure function. I would put the exposure and bright pass filter into the same function, writing the <=1 and >1 values to two separate buffers.
4. Not sure what vignette has to do with it. This is the stage where you accumulate the <1 buffer and the blurred >1 buffer for the final result.

Share this post


Link to post
Share on other sites
I think it's important to keep in mind that HDR, bloom, tone mapping, and exposure are all very separate things (even if they are related). A lot of people just lump them into one process, and incorrectly assume that the way the DirectX or Nvidia samples are the only way to do it.

1. HDR just means you're using a range for lighting and rendering values that's wider than your displayable range.

2. Bloom is an effect meant to simulate glares that occur from bright objects. It doesn't require HDR, but you can do it better with HDR because you can determine which pixels are really really bright..

3. Exposure is just a scalar applied to your HDR values. Since you can't typically view really bright and really dark things simultaneously, adjusting exposure lets you pick whether you want to be able to see the bright stuff or the dark stuff. So if you're in a house you'd use a higher exposure, and then when you step outside to a bright sunny day you'd switch to a lower exposure.You can also implement "auto-exposure" if you want, where you try to choose a good exposure based on what's currently on the screen. Most of the samples use the Reinhard algorithm for this, which uses the geometric mean (log average) of pixel luminance combined with a key value.

4. Tone mapping is applying a curve to HDR pixel values, which is typically nonlinear. Tone mapping is basically like choosing film for a camera: certain tone mapping operators will let you display a wider range of brightnesses, and will do a better job of preserving contrast and detail. However it also affects the final "look", and consequently certain operators might be chosen due to artistic preference. Most of the samples use one of the Reinhard operators for this, and so do a lot of games. Reinhard tends to be good at preserving details, but can produce results that more washed out. "Filmic" operators (popularized by Naughty Dog) tend to preserve less detail, but give look that's more saturated with crushed blacks that's closer to the look movies usually go for.

Share this post


Link to post
Share on other sites
[quote name='bluntman' timestamp='1306490908' post='4816366']
In the past I have performed the tonemap before the bright-pass. This has a couple of advantages that I can think of:
[list][*]the bright pass doesn't need a changing cut off, just set it to 1.[*]more stages of the pipe-line can be done in rgb8 buffers.[/list]Am I missing something?
[/quote]

Usually you don't want to do that (if you can spare the performance) for the same reason you want to do any other post-process effect in HDR: if you don't do it in HDR, the bright spots won't be preserved and will become "washed out". For bloom this usually means all of your bloom blurs out to white, rather than to the actual color of the pixel.

Share this post


Link to post
Share on other sites
[quote name='VISQI' timestamp='1306508120' post='4816444']

3- In step 3, by a bright pass filter, do you mean something as simple as Color = Color - float3(0.3f,0.3f,0.3); and that is it or is there something more to it??

[/quote]

There's no real "right" way to do a threshold for bloom, since bloom is fundamentally a hack and not anything close to a real simulation of glare. So yeah, just subtracting some value (and clamping to 0 so that you don't get negative values) can work just fine.

Share this post


Link to post
Share on other sites
all of this is really easy to understand, but from what i searched, the only good implementation of HDR with bloom effects and all the good stuff is DX SDK which i really have a hard time getting through with it. Is there any other source code that doesn't make me want to bang my head on the wall just for the sack of it??


And i have a few question on the [url="http://wiki.gamedev.net/index.php/D3DBook:High-Dynamic_Range_Rendering"]HDR article[/url] in the D3DBOOK in the luminance transform section:
- In The implementation, why did he fetch it multiple times, shouldn't he calculate the luminance for EACH pixel one pixel at a time??
- Shouldn't he convert the pixels to CIE Yxy then calculate the luminance?? why did he do the opposite??
- And where is equation x??
- Is there a full implementation on how to get the average luminance based on the author's method??

Thanks

Share this post


Link to post
Share on other sites
[quote name='VISQI' timestamp='1306478532' post='4816322']- Render the scene to a texture
- apply a bright-pass filter and downsample the texture to half its size
- apply a Gaussian blur in two passes(through x-Axis and Y-Axis)
- additively blend the scene texture with the gaussian blur[/quote]As mentioned above, this is bloom, not HDR.

Share this post


Link to post
Share on other sites
[quote name='VISQI' timestamp='1306556425' post='4816671']
- In The implementation, why did he fetch it multiple times, shouldn't he calculate the luminance for EACH pixel one pixel at a time??
[/quote]

-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.

Share this post


Link to post
Share on other sites
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??

Share this post


Link to post
Share on other sites
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/"][url="http://www.gamedev.net/topic/532960-hdr-lighting--bloom-effect/"]SimonJacoby method[/url].[/url][/size][/color]
[code]
float3 Color = 1.0f - pow(2.71, -(Vignette * Original * Exposure);
[/code]

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

will this one suffice??

Share this post


Link to post
Share on other sites
[quote name='VISQI' timestamp='1306580028' post='4816748']
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??
[/quote]

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.

Share this post


Link to post
Share on other sites
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.

[code]

//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[i].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[i].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[i].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();
}
}
[/code]

- 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

Share this post


Link to post
Share on other sites
[quote name='VISQI' timestamp='1306765773' post='4817514']
the luminance calculation is not working, please have a look at it.
[/quote]

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:
[code]
//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)
};
[/code]

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...

Share this post


Link to post
Share on other sites
[quote name='TiagoCosta' timestamp='1306775274' post='4817574']
[quote name='VISQI' timestamp='1306765773' post='4817514']
the luminance calculation is not working, please have a look at it.
[/quote]

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:
[code]
//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)
};
[/code]

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??)

Share this post


Link to post
Share on other sites
[quote name='VISQI' timestamp='1306783083' post='4817616']
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).
[/quote]
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...

[quote name='VISQI' timestamp='1306783083' post='4817616']
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??)
[/quote]
Why the position I gave you are in screen-space so no need for WVP matrix.

My vertex shader looks like this:
[code]
VS_OUT QuadVS(VS_IN vIn)
{
VS_OUT vOut;

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

return vOut;
}
[/code]

About the viewports:
[code]
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;
[...]
[/code]

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

Share this post


Link to post
Share on other sites
Ok. I went through PIX to check out why the demo is still not working, and found out that the downsampling code for the Bright pass filter is downsampling only a part of the texture and not all of it.
I am using Bilinear filtering to downsample it
here is the bright pass FX technique that has the downsampling filter
[code]

float4 BP_PShader(float2 TexC : TEXCOORD0):COLOR
{
float dx = 1.0f / SourceDimensions.x;
float3 C0 = tex2D(HDR_sTex, TexC);
float3 C1 = tex2D(HDR_sTex, TexC + float2(dx,0.0f));
float3 C2 = tex2D(HDR_sTex, TexC + float2(0.0f,dx));
float3 C3 = tex2D(HDR_sTex, TexC + float2(dx,dx));

float2 TexelSize = TexC / SourceDimensions.x;
float2 lerps = frac(TexelSize);

float3 C01 = lerps.x*C0 + (1.0f-lerps.x)*C1;
float3 C23 = lerps.x*C2 + (1.0f-lerps.x)*C3;
float3 Color = lerps.y*C01 + (1.0f-lerps.y)*C23;

Color = Color - float3(0.3f,0.3f,0.3f);

Color = max(Color,0.0f);

return float4(Color,1.0f);
}
[/code]
And the luminance texture is still black. I did everything you said about the viewports but the luminance code is still getting zero output.
Here is my function to measure the luminance, maybe there is something i missed in it.
[code]

void RoomApp::MeasureLuminance()
{
LPDIRECT3DTEXTURE9 LumTextures[4] = {0};
LPDIRECT3DSURFACE9 LumSurfaces[4] = {0};
D3DXVECTOR4 LumOffset[16];
int LumSizes[5];
D3DVIEWPORT9 VP;
D3DVIEWPORT9 OriginalVP;
V(gd3dDev->GetViewport(&OriginalVP));

V(D3DXCreateTexture(gd3dDev, 256,256, 1, D3DUSAGE_RENDERTARGET, D3DFMT_L16, D3DPOOL_DEFAULT, &LumTextures[0]));
V(D3DXCreateTexture(gd3dDev, 64,64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_L16, D3DPOOL_DEFAULT, &LumTextures[1]));
V(D3DXCreateTexture(gd3dDev, 16,16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_L16, D3DPOOL_DEFAULT, &LumTextures[2]));
V(D3DXCreateTexture(gd3dDev, 4,4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_L16, D3DPOOL_DEFAULT, &LumTextures[3]));

LumSizes[0] = 256;
LumSizes[1] = 64;
LumSizes[2] = 16;
LumSizes[3] = 4;
LumSizes[4] = 1;

for(int i = 0; i < 4; i++)
{
V(LumTextures[i]->GetSurfaceLevel(0, &LumSurfaces[i]));
}

LPDIRECT3DSURFACE9 BBSurface = 0;

V(gd3dDev->GetRenderTarget(0, &BBSurface));

D3DXVECTOR2 SourceDimensions(WINDOW_WIDTH, WINDOW_HEIGHT);
int index = 0;
for(float i = -1.0f; i <= 1.0f; i++)
for(float j = -1.0f; j <= 1.0f; j++)
{
LumOffset[index].x = i / SourceDimensions.x;
LumOffset[index].y = j / SourceDimensions.y;
LumOffset[index].x = 0.0f;
LumOffset[index].w = 0.0f;

index++;
}

VP.MinZ = 0.0f;
VP.MaxZ = 1.0f;
VP.X = 0;
VP.Y = 0;

//Lum Texture 0 - Initialize Luminance Technique
VP.Width = LumSizes[0];
VP.Height = LumSizes[0];
V(gd3dDev->SetViewport(&VP));
V(gd3dDev->SetRenderTarget(0, LumSurfaces[0]));

V(gd3dDev->BeginScene());

V(gd3dDev->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0));

V(HDR_FX->SetTechnique("Init_Lum_Tech"));
V(HDR_FX->SetTexture(HHDR_FullTex, Full_RTS->GetTex()));
V(HDR_FX->SetVectorArray("gLumOffset", LumOffset, 16));

UINT NumPasses = 0;
V(HDR_FX->Begin(&NumPasses, 0));
V(HDR_FX->BeginPass(0));

V(gd3dDev->SetFVF(D3DFVF_SCREENVERTEX));
V(gd3dDev->SetStreamSource(0, mQuadVB, 0, sizeof(ScreenVertex)));
V(gd3dDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2));

V(HDR_FX->EndPass());
V(HDR_FX->End());

V(gd3dDev->EndScene());

//Lum Texture 1 -> 3 - Iterative Luminance Technique
for(int i = 1; i < 4; i++)
{
index = 0;
for(float x = -2.0f; x <= 1.0f; x++)
for(float y = -2.0f; y <= 1.0f; y++)
{
LumOffset[index].x = x / LumSizes[i];
LumOffset[index].y = y / LumSizes[i];
LumOffset[index].x = 0.0f;
LumOffset[index].w = 0.0f;

index++;
}

VP.Width = LumSizes[i];
VP.Height = LumSizes[i];
V(gd3dDev->SetViewport(&VP));
V(gd3dDev->SetRenderTarget(0, LumSurfaces[i]));
V(gd3dDev->BeginScene());

V(gd3dDev->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0));

V(HDR_FX->SetTechnique("Iter_Lum_Tech"));
V(HDR_FX->SetTexture("ToBeDownSampledTexture", LumTextures[i-1]));
V(HDR_FX->SetVectorArray("gLumOffset", LumOffset, 16));

NumPasses = 0;
V(HDR_FX->Begin(&NumPasses, 0));
V(HDR_FX->BeginPass(0));

V(gd3dDev->SetFVF(D3DFVF_SCREENVERTEX));
V(gd3dDev->SetStreamSource(0, mQuadVB, 0, sizeof(ScreenVertex)));
V(gd3dDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2));

V(HDR_FX->EndPass());
V(HDR_FX->End());

V(gd3dDev->EndScene());
}

//Lum Texture 4 - final Luminance Technique
AvgLum_RTS->BeginScene();
VP.Width = LumSizes[4];
VP.Height = LumSizes[4];
V(gd3dDev->SetViewport(&VP));

V(gd3dDev->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0));

V(HDR_FX->SetTechnique("Final_Lum_Tech"));
V(HDR_FX->SetTexture("ToBeDownSampledTexture", LumTextures[3]));

NumPasses = 0;
V(HDR_FX->Begin(&NumPasses, 0));
V(HDR_FX->BeginPass(0));

V(gd3dDev->SetFVF(D3DFVF_SCREENVERTEX));
V(gd3dDev->SetStreamSource(0, mQuadVB, 0, sizeof(ScreenVertex)));
V(gd3dDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2));

V(HDR_FX->EndPass());
V(HDR_FX->End());

AvgLum_RTS->EndScene();

//Returning back to the backbuffer

V(gd3dDev->SetRenderTarget(0, BBSurface));
V(gd3dDev->SetViewport(&OriginalVP));

for(int i = 0; i < 4; i++)
{
Releaser(LumTextures[i]);
Releaser(LumSurfaces[i]);
}

Releaser(BBSurface);

}
[/code]

Share this post


Link to post
Share on other sites

This topic is 2392 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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