Jump to content
  • Advertisement
Sign in to follow this  
vidalsasoon

post processing effects nightmare part IV

This topic is 4816 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

I'm going crazy getting this bloom effect to work... I'm not sure whether the problem is with rendering the quad or setting the semantic values. anyway, from the images I can tell something is happening at least :/ This is my code to draw my quad with the rendertarget.

		public void Draw(Surface _backBuffer, Texture _renderTexture)
		{
					
			dev.SetRenderTarget(0,_backBuffer); 
			
			myeffect.World = Matrix.Identity;
			myeffect.Texture = _renderTexture;
			myeffect.SetRealTimeShader();
            
			int numPasses = myeffect.effect.Begin(0);
			for (int pass = 0; pass < numPasses; pass++)
			{
				myeffect.effect.BeginPass(pass);


				dev.SetTexture(0,_renderTexture);
				dev.SetStreamSource(0, vertBuffer, 0);
				dev.VertexFormat = vertFormat;
				dev.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);

				myeffect.effect.EndPass();
			}
			myeffect.effect.End();

			dev.SetTexture(0,null);


			dev.SetRenderTarget(0,_renderTexture.GetSurfaceLevel(0)); 
		}

ORIGINAL WITH BLOOM!?

Share this post


Link to post
Share on other sites
Advertisement
Looks like I was setting the DepthMap : RENDERDEPTHSTENCILTARGET with my rendertarget texture instead of a different texture.

I dunno what this "RENDERDEPTHSTENCILTARGET" semantic is supposed to represent :(

A different rendertarget?

V.


post_bloom.fx

/*********************************************************************NVMH3****
File: $Id: Scene_bloom.fx

Copyright NVIDIA Corporation 2004
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Comments:
Glow/bloom post processing effect
Down-samples scene first for performance (reduces size by 4)
Thresholds luminance for extra highlights
Separable filter, filters in X, then in Y
Takes advantage of bilinear filtering for blur

******************************************************************************/


float4 ClearColor : DIFFUSE = { 1.0f, 0.0f, 1.0f, 1.0f};
float ClearDepth = 1.0f;

float Script : STANDARDSGLOBAL
<
string UIWidget = "none";
string ScriptClass = "scene";
string ScriptOrder = "postprocess";
string ScriptOutput = "color";

// We just call a script in the main technique.
string Script = "Technique=Bloom;";

> = 0.8;

///////////////////////////////////////////////////////////
/////////////////////////////////////// Tweakables ////////
///////////////////////////////////////////////////////////

float SceneIntensity <
string UIName = "Scene intensity";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 2.0f;
float UIStep = 0.1f;
> = 0.5f;

float GlowIntensity <
string UIName = "Glow intensity";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 2.0f;
float UIStep = 0.1f;
> = 0.5f;

float HighlightThreshold <
string UIName = "Highlight threshold";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 1.0f;
float UIStep = 0.1f;
> = 0.9f;

float HighlightIntensity <
string UIName = "Highlight intensity";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 10.0f;
float UIStep = 0.1f;
> = 0.5f;

///////////////////////////////////////////////////////////
///////////////////////////// Render-to-Texture Data //////
///////////////////////////////////////////////////////////

float2 WindowSize : VIEWPORTPIXELSIZE < string UIWidget = "none"; >;
float downsampleScale = 0.25;

float BlurWidth <
string UIName = "Blur width";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 10.0f;
float UIStep = 0.5f;
> = 2.0f;

texture SceneMap : RENDERCOLORTARGET
<
float2 ViewportRatio = { 1.0, 1.0 };
int MIPLEVELS = 1;
string format = "X8R8G8B8";
>;
texture DepthMap : RENDERDEPTHSTENCILTARGET
<
float2 ViewportRatio = { 1.0, 1.0 };
string format = "D24S8";
>;

sampler SceneSampler = sampler_state
{
texture = <SceneMap>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

texture DownsampleMap : RENDERCOLORTARGET
<
float2 ViewportRatio = { 0.25, 0.25 };
int MIPLEVELS = 1;
string format = "A8R8G8B8";
>;

sampler DownsampleSampler = sampler_state
{
texture = <DownsampleMap>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

texture HBlurMap : RENDERCOLORTARGET
<
float2 ViewportRatio = { 0.25, 0.25 };
int MIPLEVELS = 1;
string format = "A8R8G8B8";
>;

sampler HBlurSampler = sampler_state
{
texture = <HBlurMap>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

texture FinalBlurMap : RENDERCOLORTARGET
<
float2 ViewportRatio = { 0.25, 0.25 };
int MIPLEVELS = 1;
string format = "A8R8G8B8";
>;

sampler FinalBlurSampler = sampler_state
{
texture = <FinalBlurMap>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};

///////////////////////////////////////////////////////////
/////////////////////////////////// data structures ///////
///////////////////////////////////////////////////////////

struct VS_OUTPUT_BLUR
{
float4 Position : POSITION;
float2 TexCoord[8]: TEXCOORD0;
};

struct VS_OUTPUT
{
float4 Position : POSITION;
float2 TexCoord0 : TEXCOORD0;
float2 TexCoord1 : TEXCOORD1;
};

struct VS_OUTPUT_DOWNSAMPLE
{
float4 Position : POSITION;
float2 TexCoord[4]: TEXCOORD0;
};

////////////////////////////////////////////////////////////
////////////////////////////////// vertex shaders //////////
////////////////////////////////////////////////////////////

// generate texture coordinates to sample 4 neighbours
VS_OUTPUT_DOWNSAMPLE VS_Downsample(float4 Position : POSITION,
float2 TexCoord : TEXCOORD0)
{
VS_OUTPUT_DOWNSAMPLE OUT;
float2 texelSize = downsampleScale / WindowSize;
float2 s = TexCoord;
OUT.Position = Position;
OUT.TexCoord[0] = s;
OUT.TexCoord[1] = s + float2(2, 0)*texelSize;
OUT.TexCoord[2] = s + float2(2, 2)*texelSize;
OUT.TexCoord[3] = s + float2(0, 2)*texelSize;
return OUT;
}

// generate texcoords for blur
VS_OUTPUT_BLUR VS_Blur(float4 Position : POSITION,
float2 TexCoord : TEXCOORD0,
uniform int nsamples,
uniform float2 direction
)
{
VS_OUTPUT_BLUR OUT = (VS_OUTPUT_BLUR)0;
OUT.Position = Position;
float2 texelSize = BlurWidth / WindowSize;
float2 s = TexCoord - texelSize*(nsamples-1)*0.5*direction;
for(int i=0; i<nsamples; i++) {
OUT.TexCoord = s + texelSize*i*direction;
}
return OUT;
}

VS_OUTPUT VS_Quad(float4 Position : POSITION,
float2 TexCoord : TEXCOORD0)
{
VS_OUTPUT OUT;
float2 texelSize = 1.0 / WindowSize;
OUT.Position = Position;
// don't want bilinear filtering on original scene:
OUT.TexCoord0 = TexCoord + texelSize*0.5;
OUT.TexCoord1 = TexCoord + texelSize*0.5/downsampleScale;
return OUT;
}

//////////////////////////////////////////////////////
////////////////////////////////// pixel shaders /////
//////////////////////////////////////////////////////

half luminance(half3 c)
{
return dot( c, float3(0.3, 0.59, 0.11) );
}

// this function should be baked into a texture lookup for performance
half highlights(half3 c)
{
return smoothstep(HighlightThreshold, 1.0, luminance(c.rgb));
}

half4 PS_Downsample(VS_OUTPUT_DOWNSAMPLE IN,
uniform sampler2D tex) : COLOR
{
half4 c;
#if 0
// sub sampling
c = tex2D(tex, IN.TexCoord[0]);
#else
// box filter
c = tex2D(tex, IN.TexCoord[0]) * 0.25;
c += tex2D(tex, IN.TexCoord[1]) * 0.25;
c += tex2D(tex, IN.TexCoord[2]) * 0.25;
c += tex2D(tex, IN.TexCoord[3]) * 0.25;
#endif

// store hilights in alpha
c.a = highlights(c.rgb);

return c;
}

// blur filter weights
const half weights7[7] = {
0.05,
0.1,
0.2,
0.3,
0.2,
0.1,
0.05,
};

const half weights7_Central[7] = {
0.0,
0.0,
0.2,
0.6,
0.2,
0.0,
0.0,
};

// fx doesn't support variable length arrays
// otherwise we could generalize this
half4 PS_Blur7(VS_OUTPUT_BLUR IN,
uniform sampler2D tex,
uniform half weight[7]
) : COLOR
{
half4 c = 0;
// this loop will be unrolled by compiler
for(int i=0; i<7; i++) {
c += tex2D(tex, IN.TexCoord) * weight;
}
return c;
}


half4 PS_Display(VS_OUTPUT IN,
uniform sampler2D tex) : COLOR
{
return tex2D(tex, IN.TexCoord1);
}

half4 PS_Comp(VS_OUTPUT IN,
uniform sampler2D sceneSampler,
uniform sampler2D blurredSceneSampler) : COLOR
{
half4 orig = tex2D(sceneSampler, IN.TexCoord0);
half4 blur = tex2D(blurredSceneSampler, IN.TexCoord1);
return SceneIntensity*orig + GlowIntensity*blur + HighlightIntensity*blur.a;
}

////////////////////////////////////////////////////////////
/////////////////////////////////////// techniques /////////
////////////////////////////////////////////////////////////
technique Bloom
<
string Script = "ClearSetDepth=ClearDepth;"
"RenderColorTarget=SceneMap;"
"RenderDepthStencilTarget=DepthMap;"
"ClearSetColor=ClearColor;"
"ClearSetDepth=ClearDepth;"
"Clear=Color;"
"Clear=Depth;"
"ScriptSignature=color;"
"ScriptExternal=;"
"Pass=DownSample;"
"Pass=GlowH;"
"Pass=GlowV;"
"Pass=FinalComp;";
>
{
pass DownSample
<
string Script = "RenderColorTarget0=DownsampleMap;"
"ClearSetColor=ClearColor;"
"Clear=Color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Downsample();
PixelShader = compile ps_2_0 PS_Downsample(SceneSampler);
}
pass GlowH
<
string Script = "RenderColorTarget0=HBlurMap;"
"ClearSetColor=ClearColor;"
"Clear=Color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(1, 0));
// PixelShader = compile ps_2_0 PS_Blur7(SceneSampler, weights7);
PixelShader = compile ps_2_0 PS_Blur7(DownsampleSampler, weights7);
}
pass GlowV
<
string Script = "RenderColorTarget0=FinalBlurMap;"
"ClearSetColor=ClearColor;"
"Clear=color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(0, 1));
PixelShader = compile ps_2_0 PS_Blur7(HBlurSampler, weights7);
}

pass GlowH_Central
<
string Script = "RenderColorTarget0=HBlurMap;"
"ClearSetColor=ClearColor;"
"Clear=Color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(1, 0));
PixelShader = compile ps_2_0 PS_Blur7(DownsampleSampler, weights7_Central);
}
pass GlowV_Central
<
string Script = "RenderColorTarget0=FinalBlurMap;"
"ClearSetColor=ClearColor;"
"Clear=Color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(0, 1));
PixelShader = compile ps_2_0 PS_Blur7(HBlurSampler, weights7_Central);
}
pass FinalComp
<
string Script = "RenderColorTarget=;"
"RenderDepthStencilTarget=;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Quad();
PixelShader = compile ps_2_0 PS_Comp(SceneSampler, FinalBlurSampler);
}
}

Share this post


Link to post
Share on other sites
Quote:
Original post by vidalsasoon
I dunno what this "RENDERDEPTHSTENCILTARGET" semantic is supposed to represent

Looks to me like that FX file is using the DXSAS annotations - or a variant thereof. I'm not up to speed on the finer details of DXSAS yet, but you probably want to have a read through the DXSAS stuff if you want to understand a lot of that FX file [smile]

DirectX Standard Annotations and Semantics Reference

With respect to your original problem... I can't see the exact reason from that FX file you've posted - it's a little lengthy to read through. But it looks like your result is just getting washed out - probably by adding the results together rather than modulating (for example). Maybe try tweaking some of the parameters and/or biases?

hth
Jack

Share this post


Link to post
Share on other sites
My semantics are based on nVidia's latest SDK (not DXSAS 1.0) and the bloom.fx file is also from the nVidia SDK so I know the error is on my end...

The info on SAS has been pretty weak and the conflicting standards has been a major annoyance.

I'm gonna try a little harder to find out how to get the correct RENDERDEPTHSTENCILTARGET and see if I can make it more efficient :/

Share this post


Link to post
Share on other sites
Are you sure this effect is designed to be run with all the passes in the order they are written in the FX file?

From what I can read out of the scripts in it, you should only be using 4 passes out of the 6 in the file:
Quote:

"Pass=DownSample;"
"Pass=GlowH;"
"Pass=GlowV;"
"Pass=FinalComp;";


I think you might need to skip the two passes with Central after the name. Try this as a temporary hack to see if it helps:

for (int pass = 0; pass < numPasses; pass++)
{
if ((pass != 3) & (pass != 4))
{
myeffect.effect.BeginPass(pass);


dev.SetTexture(0,_renderTexture);
dev.SetStreamSource(0, vertBuffer, 0);
dev.VertexFormat = vertFormat;
dev.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);

myeffect.effect.EndPass();
}
}



Hope this helps :).

Share this post


Link to post
Share on other sites
Well, I removed those 2 passes from the effect file. I got a better framerate but had the exact same results :(

any idea why those passes were included in the first place?

Share this post


Link to post
Share on other sites
Well, first off, DepthMap is only used in a script, so I doubt it's anything critical for the effect. It's probably just a standard depth-stencil buffer there for no real reason, since this effect doesn't use depth nor stenciling. Maybe it's just there becuase this is a post-proccess framework and might be used.

At any rate, I think the central passes use a different technique to do the bloom, which just looks better/worse and works slower/faster. Once the effect works, try using them instead of the regular passes and see if you get anything different.

I can't tell much from your code, but you are actually setting the texture in the effect, right? theres this line:
Quote:

myeffect.Texture = _renderTexture;

but I'm not sure what it's actually doing.
From what I could figure out, somewhere, you should be settings the "SceneMap" texture to your "_renderTexture".

Hope this helps.

Share this post


Link to post
Share on other sites

shaderdata = (ShaderData)myeffect.shaderparam["SceneMap"];
myeffect.shaderparam["SceneMap"] = new ShaderData(shaderdata.effectHandle,_renderTexture);

shaderdata = (ShaderData)myeffect.shaderparam["DownsampleMap"];
myeffect.shaderparam["DownsampleMap"] = new ShaderData(shaderdata.effectHandle,_renderTexture);

shaderdata = (ShaderData)myeffect.shaderparam["HBlurMap"];
myeffect.shaderparam["HBlurMap"] = new ShaderData(shaderdata.effectHandle,_renderTexture);

shaderdata = (ShaderData)myeffect.shaderparam["FinalBlurMap"];
myeffect.shaderparam["FinalBlurMap"] = new ShaderData(shaderdata.effectHandle,_renderTexture);

shaderdata = (ShaderData)myeffect.shaderparam["DepthMap"];
myeffect.shaderparam["DepthMap"] = new ShaderData(shaderdata.effectHandle,_renderTexture);



These are my custom values. Any other values provided by the fx file are provided by default. Modifying my hashtable triggers an event that does an effect "SetValue(..)" to override the param. it works. But like I said, i'm not so sure i'm giving it the right data.

I need to read up more on post processing effects.

Share this post


Link to post
Share on other sites
Well, this definatly is not good. Setting them all to the same texture is definatly not what you want to be doing. This is a sequential effect, so you need to apply the second pass to the results of the first pass, third to second and so on.
I think you need to be making another rendertarget. Then, you do the first pass with this new texture as the rendertarget, and the texture with the scene as the input texture (the smapler for the current pass). Then, for the next pass, you swap the two, rendering with your results, over the previous rendertarget (you can make a third target if you require the original texture for something else.
For the last pass, you can render directly to the backbuffer.

You can also have a look at the DX9 Post Proccess sample, and see how it works, theres a very similar bloom effect there. I do think it is quite comlicated there, with the DX Sample framework and all.

Good luck at any rate, I hope this cleared this up a bit.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!