私はゲーム用の3Dレンダラーを開発していましたが、これまでDrawIndexedを使用してテクスチャレスメッシュをすべてレンダリングしました。パフォーマンスを向上させるために、私はDrawIndexedInstancedに切り替えて、テクスチャリングされたメッシュが最初にレンダリングされるようにしました。これにより、アルファブレンディングやデプスチェックの設定に関する問題が明らかになりました。フォアグラウンドとバックグラウンドでDirect3D 11デプスステンシル/アルファブレンディングの問題
View through the top of the front-most textures (textured meshes rendered first)
The same view, slightly different angle (textureless meshes rendered first)
は、テクスチャ四角形メッシュの行であり、手前のものは部分的に透明メッシュを持っている:以下の画像は、問題が何であるかを説明しなければなりません。中間の行には、透明度が0.3fに設定されたテクスチャなしのメッシュがあります。テクスチャメッシュが最初にレンダリングされると、未テクスチャのメッシュが前景の透明メッシュによって覆い隠されます。しかし、最初にレンダリングされる非テクスチャメッシュの場合、透明度が0.3fの場合でも、それらの背後のテクスチャメッシュは完全に覆い隠されます。非テクスチャメッシュが他の未テクスチャメッシュを覆い隠す場合、アルファブレンディングはそのシナリオで正しく動作します。
私はラスタライザ状態、深度ステンシル状態と深さステンシルビュー設定場所です:
ID3D11Texture2D *pBackBuffer;
D3D11_TEXTURE2D_DESC backBufferDesc;
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
pBackBuffer->GetDesc(&backBufferDesc);
RELEASE_RESOURCE(pBackBuffer);
// creating a buffer for the depth stencil
D3D11_TEXTURE2D_DESC depthStencilBufferDesc;
ZeroMemory(&depthStencilBufferDesc, sizeof(D3D11_TEXTURE2D_DESC));
depthStencilBufferDesc.ArraySize = 1;
depthStencilBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilBufferDesc.CPUAccessFlags = 0; // No CPU access required.
depthStencilBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilBufferDesc.Width = backBufferDesc.Width;
depthStencilBufferDesc.Height = backBufferDesc.Height;
depthStencilBufferDesc.MipLevels = 1;
depthStencilBufferDesc.SampleDesc.Count = 4;
depthStencilBufferDesc.SampleDesc.Quality = 0;
depthStencilBufferDesc.Usage = D3D11_USAGE_DEFAULT;
m_device->CreateTexture2D(&depthStencilBufferDesc, NULL, &m_depthStencilBuffer);
// creating a depth stencil view
HRESULT hr = m_device->CreateDepthStencilView( m_depthStencilBuffer,
NULL,
&m_depthStencilView);
// setup depth stencil state.
D3D11_DEPTH_STENCIL_DESC depthStencilStateDesc;
ZeroMemory(&depthStencilStateDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));
depthStencilStateDesc.DepthEnable = TRUE;
depthStencilStateDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilStateDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilStateDesc.StencilEnable = FALSE;
hr = m_device->CreateDepthStencilState(&depthStencilStateDesc, &m_depthStencilState);
// setup rasterizer state.
D3D11_RASTERIZER_DESC rasterizerDesc;
ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC));
rasterizerDesc.AntialiasedLineEnable = FALSE;
rasterizerDesc.CullMode = D3D11_CULL_BACK;
rasterizerDesc.DepthBias = 0;
rasterizerDesc.DepthBiasClamp = 0.0f;
rasterizerDesc.DepthClipEnable = TRUE;
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.FrontCounterClockwise = FALSE;
rasterizerDesc.MultisampleEnable = FALSE;
rasterizerDesc.ScissorEnable = FALSE;
rasterizerDesc.SlopeScaledDepthBias = 0.0f;
// create the rasterizer state
hr = m_device->CreateRasterizerState(&rasterizerDesc, &m_RasterizerState);
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);
m_deviceContext->RSSetState(m_RasterizerState);
をそして、これは私がアルファブレンディングを有効場所です:
D3D11_BLEND_DESC blendDescription;
ZeroMemory(&blendDescription, sizeof(D3D11_BLEND_DESC));
blendDescription.RenderTarget[0].BlendEnable = TRUE;
blendDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blendDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blendDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
m_device->CreateBlendState(&blendDescription, &m_blendState);
m_deviceContext->OMSetBlendState(m_blendState, 0, 0xffffffff);
を私が与えていることを知っていますテクスチャレスメッシュの場合、白い完全に不透明なテクスチャが問題を解決しますが、深度テストが間違っていると思われます。
D3D11_CREATE_DEVICE_DEBUGフラグを使用してデバイスを作成しても、エラーや警告は表示されません。
Create関数によって返されるすべてのHRESULTはS_OKです。
ありがとうございます。
ちょうどそれを明確にするために、私は深度テストとアルファブレンディングを設定した方法に何も間違っていませんか? –
彼らは私によく見えます。 – megadan
透明オブジェクトを最初にレンダリングすると、ブレンドするものは何もないので、不透明に見えます。また、z値を深度バッファに書き込みます。次に描画するオブジェクトが透明オブジェクトの背後にある場合、奥行きテストによってぼやけたピクセルは描画されません。これは、現在の奥行きバッファにあるものに近いz値のピクセルのみを許可します。 – megadan