Jump to content
  • Advertisement
Sign in to follow this  
vidalsasoon

Getting rendertarget from GPU

This topic is 4813 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've been having big problems with scene effects lately. sorry for many posts. I'm trying to do a bloom effect that requires 4 passes. I have a rendertarget and a quad ready for this. My post_bloom.fx wants to execute these passes: "Pass=DownSample;" "Pass=GlowH;" "Pass=GlowV;" "Pass=FinalComp;" The shader is also expecting these textures: "SceneMap" "DownsampleMap" "HBlurMap" "FinalBlurMap" Is there an specific order to set these textures? When I set the 1st pass rendertarget to an effect param, can I reuse the same texure on the next pass? or do I take it from the GPU to apply to the second pass? I read it was only possible to get a rendertarget from a GPU but I don't know how to do this :/ The SDK samples have too much information. V. [Edited by - vidalsasoon on September 11, 2005 7:01:53 AM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by vidalsasoon
Is there an specific order to set these textures?
When I set the 1st pass rendertarget to an effect param, can I reuse the same texure on the next pass? or do I take it from the GPU to apply to the second pass?

I read it was only possible to get a rendertarget from a GPU but I don't know how to do this :/ The SDK samples have too much information.

What do you mean by "reuse the same texture on the next pass"? The first pass uses the texture you rendered the original scene into. This pass produces a second texture that is the same as your original, just smaller, and with the areas that you want blurred visible.

This smaller texture is then used as input to your subsequent passes. The texture is blurred horizontally into a third texture (because with current hardware, you cannot use the same texture as both a source and a destination during rendering).

This third texture is the input into the next pass, which blurrs in the vertical direction. In this pass, you can set as your second texture (the one with the scaled down version of the scene) as your render target. The reason is that that texture is the size that you want and it is not the source for this pass.

Now you have the result of blurring in both the horizontal and vertical directions. Now you can apply this to the original, full size rendering by scaling it in your last pass.

Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites

ok, lets say for the first pass ("DownSample"), I set my rendertarget as the texture, the GPU does it's work and makes my texture smaller. this is good.

How do I get this smaller texture so I can feed it to the second pass?

Share this post


Link to post
Share on other sites
Quote:
Original post by vidalsasoon

ok, lets say for the first pass ("DownSample"), I set my rendertarget as the texture, the GPU does it's work and makes my texture smaller. this is good.

How do I get this smaller texture so I can feed it to the second pass?

When you want to render to a texture, you create a texture with the D3DUSAGE_RENDERTARGET flag. One way to do this would be to use the D3DXCreateTexture function. This function can create a texture that you can use as a render target.

In your render loop, you would set this texture as the rendertarget by first getting the level 0 surface of the texture and calling SetRenderTarget:


LPDIRECT3DSURFACE9 pScaledSurface = NULL;
pScaledTexture->GetSurfaceLevel( 0, &pScaledSurface );
pDevice->SetRenderTarget( 0, pScaledSurface );
// perform "DownSample" pass
pScaledSurface->Release();


When the pass is complete, the texture you created as a render target now has the result of the "DownSample" pass. You then you take take this texture and set it as the input for the next pass. You also change the render target to a new texture to store this result:


LPDIRECT3DSURFACE9 pHorizontalSurface = NULL;
pHorizontalBlurTexture->GetSurfaceLevel( 0, pHorizontalSurface );
pDevice->SetRenderTarget( 0, pHorizontalSurface );
pEffect->SetTexture( /*handle*/, pScaledTexture );
// perform "GlowH" pass

...

Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites
Thanks, that was very helpful.

I'm still not able to get this damn bloom to work however :(
I'm getting close... any obvious mistakes? I always end up seeing what is in pass 3.

should I be blending the textures of each pass together???

Here's a screenshot of each pass that i'm making.

any ideas?

Thanks,
V.

Pass 0


Pass 1


Pass 2


Pass 3


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, 0.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 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);
}
}





Rendering Quad...

myeffect.effect.SetValue("SceneMap", _renderTexture);
myeffect.effect.CommitChanges();

dev.SetRenderTarget(0,_downSample.GetSurfaceLevel(0));

myeffect.effect.BeginPass(0);
dev.SetTexture(0,_renderTexture);
dev.SetStreamSource(0, vertBuffer, 0);
dev.VertexFormat = vertFormat;
dev.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);
myeffect.effect.SetValue("DownsampleMap", _downSample);
myeffect.effect.CommitChanges();
myeffect.effect.EndPass();


SurfaceLoader.Save(Global.settings.InstallPath + "p1.jpg", ImageFileFormat.Jpg, _downSample.GetSurfaceLevel(0));


dev.SetRenderTarget(0,_hBlur.GetSurfaceLevel(0));
myeffect.effect.BeginPass(1);
dev.SetTexture(0,_renderTexture);
dev.SetStreamSource(0, vertBuffer, 0);
dev.VertexFormat = vertFormat;
dev.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);
myeffect.effect.SetValue("HBlurMap", _hBlur);
myeffect.effect.CommitChanges();
myeffect.effect.EndPass();


SurfaceLoader.Save(Global.settings.InstallPath + "p2.jpg", ImageFileFormat.Jpg, _hBlur.GetSurfaceLevel(0));


dev.SetRenderTarget(0,_finalBlur.GetSurfaceLevel(0));
myeffect.effect.BeginPass(2);
dev.SetTexture(0,_renderTexture);
dev.SetStreamSource(0, vertBuffer, 0);
dev.VertexFormat = vertFormat;
dev.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);
myeffect.effect.SetValue("FinalBlurMap", _finalBlur);
myeffect.effect.CommitChanges();
myeffect.effect.EndPass();


SurfaceLoader.Save(Global.settings.InstallPath + "p3.jpg", ImageFileFormat.Jpg, _finalBlur.GetSurfaceLevel(0));


dev.SetRenderTarget(0,_backBuffer);
myeffect.effect.BeginPass(3);
dev.SetTexture(0,_renderTexture);
dev.SetStreamSource(0, vertBuffer, 0);
dev.VertexFormat = vertFormat;
dev.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);
myeffect.effect.EndPass();
//myeffect.effect.CommitChanges();

SurfaceLoader.Save(Global.settings.InstallPath + "p4.jpg", ImageFileFormat.Jpg, _backBuffer);



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!