void App::RenderGBuffer(ID3D11DeviceContext* d3dDeviceContext, CDXUTSDKMesh& mesh_opaque, CDXUTSDKMesh& mesh_alpha, const CFirstPersonCamera* viewerCamera, const D3D11_VIEWPORT* viewport, const UIConstants* ui) { // Clear GBuffer // NOTE: We actually only need to clear the depth buffer here since we replace unwritten (i.e. far plane) samples // with the skybox. We use the depth buffer to reconstruct position and only in-frustum positions are shaded. // NOTE: Complementary Z buffer: clear to 0 (far)! d3dDeviceContext->ClearDepthStencilView(mDepthBuffer->GetDepthStencil(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0); d3dDeviceContext->IASetInputLayout(mMeshVertexLayout); d3dDeviceContext->VSSetConstantBuffers(0, 1, &mPerFrameConstants); d3dDeviceContext->VSSetShader(mGeometryVS->GetShader(), 0, 0); d3dDeviceContext->GSSetShader(0, 0, 0); d3dDeviceContext->RSSetViewports(1, viewport); d3dDeviceContext->PSSetConstantBuffers(0, 1, &mPerFrameConstants); d3dDeviceContext->PSSetSamplers(0, 1, &mDiffuseSampler); // Diffuse texture set per-material by DXUT mesh routines // Set up render GBuffer render targets d3dDeviceContext->OMSetDepthStencilState(mDepthState, 0); d3dDeviceContext->OMSetRenderTargets(static_cast<UINT>(mGBufferRTV.size()), &mGBufferRTV.front(), mDepthBuffer->GetDepthStencil()); d3dDeviceContext->OMSetBlendState(mGeometryBlendState, 0, 0xFFFFFFFF); // Render opaque geometry if (mesh_opaque.IsLoaded()) { d3dDeviceContext->RSSetState(mRasterizerState); d3dDeviceContext->PSSetShader(mGBufferPS->GetShader(), 0, 0); mesh_opaque.Render(d3dDeviceContext, 0); } // Render alpha tested geometry if (mesh_alpha.IsLoaded()) { d3dDeviceContext->RSSetState(mDoubleSidedRasterizerState); d3dDeviceContext->PSSetShader(mGBufferAlphaTestPS->GetShader(), 0, 0); mesh_alpha.Render(d3dDeviceContext, 0); } // Cleanup (aka make the runtime happy) d3dDeviceContext->OMSetRenderTargets(0, 0, 0); }
void App::Render(ID3D11DeviceContext* d3dDeviceContext, ID3D11RenderTargetView* backBuffer, CDXUTSDKMesh& mesh_opaque, CDXUTSDKMesh& mesh_alpha, ID3D11ShaderResourceView* skybox, const D3DXMATRIXA16& worldMatrix, const CFirstPersonCamera* viewerCamera, const D3D11_VIEWPORT* viewport, const UIConstants* ui) { D3DXMATRIXA16 cameraProj = *viewerCamera->GetProjMatrix(); D3DXMATRIXA16 cameraView = *viewerCamera->GetViewMatrix(); D3DXMATRIXA16 cameraViewInv; D3DXMatrixInverse(&cameraViewInv, 0, &cameraView); // Compute composite matrices D3DXMATRIXA16 cameraViewProj = cameraView * cameraProj; D3DXMATRIXA16 cameraWorldViewProj = worldMatrix * cameraViewProj; // Fill in frame constants { D3D11_MAPPED_SUBRESOURCE mappedResource; d3dDeviceContext->Map(mPerFrameConstants, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); PerFrameConstants* constants = static_cast<PerFrameConstants *>(mappedResource.pData); constants->mCameraWorldViewProj = cameraWorldViewProj; constants->mCameraWorldView = worldMatrix * cameraView; constants->mCameraViewProj = cameraViewProj; constants->mCameraProj = cameraProj; // NOTE: Complementary Z => swap near/far back constants->mCameraNearFar = D3DXVECTOR4(viewerCamera->GetFarClip(), viewerCamera->GetNearClip(), 0.0f, 0.0f); constants->mFramebufferDimensionsX = mGBufferWidth; constants->mFramebufferDimensionsY = mGBufferHeight; constants->mFramebufferDimensionsZ = 0; // Unused constants->mFramebufferDimensionsW = 0; // Unused constants->mUI = *ui; d3dDeviceContext->Unmap(mPerFrameConstants, 0); } // Geometry phase if (mesh_opaque.IsLoaded()) { mesh_opaque.ComputeInFrustumFlags(cameraWorldViewProj); } if (mesh_alpha.IsLoaded()) { mesh_alpha.ComputeInFrustumFlags(cameraWorldViewProj); } // Setup lights ID3D11ShaderResourceView *lightBufferSRV = SetupLights(d3dDeviceContext, cameraView); // Forward rendering takes a different path here if (ui->lightCullTechnique == CULL_FORWARD_NONE) { RenderForward(d3dDeviceContext, mesh_opaque, mesh_alpha, lightBufferSRV, viewerCamera, viewport, ui, false); } else if (ui->lightCullTechnique == CULL_FORWARD_PREZ_NONE) { RenderForward(d3dDeviceContext, mesh_opaque, mesh_alpha, lightBufferSRV, viewerCamera, viewport, ui, true); } else { RenderGBuffer(d3dDeviceContext, mesh_opaque, mesh_alpha, viewerCamera, viewport, ui); ComputeLighting(d3dDeviceContext, lightBufferSRV, viewport, ui); } // Render skybox and tonemap RenderSkyboxAndToneMap(d3dDeviceContext, backBuffer, skybox, mDepthBuffer->GetShaderResource(), viewport, ui); }