私はこれを Gamedev に投稿しましたが、それから数日経ちましたが、何の被害もありませんでした。私が見逃したものを誰かが知っているかどうかを見たかった.
通常、私はこれらを 2 つの質問として投稿しますが、それらが絡み合っていると感じています。要するに、透明な表面に表示するスプライトのデータを生成するパーティクル システムがあります。次にジオメトリ シェーダーに送信され (パス スルー頂点シェーダーを介して)、1 つの頂点をクワッドに押し出し、最後にピクセル シェーダーに送信されます (以下のコード)。
ピクセルの色は、テクスチャ アトラス (64x64 サーフェス) として使用されている 32 ビット DDS (透明度を示すためにアルファ チャネルを使用) からサンプリングされます。
2 つの問題は次のとおりです: 1 つのスプライトはその透明度を適切に尊重しますが、そのスプライトが別のスプライトを通過すると、四角形の 1 つが透明な四角形で他の四角形を上書きします (添付の画像を見ることができます: 最初の画像はそれらは重なっており、2 番目は 1 つが少し離れた後です)。私は一生、MSAAに協力してもらうことはできません. output->ResolveSubresource->output_msaa->CopyResource->final_output を実行するためにトリプル Texture2D システムをセットアップしましたが、レンダリングされますが、まだエイリアスが付けられています。
デバイス、テクスチャ、およびサンプラーの状態のコードは次のとおりです。
//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;
}
最後に、透明なクリッピングを示す画像が添付されます (問題のスプライトは画面の中央にあります)。
みなさん、よろしくお願いします!
更新: クリッピングの問題は、実際にはグラフィック アーティストと私との間の誤解が原因でした。テクスチャは、従来のアルファではなく、透明の指標として黒を使用していました。これを考慮して (ピクセル シェーダーで純粋な黒を float4(0,0,0,1) に変更することにより)、クリッピングを解決しました。MSAA の問題は残ります。