我在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;
}
最后,附加了显示透明剪辑的图像(违规精灵位于屏幕中间)。
先谢谢大家!
更新: 裁剪问题实际上是因为我们的图形艺术家和我之间的沟通错误。纹理使用黑色作为透明的指示,而不是传统的alpha。考虑到这一点(通过在像素着色器中将纯黑色更改为float4(0,0,0,1))解决了剪辑问题。 MSAA问题仍然存在。