Jump to content
  • Advertisement
Sign in to follow this  
db123

I was confused about this down scale shader

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


DepthStencilState DisableDepth
{
DepthEnable = FALSE;
DepthWriteMask = ZERO;
};
BlendState DisableBlend
{
BlendEnable[0] = false;
};

//#############################################################################
//
// SAMPLERS
//
//#############################################################################
Texture2D <float4>g_SourceTex : TEXTURE0;
SamplerState BilinearSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};

//#############################################################################
struct VS_Output
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD0;
};

//#############################################################################
//
// DOWNSCALE
//
//#############################################################################
VS_Output VS_downscale(in float4 Pos : POSITION)
{
VS_Output OUT;
OUT = (VS_Output)0;
OUT.Pos = float4(Pos.x, Pos.y, 0.5f, 1.0f);
OUT.Tex = Pos.zw;
return OUT;
}
float4 PS_downScale2x2(in VS_Output IN) : SV_TARGET0
{
half4 sample = 0.0f;
return g_SourceTex.Sample(BilinearSampler, IN.Tex.xy);
}
//=============================================================
technique10 Downscale4x4Bilinear
{
pass p0
{
SetVertexShader ( CompileShader( vs_4_0, VS_downscale() ) );
SetGeometryShader( NULL );
SetPixelShader ( CompileShader( ps_4_0, PS_downScale2x2() ) );
SetBlendState( DisableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
SetDepthStencilState( DisableDepth, 0 );
}
}

this code is copy from nv dx10 sdk HDRRendering.

vs input:
[attachment=7594:1.png]

vs output:
[attachment=7595:2.png]


for(int i = 1; i <= m_NumberOfTaps; i++){
m_SourceTex->SetResource( m_FilterTapsSRV[i-1] );
m_D3DDevice->RSSetViewports( 1, &m_DownsampleQuadCoords[i-1].Viewport );
m_D3DDevice->OMSetRenderTargets(1, &m_FilterTapsRTV, NULL);
m_D3DDevice->IASetVertexBuffers( 0, 1, &m_DownsampleQuadCoords[i-1].VBdata, &stride, &offset );
for( UINT p = 0; p < techDesc.Passes; ++p )
{
m_TechniqueDownscale->GetPassByIndex( p )->Apply(0);
m_D3DDevice->Draw(3, 0);
}
}


it is render a primitive with three vertices, but why it can be used to down scale a surface.
formerly, we need create a vertex buffer, a index buffer, a input layout by these data:

struct FQuadVertex
{
float3 vPos;
float2 vTex;
};
static const FQuadVertex Vertices[4] =
{
{ float3(-1.0f, -1.0f, 0.0f), float2(0.0f, 1.0f) },
{ float3(-1.0f, 1.0f, 0.0f), float2(0.0f, 0.0f ) },
{ float3( 1.0f, 1.0f, 0.0f), float2(1.0f, 0.0f) },
{ float3( 1.0f, -1.0f, 0.0f), float2(1.0f, 1.0f) }
};
static const word_t Indices[6] =
{
0, 1, 2,
0, 2, 3
};


then, draw

DrawIndexed( EPT_TriangleList, 0, 0, 2 );


what the difference between these two approaches?
which is the better way?
the first approach, the output texture texcoordinates is greater than 1.0, and the primitive is just a triangle, how does it cover the full screen?

Share this post


Link to post
Share on other sites
Advertisement
In the first approach you create a triangle that is larger than the viewport. It will automatically get clipped to the viewport, so the results will be identical to the method where you render a quad. However, the triangle might be slightly faster on some GPUs. First, you have to transform fewer vertices (though this is almost certainly negligible). Second, in the latter method you send two triangles, which means there is a seam running down the diagonal. Depending on the GPU, it may render pixels along the seam twice. So there might be a slight performance benefit to using a single triangle, but it is probably not noticeable.

Share this post


Link to post
Share on other sites

In the first approach you create a triangle that is larger than the viewport. It will automatically get clipped to the viewport, so the results will be identical to the method where you render a quad. However, the triangle might be slightly faster on some GPUs. First, you have to transform fewer vertices (though this is almost certainly negligible). Second, in the latter method you send two triangles, which means there is a seam running down the diagonal. Depending on the GPU, it may render pixels along the seam twice. So there might be a slight performance benefit to using a single triangle, but it is probably not noticeable.


So that was it! thank you~!
smile.png smile.png

Share this post


Link to post
Share on other sites
Note that in D3D10 and later, you don't even have to use a vertex buffer for this. It is possible to use SV_VertexID as a parameter to the vertex shader, and generate the return values (transformed vertices) based on that.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!