| 1596 | } |
| 1597 | |
| 1598 | void Tr2PostProcessRenderer::RenderDepthOfField( const Tr2TextureAL& dest, Tr2GpuResourcePool& gpuResourcePool, Tr2RenderContext& renderContext, Tr2PPDepthOfFieldEffect* depthOfField, bool temporal, float upscalingAmount ) |
| 1599 | { |
| 1600 | GPU_REGION( renderContext, "DepthOfField" ); |
| 1601 | { |
| 1602 | renderContext.m_esm.ApplyStandardStates( Tr2EffectStateManager::RM_FULLSCREEN ); |
| 1603 | |
| 1604 | |
| 1605 | BlueSharedString shape = depthOfField->GetBokehShapeString(); |
| 1606 | { |
| 1607 | Tr2GpuResourcePool::Texture coc; |
| 1608 | |
| 1609 | auto cocSize = TextureSize2D( dest.GetDesc() ) * depthOfField->m_cocScale; |
| 1610 | m_depthOfFieldCoCShader->SetParameter( MEMOIZED_STRING( "FocalInfo" ), Vector4( depthOfField->m_focalDistance, depthOfField->m_focalLength, depthOfField->m_scale, 0.0 ) ); |
| 1611 | m_depthOfFieldCoCShader->SetOption( MEMOIZED_STRING( "COC_OUTPUT_CHANNEL_COUNT" ), depthOfField->m_foregroundBlurNeeded ? MEMOIZED_STRING( "COC_OUTPUT_CHANNEL_COUNT_2" ) : MEMOIZED_STRING( "COC_OUTPUT_CHANNEL_COUNT_1" ) ); |
| 1612 | |
| 1613 | if( !depthOfField->m_foregroundBlurNeeded ) |
| 1614 | { |
| 1615 | GPU_REGION( renderContext, "CoC" ); |
| 1616 | |
| 1617 | coc = gpuResourcePool.GetTempTexture( "CoC", cocSize, Tr2RenderContextEnum::PIXEL_FORMAT_R8_UNORM, RENDER_TARGET ); |
| 1618 | DrawInto( coc, Tr2LoadAction::DONT_CARE, m_depthOfFieldCoCShader, renderContext ); |
| 1619 | } |
| 1620 | else |
| 1621 | { |
| 1622 | GPU_REGION( renderContext, "CoC" ); |
| 1623 | auto coc2 = gpuResourcePool.GetTempTexture( "CoC", cocSize, Tr2RenderContextEnum::PIXEL_FORMAT_R8G8_UNORM, RENDER_TARGET ); |
| 1624 | |
| 1625 | DrawInto( coc2, Tr2LoadAction::DONT_CARE, m_depthOfFieldCoCShader, renderContext ); |
| 1626 | { |
| 1627 | GPU_REGION( renderContext, "CoC Blur" ); |
| 1628 | |
| 1629 | auto blurContext = PostProcessBlur::CreateBlurContext( PostProcessBlur::BT_Big, |
| 1630 | PostProcessBlur::BC_r, |
| 1631 | PostProcessBlur::BP_Maximum, |
| 1632 | PostProcessBlur::BF_MaxOfAllChannels ); |
| 1633 | coc = Blur( coc2, gpuResourcePool, renderContext, blurContext ); |
| 1634 | } |
| 1635 | } |
| 1636 | |
| 1637 | float adjustedScale = depthOfField->m_scale / upscalingAmount; |
| 1638 | |
| 1639 | auto blur = gpuResourcePool.GetTempTexture( "Bokeh Blend", dest.GetWidth(), dest.GetHeight(), dest.GetFormat(), RENDER_TARGET ); |
| 1640 | |
| 1641 | if( depthOfField->m_useTAAFriendlyBokeh ) |
| 1642 | { |
| 1643 | |
| 1644 | float GOLDEN_ANGLE = TRI_PI * ( 3.0f - sqrt( 5.0f ) ); |
| 1645 | float angle = 0; |
| 1646 | float samplesPerPixel = 2.0 / 5.0; |
| 1647 | |
| 1648 | if( temporal ) |
| 1649 | { |
| 1650 | //Vary between 4 different rotations, so that it has the same period as the TAA jitter |
| 1651 | //This allows it to detect some kinds of flickering and remove it. |
| 1652 | if( ( m_bokehFrameCounter & 1 ) != 0 ) |
| 1653 | angle += TRI_PI; |
| 1654 | if( ( m_bokehFrameCounter & 2 ) != 0 ) |
| 1655 | angle += 0.5f * GOLDEN_ANGLE; |
nothing calls this directly
no test coverage detected