zoukankan      html  css  js  c++  java
  • Directx11教程(47) alpha blend(4)雾的实现

         除了用来实现透明效果之外,我们还可以用alpha blend来实现雾(fog)的效果。通过逐渐清晰的雾气效果,可以增加场景的真实感。

         雾的效果实现很简单,首先我们要一种颜色来表示雾,通常使用用灰色

         其实雾的效果和视点有很大关系,距离视点越近,雾就越淡,距离越远,雾就越浓。

         最终物体颜色是雾的颜色和计算出的pixel颜色的混合,我们使用的公式如下:

         Final Color = FogFactor * computed pixel color + (1.0 - FogFactor) * FogColor

         可以看出,最终的颜色是雾的颜色和计算的pixel颜色基于雾因子的加权平均。

    下面我看看如何计算雾因子:

         首先定义一个雾范围(fogstart, fogend),在这个范围内,雾逐渐由淡变浓,超出fogend后,就完全是雾的颜色了,再假定顶点到视点的距离为ViewDistance,则雾因子的计算公式有以下几种:

    1、线性因子

        Linear Fog = (FogEnd - ViewpointDistance) / (FogEnd - FogStart)

    2、指数因子

       Exponential Fog = exp2(-abs(ViewpointDistance * FogDensity))

    3、二次指数因子

        Exponential Fog 2 = exp2(- (ViewpointDistance * FogDensity) *(ViewpointDistance * FogDensity)) 

     

          下面我们在myTutorialD3D11_41的基础上来实现雾的效果:

    首先需要修改的是lighttex.vs和lighttex.ps, 在vs中,我们定义一个常量缓冲,表示fog的参数,然后根据这几个参数来计算雾因子,并把雾因子传递到ps阶段。

    lighttex.vs代码:

    cbuffer FogBuffer
    {
        float fogStart;
        float fogEnd;
        float fogDensity;
        float padding;
    };

        // 计算摄像机的位置.
        cameraPosition = mul(input.position, worldMatrix);
        cameraPosition = mul(cameraPosition, viewMatrix);

        // 计算线性雾.   
        output.fogFactor = saturate((fogEnd - cameraPosition.z) / (fogEnd - fogStart));

    lighttex.ps代码:

        // 混合雾颜色.
       finalcolor = input.fogFactor * finalcolor1 + (1.0 - input.fogFactor) * fogColor;

           另外在LightTexShaderClass中,也要做一些小改动,增加设置FogBuffer的代码,并在Render函数和 SetShaderParameters中,增加三个参数,用来设置fog。

          最后,在GraphicsClass中,定义四个参数,并把它们传入shader。

    float fogColor, fogStart, fogEnd, fogDensity;

    // 雾颜色.
    fogColor = 0.5f;

    // 雾距离.
    fogStart = 20.0f;
    fogEnd = 80.0f;

    fogDensity = 0.04f;

    首先用fogColor设置背景,这样很远的地方就是雾的颜色,…

    程序执行后,界面如下:

    image

    下面我们在vs中尝试修改雾因子的计算方法,看看指数因子和二次指数因子的效果。

    指数因子:

    fogDensity = 0.04f;

    // 计算指数因子.    
    output.fogFactor = saturate(exp2(-abs( cameraPosition.z *fogDensity)) );

    image

    二次指数因子:

    fogDensity = 0.02f;

    // 计算指数因子.
    output.fogFactor = saturate(exp2(- ( cameraPosition.z *fogDensity)*( cameraPosition.z *fogDensity)) );

    image

    完整的代码请参考:

    工程文件myTutorialD3D11_42

    代码下载:

    https://files.cnblogs.com/mikewolf2002/d3d1139-49.zip

    https://files.cnblogs.com/mikewolf2002/pictures.zip

  • 相关阅读:
    过往总结
    查找光标处的标识符
    【转】Linux 内核开发 Eclipse内核开发环境搭建
    【转】Writing linux kernel code in Eclipse
    【转】 Linux内核升级指南
    [转]Ubuntu 11.04 安装后要做的20件事情
    【转】vim 替换操作大全
    【转】移动硬盘安装ubuntu
    重置 Winsock 目录
    【转】让Firefox像vim一样操作
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2497120.html
Copyright © 2011-2022 走看看