0
\$\begingroup\$

I'm new to DirectX and I am trying to get my feet wet by making a simple 2D game. I chose DirectX 11 and am using the DirectX ToolKit helper library which recommended I start with DX11 and not DX12.

The guide I am following to create an animating sprite is working great except for when attempting to draw a single sprite from the sprite sheet I am seeing "ghosting" of other sprites behind it. I created the sprite sheet and saved it as a PNG and also as a BMP and it seems to happen either way.

Here is the sprite sheet I am using:

pony sprite sheet

It is 336px width, 48px height, in 48px x 48px square sprites. If I render the entire sprite sheet, or if I render the first sprite (0,0,48,48), it looks fine, but if I attempt to render the 2nd, 3rd, 4th, etc. this is how it renders: pony with ghosting

Here is the code I am using to load the PNG file as a texture:

ComPtr<ID3D11Resource> ponyIdleResource;

DX::ThrowIfFailed(
    CreateWICTextureFromFile(_D3dDevice.Get(), L"assets/pony_idle.png",
        ponyIdleResource.GetAddressOf(),
        _Texture.ReleaseAndGetAddressOf())
);

ComPtr<ID3D11Texture2D> ponyIdleTexture;
DX::ThrowIfFailed(ponyIdleResource.As(&ponyIdleTexture));

CD3D11_TEXTURE2D_DESC ponyIdleDesc;
ponyIdleTexture->GetDesc(&ponyIdleDesc);

and here is the code I am using to draw:

_SpriteBatch->Begin();

RECT sourceRect;
sourceRect.left = 48;
sourceRect.top = 0;
sourceRect.right = 96;
sourceRect.bottom = 48;

_SpriteBatch->Draw(_Texture.Get(), _ScreenPos, &sourceRect, Colors::White, 0, _Origin);

_SpriteBatch->End();

If I pass the RECT in as 0,0,48,48, it looks fine. Is there some special way I need to format my image? I've tried it as both PNG and BMP.

\$\endgroup\$
3
  • \$\begingroup\$ Do your bitmaps have an alpha channel? If they do, are they using premultiplied alpha? SpriteBatch defaults to blend state assuming premultiplied alpha. \$\endgroup\$ Apr 1 '19 at 23:23
  • \$\begingroup\$ That was it. Thanks. I found out I need to change my call to Begin(SpriteSortMode_Deferred, _States->NonPremultiplied()). Also, alternately, I suppose I could save my image in the premultiplied alpha format? But I honestly don't know how to do that. \$\endgroup\$ Apr 2 '19 at 18:21
  • \$\begingroup\$ You can use texconv to convert it to pmalpha. See DirectXTex \$\endgroup\$ Apr 2 '19 at 20:13
1
\$\begingroup\$

SpriteBatch uses premultiplied blending by default. The spritesheet in question is using straight-alpha, hence the 'ghosting'.

Fix is to either:

(a) Use straight-alpha blending

_SpriteBatch->Begin(SpriteSortMode_Deferred, _States->NonPremultiplied())

(b) Convert the spritesheet to pmalpha (this creates a ponyidle.dds with pmalpha instead of straight alpha)

texconv ponyidle.png -pmalpha -m 1

See Shawn Hargreaves' Blog, DirectX Tool Kit, and DirectXTex.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .