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

  • 相关阅读:
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2497120.html
Copyright © 2011-2022 走看看