0

I had posted this on Gamedev, however, it's been a few days and no bites. I wanted to see if anyone has an idea what I've missed.

Normally I'd post these as two questions, but I have a feeling they're intertwined. In short, I have a particle system that generates data for a sprite to display on a transparent surface. It's then sent to a geometry shader (through a pass through vertex shader) to extrude a single vertex into quads, then finally to a pixel shader (code below).

The pixel colors are sampled from a 32bit DDS (using an alpha channel to denote transparency) that's being used as a texture atlas (64x64 surfaces).

The two problems are as follows: Although a single sprite honors its transparency properly, when that sprite passes over another one, one of the quads overwrites the other with a transparent rectangle (you can see the attached images: the first image is a frame with them overlapping, the second is after one has moved away slightly). I cannot for, for the life of my, get MSAA to cooperate. I've setup a triple Texture2D system to do an output->ResolveSubresource->output_msaa->CopyResource->final_output, and it renders, it's just still aliased.

Here is the code for the device, texture, and sampler state:

//Errors are checked in other places and the debug layer is showing no warnings

//Render Target Texture
D3D11_TEXTURE2D_DESC texd;
ZeroMemory(&texd, sizeof(texd));
texd.Width = config.width;
texd.Height = config.height;
texd.ArraySize = 1;
texd.SampleDesc.Count = 4;
texd.SampleDesc.Quality = D3D11_CENTER_MULTISAMPLE_PATTERN;
texd.MipLevels = 1;
texd.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texd.BindFlags = D3D11_BIND_RENDER_TARGET;
texd.Usage = D3D11_USAGE_DEFAULT;
hr = dev->CreateTexture2D(&texd, NULL, &output_texture);

//Sampler State
D3D11_SAMPLER_DESC samplerdesc;
ZeroMemory(&samplerdesc, sizeof(samplerdesc));
samplerdesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerdesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerdesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerdesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
samplerdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerdesc.MaxLOD = D3D11_FLOAT32_MAX; 
hr = dev->CreateSamplerState(&samplerdesc, &samplerstate);

//MSAA Intermediary Texture
ZeroMemory(&texd, sizeof(texd));
texd.Height = config.height;
texd.Width = config.width;
texd.MipLevels = 1;
texd.ArraySize = 1;
texd.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texd.SampleDesc.Count = 1;
texd.SampleDesc.Quality = 0;
texd.Usage = D3D11_USAGE_DEFAULT;       
hr = dev->CreateTexture2D(&texd, NULL, &output_temp_msaa);

//Second Intermediary Texture
ZeroMemory(&texd, sizeof(texd));
texd.Height = config.height;
texd.Width = config.width;
texd.MipLevels = 1;
texd.ArraySize = 1;
texd.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texd.SampleDesc.Count = 1;
texd.SampleDesc.Quality = 0;
texd.Usage = D3D11_USAGE_STAGING;
texd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
hr = dev->CreateTexture2D(&texd, NULL, &output_temp);
The texture loading:
hr = D3DX11CreateShaderResourceViewFromFile(
        dev,
    L"Atlas.dds", 
    &rtd,
    NULL,
    &res_texture,
    NULL
);

//in the Render() function:
devcon->PSSetShaderResources(0, 1, &res_texture);
The blend state code:
D3D11_BLEND_DESC desc;
desc.AlphaToCoverageEnable = false;
desc.IndependentBlendEnable = false;
for (int i = 0; i < 8; i++)
{
    desc.RenderTarget[i].BlendEnable = true;
    desc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
    desc.RenderTarget[i].SrcBlend = D3D11_BLEND_SRC_ALPHA;
    desc.RenderTarget[i].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
    desc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ZERO;
    desc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO; 
    desc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
    desc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD; 
}       
hr = dev->CreateBlendState(&desc, &blendstate);

Here is the code that converts from output_texture to the output_temp texture for copying:

devcon->ResolveSubresource(
    output_temp_msaa,
    D3D11CalcSubresource(0, 0, 1),
    output_texture,
    D3D11CalcSubresource(0, 0, 1),
    DXGI_FORMAT_B8G8R8A8_UNORM
);
devcon->CopyResource(output_temp, output_temp_msaa);

This is then used as such:

devcon->Map(output_temp, 0, D3D11_MAP_READ, 0, &output_subresource);

and copied, bit by bit, to another location for drawing.

Here is the current pixel shader:

//These are properly being set, AFAIK.
Texture2D Texture;
SamplerState ss;

struct PS_INPUT {
    float4 p : SV_POSITION;
    float2 t : TEXCOORD;
    float opacity : OPACITY;
};


float4 PShader(PS_INPUT input) : SV_TARGET
{
    float4 color = Texture.Sample(ss, input.t); 
    color.a = input.opacity;        
    return color;
}

Finally, the images showing the transparent clipping are attached (the offending sprite is in the middle of the screen).

Thanks in advance everybody!

Normal Sprites Normal Sprites

Clipping Sprites Clipping Sprites

Update: The clipping issue was actually because of a miscommunication between our graphic artist and I. The texture was using black as its indication of transparent, instead of traditional alpha. Accounting for this (by changing pure black to float4(0,0,0,1) in the pixel shader) solved the clipping. The MSAA issue remains.

  • Do you have depth enabled when rendering the sprites? – MooseBoys Feb 26 '16 at 01:46
  • I've tried both with and without zbuffering (same effect, somehow). Would we want to have it on or off, completely? – Collin Biedenkapp Feb 26 '16 at 03:13
  • msaa only works on triangle edges, a translucent material without geometric edges will get no improvements from a msaa rendering. unless you use SV_SampleIndex in the pixel shader, but in that case, it is supersampling. Also, think about turning on msaa in the rasterizer desc or msaa would be off even if the surfaces are. – galop1n Mar 02 '16 at 03:03

0 Answers0