DirectX9 SDK Samples(20) HDRDemo Sample(3)
来源:互联网 发布:人人会计软件 编辑:程序博客网 时间:2024/06/05 23:02
HDR需要对源场景进行处理,因此在渲染初始源场景的时候,也要创建一个纹理,并且将场景渲染到这个纹理上,然后进行HDR处理。这个例子中,上述工作由HDRScene完成。关于渲染到纹理,这篇博文讲得很清楚:http://www.cnblogs.com/graphics/archive/2011/04/23/2024294.html
那么到此为止,我们明白了如何进行计算平均亮度,如何进行Bloom,如何渲染场景到纹理上。那么接下来我们就应该将这些东西组合起来,完成HDR的渲染。
让我们直接进入RenderScene函数:
if( SUCCEEDED( pd3dDevice->BeginScene() ) ) { // RENDER THE COMPLETE SCENE //-------------------------- // The first part of each frame is to actually render the "core" // resources - those that would be required for an HDR-based pipeline. // HDRScene creates an unprocessed, raw, image to work with. HDRScene::RenderScene( pd3dDevice ); // Luminance attempts to calculate what sort of tone/mapping should // be done as part of the post-processing step. Luminance::MeasureLuminance( pd3dDevice ); // The post-processing adds the blur to the bright (over-exposed) areas // of the image. PostProcess::PerformPostProcessing( pd3dDevice );上面三个简单的句子就是前面讲过的渲染场景到纹理、计算平均亮度和Bloom。
LPDIRECT3DSURFACE9 pFinalSurf = NULL; g_pFinalTexture->GetSurfaceLevel( 0, &pFinalSurf ); pd3dDevice->SetRenderTarget( 0, pFinalSurf ); LPDIRECT3DTEXTURE9 pHDRTex = NULL; HDRScene::GetOutputTexture( &pHDRTex ); LPDIRECT3DTEXTURE9 pLumTex = NULL; Luminance::GetLuminanceTexture( &pLumTex ); LPDIRECT3DTEXTURE9 pBloomTex = NULL; PostProcess::GetTexture( &pBloomTex ); pd3dDevice->SetTexture( 0, pHDRTex ); pd3dDevice->SetTexture( 1, pLumTex ); pd3dDevice->SetTexture( 2, pBloomTex ); pd3dDevice->SetPixelShader( g_pFinalPassPS ); D3DSURFACE_DESC d; pBloomTex->GetLevelDesc( 0, &d ); g_pFinalPassPSConsts->SetFloat( pd3dDevice, "g_rcp_bloom_tex_w", 1.0f / static_cast< float >( d.Width ) ); g_pFinalPassPSConsts->SetFloat( pd3dDevice, "g_rcp_bloom_tex_h", 1.0f / static_cast< float >( d.Height ) ); g_pFinalPassPSConsts->SetFloat( pd3dDevice, "fExposure", g_fExposure ); g_pFinalPassPSConsts->SetFloat( pd3dDevice, "fGaussianScalar", PostProcess::GetGaussianMultiplier() ); DrawHDRTextureToScreen();//省略 pd3dDevice->SetRenderTarget( 0, pLDRSurface );然后就是调用最后一个着色器完成合并工作。注意最后一句,将渲染目标还原为原来的LDR平面,其实也没用到。
前面没有看过FX文件,因为其实都比较简单。下面就看一下最后的这个PS完成了什么。
float4 main( in float2 t : TEXCOORD0 ) : COLOR0{ // Read the HDR value that was computed as part of the original scene float4 c = tex2D( original_scene, t ); // Read the luminance value, target the centre of the texture which will map to the only pixel in it! float4 l = tex2D( luminance, float2( 0.5f, 0.5f ) ); //也就是亮度平均值 // Compute the blur value using a bilinear filter float xWeight = frac( t.x / g_rcp_bloom_tex_w ) - 0.5; float xDir = xWeight; xWeight = abs( xWeight ); xDir /= xWeight; xDir *= g_rcp_bloom_tex_w; float yWeight = frac( t.y / g_rcp_bloom_tex_h ) - 0.5; float yDir = yWeight; yWeight = abs( yWeight ); yDir /= yWeight; yDir *= g_rcp_bloom_tex_h; // sample the blur texture for the 4 relevant pixels, weighted accordingly float4 b = ((1.0f - xWeight) * (1.0f - yWeight)) * tex2D( bloom, t ); b += (xWeight * (1.0f - yWeight)) * tex2D( bloom, t + float2( xDir, 0.0f ) ); b += (yWeight * (1.0f - xWeight)) * tex2D( bloom, t + float2( 0.0f, yDir ) ); b += (xWeight * yWeight) * tex2D( bloom, t + float2( xDir, yDir ) ); // Compute the actual colour: float4 final = c + 0.25f * b; // Reinhard's tone mapping equation (See Eqn#3 from // "Photographic Tone Reproduction for Digital Images" for more details) is: // // ( ( Lp )) // Lp * (1.0f +(---------)) // ( ((Lm * Lm))) // ------------------------- // 1.0f + Lp // // Lp is the luminance at the given point, this is computed using Eqn#2 from the above paper: // // exposure // Lp = -------- * HDRPixelIntensity // l.r // // The exposure ("key" in the above paper) can be used to adjust the overall "balance" of // the image. "l.r" is the average luminance across the scene, computed via the luminance // downsampling process. 'HDRPixelIntensity' is the measured brightness of the current pixel // being processed. float Lp = (fExposure / l.r) * max( final.r, max( final.g, final.b ) ); // A slight difference is that we have a bloom component in the final image - this is *added* to the // final result, therefore potentially increasing the maximum luminance across the whole image. // For a bright area of the display, this factor should be the integral of the bloom distribution // multipled by the maximum value. The integral of the gaussian distribution between [-1,+1] should // be AT MOST 1.0; but the sample code adds a scalar to the front of this, making it a good enough // approximation to the *real* integral. float LmSqr = (l.g + fGaussianScalar * l.g) * (l.g + fGaussianScalar * l.g); // Compute Eqn#3: float toneScalar = ( Lp * ( 1.0f + ( Lp / ( LmSqr ) ) ) ) / ( 1.0f + Lp ); // Tonemap the final outputted pixel: c = final * toneScalar; // Return the fully composed colour c.a = 1.0f; return c;}着色器完成了从纹理取值,并且根据公式计算像素颜色的工作。
DrawHDRTextureToScreen()完成的工作跟以前的同类函数类似,就是将纹理渲染到屏幕上。
到此为止,HDR渲染就差不多了。
- DirectX9 SDK Samples(20) HDRDemo Sample(3)
- DirectX9 SDK Samples(20) HDRDemo Sample(1)
- DirectX9 SDK Samples(20) HDRDemo Sample(2)
- DirectX9 SDK Samples(20) MeshFromObj Sample
- DirectX9 SDK Samples(7) EmptyProject Sample
- DirectX9 SDK Samples(8) BasicHLSL Sample(1)
- DirectX9 SDK Samples(8) BasicHLSL Sample(2)
- DirectX9 SDK Samples(9) Text3D Sample
- DirectX9 SDK Samples(10) HLSLwithoutEffects Sample
- DirectX9 SDK Samples(11) CompiledEffect Sample
- DirectX9 SDK Samples(12) CustomUI Sample
- DirectX9 SDK Samples(14) EffectParam Sample(1)
- DirectX9 SDK Samples(14) EffectParam Sample(2)
- DirectX9 SDK Samples(15) OptimizedMesh Sample
- DirectX9 SDK Samples(17) StateManager Sample
- DirectX9 SDK Samples(21) HDRCubeMap Sample
- DirectX9 SDK Samples(23) HDRFormats Sample
- DirectX9 SDK Samples(24) HDRLighting Sample
- 内核启动之启动内核——startup_32
- ZenCart按不同的国家及购买数量设置不同的运费
- 惦念一个人的句子
- JavaScript内置对象Math 产生随机整数
- html入门
- DirectX9 SDK Samples(20) HDRDemo Sample(3)
- 启动Java程序时JVM中的线程
- IO系统性能之一:衡量性能的几个指标
- ajax提交项目乱码问题 java web
- 玩的是一种成就感
- 多线程
- POJ1383
- Reactive Extensions (Rx) 入门(2) —— 安装 Reactive Extensions
- RVDS3.1破解