D3D11渲染到纹理透明度/ MSAA问题

时间:2016-02-26 01:26:46

标签: c++ textures transparency direct3d msaa

我在Gamedev上贴了这个,然而,这已经过了几天而且没有咬人。我想知道是否有人知道我错过了什么。

通常我会将这些问题发布为两个问题,但我感觉它们是交织在一起的。简而言之,我有一个粒子系统,可以为精灵生成数据,以显示在透明表面上。然后将其发送到几何着色器(通过顶点着色器)以将单个顶点拉伸到四边形中,然后最终到像素着色器(下面的代码)。

像素颜色从32位DDS(使用alpha通道表示透明度)中采样,用作纹理图集(64x64曲面)。

这两个问题如下: 虽然一个精灵正确地尊重它的透明度,当精灵经过另一个精灵时,其中一个四边形用透明矩形覆盖另一个(你可以看到附加的图像:第一个图像是一个框架,它们重叠,第二个图像是一个人稍微离开了)。 在我的生活中,我无法让MSAA合作。我已经设置了一个三重Texture2D系统来做输出 - > ResolveSubresource-> output_msaa-> CopyResource-> final_output,它渲染,它仍然是别名。

以下是设备,纹理和采样器状态的代码:

//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);

以下是从output_texture转换为output_temp纹理以进行复制的代码:

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);

然后将其用作:

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

并一点一点地复制到另一个绘图位置。

这是当前的像素着色器:

//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;
}

最后,附加了显示透明剪辑的图像(违规精灵位于屏幕中间)。

先谢谢大家!

普通精灵 Normal Sprites

剪切精灵 Clipping Sprites

更新: 裁剪问题实际上是因为我们的图形艺术家和我之间的沟通错误。纹理使用黑色作为透明的指示,而不是传统的alpha。考虑到这一点(通过在像素着色器中将纯黑色更改为float4(0,0,0,1))解决了剪辑问题。 MSAA问题仍然存在。

0 个答案:

没有答案