//-------------------------------------------------------------------------------------- // Name: Downsample4x4Texture() // Desc: Scale down pSrcTexture by 1/4 x 1/4 and place the result in pDstTexture //-------------------------------------------------------------------------------------- VOID PostProcess::Downsample4x4Texture( LPDIRECT3DTEXTURE9 pSrcTexture, LPDIRECT3DTEXTURE9 pDstTexture ) { // Make sure that the required shaders and objects exist assert( m_pDownScale4x4PS ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); // Get the sample offsets used within the pixel shader XMVECTOR avSampleOffsets[MAX_SAMPLES]; GetSampleOffsets_DownScale4x4( SrcDesc.Width, SrcDesc.Height, avSampleOffsets ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShader( m_pDownScale4x4PS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // Draw a fullscreen quad DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
//-------------------------------------------------------------------------------------- // Name: SampleLuminance() // Desc: Measure the average log luminance in the scene. //-------------------------------------------------------------------------------------- VOID PostProcess::SampleLuminance( LPDIRECT3DTEXTURE9 pSrcTexture, BOOL bInitial, LPDIRECT3DTEXTURE9 pDstTexture ) { // Make sure that the required shaders and objects exist assert( m_pSampleLumInitialPS ); assert( m_pSampleLumFinalPS ); assert( pSrcTexture && pDstTexture ); XGTEXTURE_DESC SrcDesc; XGGetTextureDesc( pSrcTexture, 0, &SrcDesc ); // Create and set a render target PushRenderTarget( 0L, CreateRenderTarget( pDstTexture ) ); // Sample initial luminance if( bInitial ) { // Initialize the sample offsets for the initial luminance pass. XMVECTOR avSampleOffsets[MAX_SAMPLES]; GetSampleOffsets_DownScale3x3( SrcDesc.Width, SrcDesc.Height, avSampleOffsets ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShader( m_pSampleLumInitialPS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); } else // ( bIntial == FALSE ) { // Perform the final pass of the average luminance calculation. This pass // performs an exp() operation to return a single texel cooresponding to the // average luminance of the scene in m_pToneMapTexture. XMVECTOR avSampleOffsets[MAX_SAMPLES]; GetSampleOffsets_DownScale4x4( SrcDesc.Width, SrcDesc.Height, avSampleOffsets ); g_pd3dDevice->SetPixelShaderConstantF( PSCONST_avSampleOffsets, ( FLOAT* )avSampleOffsets, MAX_SAMPLES ); g_pd3dDevice->SetPixelShader( m_pSampleLumFinalPS ); g_pd3dDevice->SetTexture( 0, pSrcTexture ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); } // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(); g_pd3dDevice->Resolve( D3DRESOLVE_RENDERTARGET0, NULL, pDstTexture, NULL, 0, 0, NULL, 1.0f, 0L, NULL ); // Cleanup and return PopRenderTarget( 0L )->Release(); g_pd3dDevice->SetPixelShader( NULL ); }
void HDRLight::_scene_to_sceneScaled() { PDIRECT3DSURFACE9 pSurfScaledScene = NULL; g_pTexSceneScaled->GetSurfaceLevel( 0, &pSurfScaledScene ); g_HDREffect->SetTechnique("DownScale4x4"); RECT rectSrc; rectSrc.left = 0; rectSrc.top = 0; rectSrc.right = g_D3dpp.BackBufferWidth; rectSrc.bottom = g_D3dpp.BackBufferHeight; CoordRect coords; GetTextureCoords( g_pTexScene, &rectSrc, g_pTexSceneScaled, NULL, &coords ); D3DXVECTOR2 avSampleOffsets[MAX_SAMPLES]; GetSampleOffsets_DownScale4x4(g_D3dpp.BackBufferWidth,g_D3dpp.BackBufferHeight,avSampleOffsets); g_HDREffect->SetValue( "g_avSampleOffsets", avSampleOffsets, sizeof( avSampleOffsets ) ); g_pd3dDevice->SetRenderTarget( 0, pSurfScaledScene ); g_pd3dDevice->SetTexture( 0, g_pTexScene ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); UINT uiPassCount, uiPass; g_HDREffect->Begin( &uiPassCount, 0 ); for( uiPass = 0; uiPass < uiPassCount; uiPass++ ) { g_HDREffect->BeginPass( uiPass ); // Draw a fullscreen quad DrawFullScreenQuad(g_pd3dDevice, coords.fLeftU,coords.fTopV, coords.fRightU,coords.fBottomV); g_HDREffect->EndPass(); } g_HDREffect->End(); SAFE_RELEASE(pSurfScaledScene); }
void HDRLight::_measureLuminance() { UINT uiPassCount, uiPass; int i, x, y, index; D3DXVECTOR2 avSampleOffsets[MAX_SAMPLES]; DWORD dwCurTexture = NUM_TONEMAP_TEXTURES - 1; PDIRECT3DSURFACE9 apSurfToneMap[NUM_TONEMAP_TEXTURES] = {0}; // Retrieve the tonemap surfaces for( i = 0; i < NUM_TONEMAP_TEXTURES; i++ ) { g_apTexToneMap[i]->GetSurfaceLevel( 0, &apSurfToneMap[i] ); } D3DSURFACE_DESC desc; g_apTexToneMap[dwCurTexture]->GetLevelDesc( 0, &desc ); // Initialize the sample offsets for the initial luminance pass. float tU, tV; tU = 1.0f / ( 3.0f * desc.Width ); tV = 1.0f / ( 3.0f * desc.Height ); index = 0; for( x = -1; x <= 1; x++ ) { for( y = -1; y <= 1; y++ ) { avSampleOffsets[index].x = x * tU; avSampleOffsets[index].y = y * tV; index++; } } g_HDREffect->SetTechnique("SampleAvgLum"); g_HDREffect->SetValue( "g_avSampleOffsets", avSampleOffsets, sizeof( avSampleOffsets ) ); g_pd3dDevice->SetRenderTarget( 0, apSurfToneMap[dwCurTexture] ); g_pd3dDevice->SetTexture( 0, g_pTexSceneScaled ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_HDREffect->Begin( &uiPassCount, 0 ); for( uiPass = 0; uiPass < uiPassCount; uiPass++ ) { g_HDREffect->BeginPass( uiPass ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad( g_pd3dDevice,0.0f, 0.0f, 1.0f, 1.0f ); g_HDREffect->EndPass(); } g_HDREffect->End(); dwCurTexture--; while( dwCurTexture > 0 ) { g_apTexToneMap[dwCurTexture + 1]->GetLevelDesc( 0, &desc ); GetSampleOffsets_DownScale4x4( desc.Width, desc.Height, avSampleOffsets ); // Each of these passes continue to scale down the log of average // luminance texture created above, storing intermediate results in // g_apTexToneMap[1] through g_apTexToneMap[NUM_TONEMAP_TEXTURES-1]. g_HDREffect->SetTechnique( "ResampleAvgLum" ); g_HDREffect->SetValue( "g_avSampleOffsets", avSampleOffsets, sizeof( avSampleOffsets ) ); g_pd3dDevice->SetRenderTarget( 0, apSurfToneMap[dwCurTexture] ); g_pd3dDevice->SetTexture( 0, g_apTexToneMap[dwCurTexture + 1] ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_HDREffect->Begin( &uiPassCount, 0 ); for( uiPass = 0; uiPass < uiPassCount; uiPass++ ) { g_HDREffect->BeginPass( uiPass ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(g_pd3dDevice, 0.0f, 0.0f, 1.0f, 1.0f ); g_HDREffect->EndPass(); } g_HDREffect->End(); dwCurTexture--; } g_apTexToneMap[1]->GetLevelDesc( 0, &desc ); GetSampleOffsets_DownScale4x4( desc.Width, desc.Height, avSampleOffsets ); g_HDREffect->SetTechnique( "ResampleAvgLumExp" ); g_HDREffect->SetValue( "g_avSampleOffsets", avSampleOffsets, sizeof( avSampleOffsets ) ); g_pd3dDevice->SetRenderTarget( 0, apSurfToneMap[0] ); g_pd3dDevice->SetTexture( 0, g_apTexToneMap[1] ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); g_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); g_HDREffect->Begin( &uiPassCount, 0 ); for( uiPass = 0; uiPass < uiPassCount; uiPass++ ) { g_HDREffect->BeginPass( uiPass ); // Draw a fullscreen quad to sample the RT DrawFullScreenQuad(g_pd3dDevice, 0.0f, 0.0f, 1.0f, 1.0f ); g_HDREffect->EndPass(); } g_HDREffect->End(); for( i = 0; i < NUM_TONEMAP_TEXTURES; i++ ) { SAFE_RELEASE( apSurfToneMap[i] ); } }