Advertisement

How to stretch a resource with filter

Started by July 28, 2019 05:26 AM
4 comments, last by MJP 5 years, 6 months ago

I need to stretch a texture into a larger rendertarget ,then present to the dialog window which hasn't the same size either.

And all the surfaces have the same aspect ratio.

In dx9, i can use "stretch" and "present" method easily, as they both have filter feature. But dx11 does not support.

Do i have to use shader to render a rect. I am confused about the efficiency, cause it has to pass rasterization.

Is there any better ways, i need help, thanks.

Yes, you'll need to use a shader. You'll want to draw a fullscreen quad/triangle, and in the pixel shader, for every output pixel, sample the corresponding input. You specify the filter in the sampler. This is the efficient way to do it on modern hardware.

The Present operation will stretch for you (unless you're trying to be fancy and have it not, using DXGI_SCALING in your swapchain parameters, but you'd have to really be trying).

Advertisement
On 7/28/2019 at 9:25 PM, SoldierOfLight said:

Yes, you'll need to use a shader. You'll want to draw a fullscreen quad/triangle, and in the pixel shader, for every output pixel, sample the corresponding input. You specify the filter in the sampler. This is the efficient way to do it on modern hardware.

The Present operation will stretch for you (unless you're trying to be fancy and have it not, using DXGI_SCALING in your swapchain parameters, but you'd have to really be trying).

thank you !!!:D

You can use a compute shader and that way you will not have to set up the raster pipeline. With a compute shader, you will need to write to a RWTexture2D, instead of returning an output like a pixel shader, and set up a correct thread count, but it is a lot less work than a vertex shader + pixel shader. A simple example (just from the top of my head, I haven't compiled):


Texture2D<float4> input : register(t0);
SamplerState sam : register(s0);

RWTexture2D<float4> output : register(u0);

[numthreads(8,8,1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
  output[DTid.xy] = input.SampleLevel(sam, (float2)DTid.xy / input_texture_resolution.xy, 0);
}

Such a shader will need to be started with a dispatch command:


deviceContext->Dispatch((input_texture_resolution.x + 7) / 8, (input_texture_resolution.y + 7 ) / 8, 1);

The dispatch command takes the input texture resolution and divides by the thread group size, so that each thread will work on a single pixel. +7 is there so that the integer divide doesn't underestimate if the resolution is not divisible by thread group size (which is 8 in this case). Good luck!

You can also use SpriteBatch from DirectXTK to scale up a texture and write it to a render target.

This topic is closed to new replies.

Advertisement