[shaderx5] 8 1 postprocessing effects in design

Post on 03-Jul-2015

753 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

8.1 Postprocessing Effects

in Design

http://ohyecloudy.com

http://cafe.naver.com/shader.cafe

2009.02.23

ShaderX5

Introduction

• 사용하는 Post-processing Effect가 증가.

– Color correction, depth-of-field, motion blur, night vision, HDR tone mapping…

• 확장이 쉽고 다양한 요구 사항에 유연하게 적응 가능한 framework를 제시.

The Goals

• Stability – 믿을 수 있고 일관된 결과.

• Robustness – 다른 시나리오와 이펙트에서 stability 보장.

• Extensibility – 이펙트 추가가 손쉬움.

• Performance – 가능한 최적, 효율적으로 동작.

• Flexibility – 풍부한 제어가 가능.

• Scalability – 지원하는 플랫폼에서 잠재적인 제한이 있더라도 잘 동작한다. – 예) 비디오 카드에 따라 다른 구성

The Design

Effect

Phase

Step

Step

Phase

구현이 필요한 파이프라인의 함수. 예) SetRenderTarget

Step의 그룹핑

HDR

Downsample scene texture

Set RenderTarget

Calculate luminance

Generate bright-pass

Bloom bright-pass

Tone-map and final composite

Draw Overlay

Set RenderTarget

Draw Overlay

Set RenderTarget

Draw Overlay

Set RenderTarget

Draw Overlay

Set RenderTarget

Draw Overlay

Set RenderTarget

Draw Overlay

Set RenderTarget

Draw Overlay

A Short Test Drive

<Effect Name="SepiaTone" Requirements="DX9“ Description="Output a Sepia-toned image."> <Phase Description=""> <Step Type="SetRenderTarget" Target="*CompositeOut" /> <Step Type="Overlay" ShaderTechnique="RenderSepiaTone"> <Texture Name="*CompositeIn" Alias="g_Texture"/> <Texture Name="Media/sepiatone.tga" Alias="g_DependantReadTexture" Type="File"/> <Param Name="Amout" Alias="g_fBlendAmout" Function="FadeIn"/> </Step> <Step Type="SetRenderTarget" Target="*Framebuffer"/> </Phase> </Effect>

A Short Test Drive

<Effect Name = "Output" Requirements = "DX9" Description = "Output the final results to the screen."> <Phase Description = ""> <Step Type = "SetRenderTarget" Target ="*Framebuffer" /> <Step Type = "Overlay" ShaderTechnique = "RenderScreenQuad"> <Texture Name = "*CompositeIn" Alias = "g_Texture" /> </Step> </Phase> </Effect>

Implementation Issue

A B

A

Night Vision

Sepia HDR Output

B B

B A

A

INPUT

OUTPUT

Disable Wrong!

Implementation Details

• Effect 활성 유무에 따라서 다음 Effect의 RenderTarget을 변경해주는 코드만 리뷰

– class CPostProcessTextureIoGroup

– void Enable( bool bEnable )

– void FixupTexturePointers()

– CRTTexture* FindRenderTarget( const char *strName )

class CPostProcessEffect { protected: // The list of effects phases. vector< CPostProcessEffectPhase * > m_Phases; // The list of user created render targets. vector< CRTTexture * > m_UserRenderTargets; // The effect file name. char *m_strFileName; // The effect name. char *m_strEffectName; // The next effect in the linked-list. CPostProcessEffect *m_pNext; // Whether this effect is enabled or not. bool m_bIsEnabled; // The current texture input/output group. CPostProcessTextureIoGroup *m_pCurIoGroup; // The original texture input/output group. CPostProcessTextureIoGroup m_OrigIoGroup; };

void CPostProcessEffect::Enable( bool bEnable ) // If we're disabling the effect. if ( !bEnable ) { CPostProcessEffect *pCurEffect = GetNext(); CPostProcessTextureIoGroup *pCurIoGroup = NULL; CPostProcessTextureIoGroup *pPrevIoGroup = GetCurIoGroup(); // For every active effect after this effect, // move the io groups forward to maintain // the proper texture io group mappings. for ( ; pCurEffect; pCurEffect = pCurEffect->GetNext() ) { if ( !pCurEffect->GetIsEnabled() ) { continue; } // Get the current io group. pCurIoGroup = pCurEffect->GetCurIoGroup(); // Set the current io group and fixup texture pointers. pCurEffect->SetCurIoGroup( pPrevIoGroup ); pCurEffect->FixupTexturePointers(); // Update the previous io group. pPrevIoGroup = pCurIoGroup; } }

void CPostProcessEffect::Enable( bool bEnable )

if ( bEnable ) { CPostProcessEffect *pCurEffect = CPostProcessEffectsSystem::m_pInstance->GetEffectsHead(); CPostProcessEffect *pNxtActiveEffectHead = pCurEffect; CPostProcessEffect *pNxtActiveEffect = NULL; // To enable the effect we need to traverse the entire effect list twice, // once moving forward through each original io groups, and second finding // the next active effect that we can give that io group to. for ( ; pCurEffect; pCurEffect = pCurEffect->GetNext() ) { // Where there are no more active effects we're done. if ( !pNxtActiveEffect ) { break; }

// Set the next active effects pNxtActiveEffect->SetCurIoGroup( (CPostProcessTextureIoGroup *)&pCurEffect->GetOrigIoGroup() ); pNxtActiveEffect->FixupTexturePointers(); } } // if ( bEnable )

// Fixup texture pointers. void CPPFXStep_Overlay::FixupTexturePointers() { if ( m_bIsLoadedFromFile ) return; CRTTexture *pRT = m_pParentStep->GetParentEffect()->FindRenderTarget( GetRefName() ); SetTexture( pRT ); }

// Fixup texture pointers. void CPPFXStep_SetRenderTarget::FixupTexturePointers() { CRTTexture *pRT = m_pParentEffect->FindRenderTarget( m_pRTRef->GetRefName() ); m_pRTRef->SetTexture( pRT ); }

CRTTexture *CPostProcessEffect::FindRenderTarget( const char *strName ) { if ( strcmp( strName, "*CompositeIn" ) == 0 ) { return m_pCurIoGroup->GetInput(); } else if ( strcmp( strName, "*CompositeOut" ) == 0 ) { return m_pCurIoGroup->GetOutput(); } vector< CRTTexture * >::iterator iterRT = m_UserRenderTargets.begin(); for ( ; iterRT != m_UserRenderTargets.end(); ++iterRT ) { if ( strcmp( (*iterRT)->GetName(), strName ) == 0 ) { return (*iterRT); } } return NULL; }

Conclusion

• Post processing effects는 텍스쳐를 바꾸어 가며 SetRenderTarget을 한다.

– 이 짓의 연속.

• 이 섹션에서 제시하는 Framework에서 확장성있고 변화에 유연한 Post processing effect 엔진 구현에 대한 힌트를 얻을 수 있다.

top related