Jump to content
  • Advertisement
Sign in to follow this  
turbofandude

DX11 Render to Texture and MSAA/Layered Transparency

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

Hey guys,

 

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!

Edited by turbofandude

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!