2017-05-06 3 views
0

私はゲーム用の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です。

ありがとうございます。

答えて

0

ブレンドして作業するには、まず完全に不透明なオブジェクトをすべてレンダリングし、次に透過性を持つすべてのオブジェクトを前から後ろの順にレンダリングする必要があります。つまり、透明なオブジェクトは、最初に遠いオブジェクトを含むカメラからの距離に基づいてソートされます。

不透明なオブジェクトは逆の方向(前後)にソートされるのが理想的です。そのため、不鮮明なピクセルは深度テストで破棄されます。

これは、通常、すべての描画要求をキューに入れることによって行われます。シーン内のすべてがキューに入ったら、透明度、距離、マテリアルなどのさまざまな要因に基づいてソートできます。キューをループして、すべての描画要求を適切な順序で作成できます。

単純なケースでは、不透明なオブジェクトが最初に描画され、透明なオブジェクトが一般的な前から後ろの順に描画されていることを確認してください。

+0

ちょうどそれを明確にするために、私は深度テストとアルファブレンディングを設定した方法に何も間違っていませんか? –

+0

彼らは私によく見えます。 – megadan

+0

透明オブジェクトを最初にレンダリングすると、ブレンドするものは何もないので、不透明に見えます。また、z値を深度バッファに書き込みます。次に描画するオブジェクトが透明オブジェクトの背後にある場合、奥行きテストによってぼやけたピクセルは描画されません。これは、現在の奥行きバッファにあるものに近いz値のピクセルのみを許可します。 – megadan

関連する問題