Jump to content
  • Advertisement
Sign in to follow this  
theScore

DX11 How to make downsampling with directx 11 ?

Recommended Posts

Hello !

I have a texture in 4K resolution and I need to downsample this texture to get a 1x1 resulting texture.

I know that there are intermediate downsamplings before getting to the 1x1 texture but how downsampling works and how do I have to code my pixel shader to downsample my texture ?

Share this post


Link to post
Share on other sites
Advertisement

For each slice, you just use a simple copy-pixel pixel shader and adjust your UVs with 0.5 texel offset with linear filtering - just continue this down to the 1x1 texture. That way, you let the hardware filtering do the job of averaging the pixels with nearly no cost, since you're sampling in-between texels :)

 

Share this post


Link to post
Share on other sites
11 hours ago, vinterberg said:

For each slice, you just use a simple copy-pixel pixel shader and adjust your UVs with 0.5 texel offset with linear filtering - just continue this down to the 1x1 texture. That way, you let the hardware filtering do the job of averaging the pixels with nearly no cost, since you're sampling in-between texels :)

 

So you mean the pixel shader would look like something like this :

pixelOut = pixelIN ; 

?

Share this post


Link to post
Share on other sites

Pseudo-code:

for (slice = (nslices - 1) to 1 step -1)
{
	setrendertarget(texture[slice - 1]);				// render to half-size texture
	pixelshader->setinputtexture(texture[slice]);
	texwidth = texture[slice].width;					// the double-size texture we want to downsample
	texheight = texture[slice].height;
	float u_offset = (1.0f / texwidth) / 2.0f;			// half texel size
	float v_offset = (1.0f / texheight) / 2.0f;
	pixelshader->setUVoffset(u_offset, v_offset);
	pixelshader->run();									// draw a fullscreen
}

pixelshader
{
	pixel_out = texture_sample(texture_input, vertexshader_UV + UVoffset);
};

 

Share this post


Link to post
Share on other sites
13 hours ago, belfegor said:

I thought we didnt need pixel offset since dx11?

We don't, but here it's set so deliberately to use bilinear filtering for downsampling.

Aside: You can use the API to do this, though you won't have control of the filtering: ID3D11DeviceContext::GenerateMips (note the mandatory creation flags for the texture) .

Share this post


Link to post
Share on other sites

I am confused as what to believe is true now.

For example, i am looking at MJP shadow sample project, where he downsample/scale texture, there is no "pixel offsets" applied, just bilinear filter:

 

quad verts

QuadVertex verts[4] =
    {
        { XMFLOAT4(1, 1, 1, 1), XMFLOAT2(1, 0) },
        { XMFLOAT4(1, -1, 1, 1), XMFLOAT2(1, 1) },
        { XMFLOAT4(-1, -1, 1, 1), XMFLOAT2(0, 1) },
        { XMFLOAT4(-1, 1, 1, 1), XMFLOAT2(0, 0) }
    };

 

quad vertex shader

VSOutput QuadVS(in VSInput input)
{
    VSOutput output;

    // Just pass it along
    output.PositionCS = input.PositionCS;
    output.TexCoord = input.TexCoord;

    return output;
}

 

// Uses hw bilinear filtering for upscaling or downscaling
float4 Scale(in PSInput input) : SV_Target
{
    return InputTexture0.Sample(LinearSampler, input.TexCoord);
}

 

Share this post


Link to post
Share on other sites

Are you interested only in the 1x1 version ? or do you need all the chain ? To do short, Are you computing the average exposure for exposure adaptation or something else ?

If you are interested only in the 1x1 result as i understand your question, you should forget about pixel shader, running some compute looping over the image, keeping the averaging in groupshared memory or in register will outperform the bandwidth of writing and reading full surface plus you get rid of expensive pipeline flush between the different reduction pass ( because of going from rtv to srv ).

If you are interested in the full chain, running compute can also outperform, you can for example again save on reads by having a compute generating 3 mip in one run, doing the extra 2 by reusing what it read for the first reduction and working in groupshared memory.

Forget also about the legacy GenerateMips, it is not a hardware feature and usually does a sub optimal job compared to a hand crafted solution.

 

Share this post


Link to post
Share on other sites

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  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Bobby Horn
      Hi everyone I'm a new game designer I'm currently getting my online bachelors degree from full sail University. I'm looking for a development team to make a JRPG. I'm doing this as a side project. I'm just started to learn how to use unity and I pick up on things quickly. I've been obbsed with making a JRPG game since I played final fantasy 7, and 8. I have the plot idea but I'm stuck on making the rest of the storyline. I know how many characters I'd like to have as part of the main playable ones and along with the ones that aid sometimes. I also decided on the villain for the game. There are some other details I thought about for the characters along with the turned based battle system and how I would like to do the magic users. I'm highly motivated to get this developed before I graduate. If you are interested to know more please contact me
    • By Ricardo3Ddev
      Hi guys!
      This is a independent game being produced by me and my brother. We’ve been working on it for about 6 months and we’ve already done a good part of the game. We hope to finalize and make it available on Steam by the end of this year.
      We are using Blender 3D and Gimp software for production.
       
      About the Game: Dongo Adventure will be a 3D platform style game, where the main character (Dongo) is a mouse that ventures through various scenarios (sewers, culverts, streets, electric grid, etc.) and faces several enemies along the way (cockroaches, mosquitoes, spiders, toxic gases, electrical wires, etc.). He carries a basket / backpack with cheeses that he uses to throw and defend himself from enemies, as well as being able to push objects that helps him to overcome obstacles. The ultimate goal will be a surprise!
      The game follows the style of classic platform games, bringing many surprises and challenges.
       
      Now we are developing new scenarios and enemies. We hope to publish news soon...
      Game page on Steam: http://store.steampowered.com/app/811450/Dongo_Adventure/ - (Teaser UPDATED)
      Dongo Adventure (Indie Game Project) – First Gameplay Teaser + Making Of: https://www.youtube.com/watch?v=X2nmxtkE0xk
      Dongo Adventure (Indie Game Project) – First Gameplay Teaser (UPDATED) + Making Of: https://vimeo.com/250501345
       
      Thanks for following the project!

    • By Mailbox
      Hello,
      I'm in the midst of developing a simple 3d physics engine, but have been stuck on a problem for quite a while now. I would really appreciate it if someone could have a look at it, because I'm at a loss.
      The issue I'm having concerns the collision response code, which seems to fail spectacularly in some cases, generating wrong impulse magnitudes. Specifically, something with the angular part of it is wrong, since it works as expected when only dealing with the linear part.
      I'm still not sure if I calculate the inertia tensor in world coordinates the right way, so that could be one possible culprit (though I've tried a few different ways). Impulses seem to be applied correctly to the bodies, so I think the error lies in the calculation of the impulse magnitude denominator.
      I've checked it many times with the way the Bullet physics engine does it, with the formulas available at Wikipedia, and some other sources, to no avail.
      The bodies simply keep bouncing off eachother (even though there is supposed to be no restitution) or spinning wildly on collisions.
      Here is the code that deals with the collision response:
      Vector3 originA = contactOrigin - bodyA.Position; Vector3 originB = contactOrigin - bodyB.Position; Vector3 velocityA = bodyA.Velocity + Vector3::Cross(bodyA.AngularVelocity, originA); Vector3 velocityB = bodyB.Velocity + Vector3::Cross(bodyB.AngularVelocity, originB); Vector3 velocity = velocityA - velocityB; Matrix3x3 inverseWorldInertiaTensorA = Matrix3x3::Scale(bodyA.InverseInertia) * Matrix3x3::Rotate(bodyA.Orientation); Matrix3x3 inverseWorldInertiaTensorB = Matrix3x3::Scale(bodyB.InverseInertia) * Matrix3x3::Rotate(bodyB.Orientation); float normalVelocity = Vector3::Dot(velocity, contactNormal); if (normalVelocity > 0.f) { float impulseDenominator = bodyA.InverseMass + bodyB.InverseMass + Vector3::Dot(Vector3::Cross(inverseWorldInertiaTensorA * Vector3::Cross(originA, contactNormal), originA), contactNormal) + Vector3::Dot(Vector3::Cross(inverseWorldInertiaTensorB * Vector3::Cross(originB, contactNormal), originB), contactNormal); float j = -normalVelocity / impulseDenominator; bodyA.Velocity += j * bodyA.InverseMass * contactNormal; bodyB.Velocity -= j * bodyB.InverseMass * contactNormal; bodyA.AngularVelocity += j * (inverseWorldInertiaTensorA * Vector3::Cross(originA, contactNormal)); bodyB.AngularVelocity -= j * (inverseWorldInertiaTensorB * Vector3::Cross(originB, contactNormal)); } Thanks in advance!
    • By Luca Falco
      https://www.youtube.com/watch?v=UMoc52DEoC8     ABOUT THE GAME: Room54 is a first-person Horror/adventure  Videogame for pc,mac and linux users. the game is currently under development by a very small team, we put so much effort in this project and we are keep doing our best for that we are going to launch a kickstarter campaing in order to reach our ideal budget to complete the project, we hope the GameDev community can help us a lot                      STORY:   Daniel is a family father like many other, one day he decide with your wife and his daughter  to spend her winter holidays at their mountain house that they have recently buy in  mountain ,a  wonderful place surrounded by the nature of the woods,  Completely far away from the caotic city life. During their holidays Daniel and his family will understand that they are not welcome there and they will discover an  hided and disturbing part of the valley that they have never seen before                       GAMEPLAY:   You will play as Daniel, a father that will try to save his family, your gameplay will be focused on discovering secrets places around valley,investigating and trying to survive, you will find object that will help you solve enigma and to stay alive. The immersive audio and  environment will make you feel constantly follow by an high anxiety dose  during the game.                         SOCIAL PAGES:     Follow us to get the latest development news and insights     IndieDB:     http://www.indiedb.com/games/room54   Twitter:       https://twitter.com/Room54Thegame   facebook:   https://www.facebook.com/Room54/
    • By Gnollrunner
      Hi again,  After some looking around I have decided to base my game directly on Direct X rather than using an existing game engine.  Because of the nature of the stuff I'm doing it just didn't seem to fit very well and I kept running into road blocks.  At this point I have a big blob of code for doing fractal world generation and some collision code,  and I'm trying to put it into some form that resembles a game engine.  Since I've never used one before It's a bit alien to me ..... so can someone direct me to a book, website, article, whatever... that covers this?  I'm mainly looking for stuff that covers C++ library design. I'm not adverse to using 3rd party tools for stuff I can used them for.
  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!