void FGLRenderer::UpdateShadowMap() { if (screen->mShadowMap.PerformUpdate()) { FGLDebug::PushGroup("ShadowMap"); FGLPostProcessState savedState; mBuffers->BindShadowMapFB(); mShadowMapShader->Bind(NOQUEUE); mShadowMapShader->Uniforms->ShadowmapQuality = gl_shadowmap_quality; mShadowMapShader->Uniforms.Set(); glViewport(0, 0, gl_shadowmap_quality, 1024); RenderScreenQuad(); const auto &viewport = screen->mScreenViewport; glViewport(viewport.left, viewport.top, viewport.width, viewport.height); mBuffers->BindShadowMapTexture(16); FGLDebug::PopGroup(); screen->mShadowMap.FinishUpdate(); } }
void VkPPRenderState::Draw() { auto fb = GetVulkanFrameBuffer(); auto pp = fb->GetPostprocess(); fb->GetRenderState()->EndRenderPass(); VkPPRenderPassKey key; key.BlendMode = BlendMode; key.InputTextures = Textures.Size(); key.Uniforms = Uniforms.Data.Size(); key.Shader = GetVkShader(Shader); key.SwapChain = (Output.Type == PPTextureType::SwapChain); key.ShadowMapBuffers = ShadowMapBuffers; if (Output.Type == PPTextureType::PPTexture) key.OutputFormat = GetVkTexture(Output.Texture)->Format; else if (Output.Type == PPTextureType::SwapChain) key.OutputFormat = GetVulkanFrameBuffer()->swapChain->swapChainFormat.format; else if (Output.Type == PPTextureType::ShadowMap) key.OutputFormat = VK_FORMAT_R32_SFLOAT; else key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT; if (Output.Type == PPTextureType::SceneColor) { key.StencilTest = 1; key.Samples = fb->GetBuffers()->GetSceneSamples(); } else { key.StencilTest = 0; key.Samples = VK_SAMPLE_COUNT_1_BIT; } auto &passSetup = pp->mRenderPassSetup[key]; if (!passSetup) passSetup.reset(new VkPPRenderPassSetup(key)); int framebufferWidth = 0, framebufferHeight = 0; VulkanDescriptorSet *input = GetInput(passSetup.get(), Textures, ShadowMapBuffers); VulkanFramebuffer *output = GetOutput(passSetup.get(), Output, key.StencilTest, framebufferWidth, framebufferHeight); RenderScreenQuad(passSetup.get(), input, output, framebufferWidth, framebufferHeight, Viewport.left, Viewport.top, Viewport.width, Viewport.height, Uniforms.Data.Data(), Uniforms.Data.Size(), key.StencilTest); // Advance to next PP texture if our output was sent there if (Output.Type == PPTextureType::NextPipelineTexture) { pp->mCurrentPipelineImage = (pp->mCurrentPipelineImage + 1) % VkRenderBuffers::NumPipelineImages; } }
/////////////////////////////////////////////////////////////////////////////// // // Render scene. // /////////////////////////////////////////////////////////////////////////////// void RenderScene() { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _gSceneFbo.GetFBO()); // Clear each rendering target first before drawing the scene. glUseProgram(_gClearRenderTargetShader); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); RenderScreenQuad(); // Now draw scene once destinations have been cleared. glUseProgram(_gSetRenderTargetShader); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); RenderScenePass(); // For BLUR the code need to do the following. // Use same or different FBO. // Our Display shader will become SSAO shader. // RenderSceneQuad().. using mostly the code below. // But using a HBLUR render target shader. // Now Again do RenderSceneQuad() this time with VBLUR shader. // Now draw the final image. // Draw to the back buffer using deferred shading. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _gSsaoFbo.GetFBO()); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glUseProgram(_gSsaoShader); glActiveTexture(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest1()); glUniform1i(_gSsaoNormals, 0); glActiveTexture(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, _gRandomSampler); glUniform1i(_gSsaoRandoms, 1); glActiveTexture(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest2()); glUniform1i(_gSsaoDepths, 2); glActiveTexture(GL_TEXTURE3_ARB); glBindTexture(GL_TEXTURE_2D, _gRandomSampler); glUniform2fARB(_gSsaoOffset, 1.0f / (float)WIDTH, 1.0f / (float)HEIGHT); RenderScreenQuad(); // Horizontal blur. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _gHorizontalBlurFbo.GetFBO()); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glUseProgram(_gHorizontalBlurShader); glActiveTexture(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, _gSsaoFbo.GetColorDest0()); glActiveTexture(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest1()); glActiveTexture(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest2()); glUniform1i(_gHorizontalBlurSceneSampler, 0); glUniform1i(_gHorizontalBlurSceneSamplerNormal, 1); glUniform1i(_gHorizontalBlurSceneSamplerDepth, 2); RenderScreenQuad(); // Vertical blur. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _gVerticalBlurFbo.GetFBO() ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glUseProgram( _gVerticalBlurShader ); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _gHorizontalBlurFbo.GetColorDest0()); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest1()); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest2()); glUniform1i( _gVerticalBlurSceneSampler, 0 ); glUniform1i( _gVerticalBlurSceneNormalSampler, 1 ); glUniform1i( _gVerticalBlurSceneDepthSampler, 2 ); RenderScreenQuad(); // Final stage. glUseProgram( _gRenderShader ); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glUniform2fARB(_gOffset, 1.0f / (float)WIDTH, 1.0f / (float)HEIGHT); glUniform3fARB(_gLight1Pos, 0.0f, 20.0f, 15.0f); glUniform4fARB(_gLight1AmbientColor, 0.4f, 0.4f, 0.4f, 1.0f); glUniform4fARB(_gLight1DiffuseColor, 0.6f, 0.6f, 0.6f, 1.0f); glUniform4fARB(_gLight1SpecularColor, 0.6f, 0.6f, 0.6f, 1.0f); glUniform3fARB(_gLight2Pos, 100.0f, 20.0f, 15.0f); glUniform4fARB(_gLight2AmbientColor, 0.2f, 0.2f, 0.2f, 1.0f); glUniform4fARB(_gLight2DiffuseColor, 0.1f, 0.1f, 0.1f, 1.0f); glUniform4fARB(_gLight2SpecularColor, 0.5f, 0.7f, 0.5f, 1.0f); glActiveTexture(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D, _gVerticalBlurFbo.GetColorDest0()); glUniform1i(_gAmbientOcclusion, 0); glActiveTexture(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest0()); glUniform1i(_gSceneColors, 1); glActiveTexture(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest1()); glUniform1i(_gSceneNormals, 2); glActiveTexture(GL_TEXTURE3_ARB); glBindTexture(GL_TEXTURE_2D, _gSceneFbo.GetColorDest2()); glUniform1i(_gSceneDepths, 2); RenderScreenQuad(); glutSwapBuffers(); glutPostRedisplay(); }
void TressFXRenderer::RenderHairShortcut(ID3D11DeviceContext* pd3dContext) { // Get original render target and depth stencil view ID3D11RenderTargetView* pRTV = NULL; ID3D11DepthStencilView* pDSV = NULL; pd3dContext->OMGetRenderTargets(1, &pRTV, &pDSV); ID3D11PixelShader* pPS = m_ShortCut.SetupDepthPass(pd3dContext, pRTV, pDSV); // DEPTH FILL if (m_hairParams.bAntialias) { if (m_hairParams.strandCopies > 1) { RenderHairGeometry(pd3dContext, m_pVSRenderHairAAStrandCopies, pPS, m_hairParams.density, false, m_hairParams.strandCopies); } else { RenderHairGeometry(pd3dContext, m_pVSRenderHairAA, pPS, m_hairParams.density, false, 1); } } else { if (m_hairParams.strandCopies > 1) { RenderHairGeometry(pd3dContext, m_pVSRenderHairStrandCopies, pPS, m_hairParams.density, false, m_hairParams.strandCopies); } else { RenderHairGeometry(pd3dContext, m_pVSRenderHair, pPS, m_hairParams.density, false, 1); } } // DEPTH RESOLVE pPS = m_ShortCut.SetupResolveDepth(pd3dContext, pRTV, pDSV); RenderScreenQuad(pd3dContext, m_pVSScreenQuad, pPS); // COLOR FILL pPS = m_ShortCut.SetupShadePass(pd3dContext, pRTV, pDSV); if (m_hairParams.bAntialias) { if (m_hairParams.strandCopies > 1) { RenderHairGeometry(pd3dContext, m_pVSRenderHairAAStrandCopies, pPS, m_hairParams.density, false, m_hairParams.strandCopies); } else { RenderHairGeometry(pd3dContext, m_pVSRenderHairAA, pPS, m_hairParams.density, false, 1); } } else { if (m_hairParams.strandCopies > 1) { RenderHairGeometry(pd3dContext, m_pVSRenderHairStrandCopies, pPS, m_hairParams.density, false, m_hairParams.strandCopies); } else { RenderHairGeometry(pd3dContext, m_pVSRenderHair, pPS, m_hairParams.density, false, 1); } } // COLOR RESOLVE pPS = m_ShortCut.SetupResolveColor(pd3dContext, pRTV, pDSV); RenderScreenQuad(pd3dContext, m_pVSScreenQuad, pPS); m_ShortCut.PostResolveColor(pd3dContext); pd3dContext->OMSetDepthStencilState(m_pDepthTestEnabledDSS, 0x00); pd3dContext->OMSetRenderTargets(1, &pRTV, pDSV); pd3dContext->OMSetBlendState(NULL, 0, 0xffffffff); AMD_SAFE_RELEASE(pRTV); AMD_SAFE_RELEASE(pDSV); }
//-------------------------------------------------------------------------------------- // // RenderHair // // Renders the hair in two passes. The first pass fills an A-buffer by rendering the // hair geometry into a per-pixel linked list which keeps all of the overlapping fragments. // The second pass renders a full screen quad (using a stencil mask set in the first pass // to avoid unnecessary pixels) which reads fragments from the per-pixel linked list // and blends the nearest k fragments (K-buffer) in back to front order. // //-------------------------------------------------------------------------------------- void TressFXRenderer::RenderHair(ID3D11DeviceContext* pd3dContext) { // Get original render target and depth stencil view ID3D11RenderTargetView* pRTV = NULL; ID3D11DepthStencilView* pDSV = NULL; pd3dContext->OMGetRenderTargets( 1, &pRTV, &pDSV ); // render hair const UINT dwClearDataMinusOne[1] = {0xFFFFFFFF}; pd3dContext->ClearUnorderedAccessViewUint(m_pHeadPPLL_UAV, dwClearDataMinusOne); // Clear stencil buffer to mask the rendering area // Keep depth buffer for correct depth and early z pd3dContext->ClearDepthStencilView(pDSV, D3D10_CLEAR_STENCIL, 1.0, 0); ID3D11UnorderedAccessView* pUAV[] = {m_pHeadPPLL_UAV, m_pPPLL_UAV, NULL, NULL, NULL, NULL, NULL}; UINT pUAVCounters[] = { 0, 0, 0, 0, 0, 0, 0 }; pd3dContext->OMSetRenderTargetsAndUnorderedAccessViews(1, &pRTV, pDSV, 1, 7, pUAV, pUAVCounters); // disable color write if there is no need for fragments counting pd3dContext->OMSetBlendState(m_pColorWritesOff, 0, 0xffffffff); // Enable depth test to use early z, disable depth write to make sure required layers won't be clipped out in early z pd3dContext->OMSetDepthStencilState(m_pDepthTestEnabledNoDepthWritesStencilWriteIncrementDSS, 0x00); // Pass 1: A-Buffer pass if (m_hairParams.bAntialias) { if (m_hairParams.strandCopies > 1) { RenderHairGeometry(pd3dContext, m_pVSRenderHairAAStrandCopies, m_pPSABuffer_Hair, m_hairParams.density, false, m_hairParams.strandCopies); } else { RenderHairGeometry(pd3dContext, m_pVSRenderHairAA, m_pPSABuffer_Hair, m_hairParams.density, false, 1); } } else { if (m_hairParams.strandCopies > 1) { RenderHairGeometry(pd3dContext, m_pVSRenderHairStrandCopies, m_pPSABuffer_Hair, m_hairParams.density, false, m_hairParams.strandCopies); } else { RenderHairGeometry(pd3dContext, m_pVSRenderHair, m_pPSABuffer_Hair, m_hairParams.density, false, 1); } } // Pass 2: K-Buffer pass pd3dContext->OMSetBlendState(m_pBlendStateBlendToBg, 0, 0xffffffff); pd3dContext->OMSetDepthStencilState(m_pDepthTestDisabledStencilTestLessDSS, 0x00); pUAV[0] = pUAV[1] = pUAV[2] = pUAV[3] = pUAV[4] = pUAV[5] = pUAV[6] = 0; pd3dContext->OMSetRenderTargetsAndUnorderedAccessViews(1, &pRTV, pDSV, 1, 7, pUAV, pUAVCounters); pd3dContext->PSSetShaderResources(IDSRV_HEAD_PPLL, 1, &m_pHeadPPLL_SRV); pd3dContext->PSSetShaderResources(IDSRV_PPLL, 1, &m_pPPLL_SRV); RenderScreenQuad(pd3dContext, m_pVSScreenQuad, m_pPSKBuffer_Hair); ID3D11ShaderResourceView* pNULL = NULL; pd3dContext->PSSetShaderResources(IDSRV_HEAD_PPLL, 1, &pNULL); pd3dContext->PSSetShaderResources(IDSRV_PPLL, 1, &pNULL); pd3dContext->OMSetDepthStencilState(m_pDepthTestEnabledDSS, 0x00); pd3dContext->OMSetRenderTargets(1, &pRTV, pDSV); pd3dContext->OMSetBlendState(NULL, 0, 0xffffffff); AMD_SAFE_RELEASE( pRTV ); AMD_SAFE_RELEASE( pDSV ); }