DirectX9 SDK Samples(20) HDRDemo Sample(3)

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渲染就差不多了。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值