原文: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设置背景,这样很远的地方就是雾的颜色,…

程序执行后,界面如下:

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

指数因子:

fogDensity = 0.04f;

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

二次指数因子:

fogDensity = 0.02f;

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

完整的代码请参考:

工程文件myTutorialD3D11_42

代码下载:

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

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

Directx11教程(47) alpha blend(4)-雾的实现的更多相关文章

  1. Directx11教程(46) alpha blend(3)

    原文:Directx11教程(46) alpha blend(3)       现在我们尝试改变box的贴图,使用一张带alpha的dds文件wirefence.dds, 用directx textu ...

  2. Directx11教程(45) alpha blend(2)

    原文:Directx11教程(45) alpha blend(2)     在myTutorialD3D11_40中,我们在场景中再添加一个box,并把box放在水里,实现半透明的效果.如下图所示: ...

  3. Directx11教程(44) alpha blend(1)

    原文:Directx11教程(44) alpha blend(1)    我们知道,D3D11中按Frame来渲染物体,每个Frame中又可能包含若干个primitive,如下面的示意图所示:     ...

  4. Directx11教程(66) D3D11屏幕文本输出(1)

    原文:Directx11教程(66) D3D11屏幕文本输出(1)      在D3D10中,通过ID3DX10Font接口对象,我们可以方便的在屏幕上输出文字信息,一个DrawText函数就能解决所 ...

  5. Directx11教程(54) 简单的基于GS的billboard实现

    原文:Directx11教程(54) 简单的基于GS的billboard实现     本章我们用一个billboard的实现来学习D3D11中的GS.     在VS shader中,我们输入的是顶点 ...

  6. Directx11教程(49) stencil的应用-镜面反射

    原文:Directx11教程(49) stencil的应用-镜面反射      本教程中,我们利用stencil来实现一个镜面反射效果. 1.首先我们要在D3DClass中增加几个成员变量及函数. I ...

  7. Directx11教程(18) D3D11管线(7)

    原文:Directx11教程(18) D3D11管线(7) 光栅化阶段(RS)之后,将进入PS/OM阶段. 参考外文资料:http://fgiesen.wordpress.com/2011/07/01 ...

  8. Directx11教程(57) 环境映射

    原文:Directx11教程(57) 环境映射       建好skydome后,如果我们想让其中的某个物体,比如那个球体来映射出周围环境的蓝天白云(不包括自己附近的物体),该怎么做呢?此时可以把这个 ...

  9. Directx11教程(51) 简单的billboard

    原文:Directx11教程(51) 简单的billboard        billboard称作公告板,通常用一个quad(四边形)表示[有的billboard用两个正交的quad表示],它的特点 ...

随机推荐

  1. Django项目:CMDB(服务器硬件资产自动采集系统)--03--03CMDB信息安全API接口交互认证

    #settings.py """ Django settings for AutoCmdb project. Generated by 'django-admin sta ...

  2. springboot核心技术(三)-----web开发

    web开发 1.简介 使用SpringBoot: 1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运 ...

  3. ERROR:ORA-30076: 对析出来源无效的析出字段

    DEBUG:key: sql: select count(*) as col_0_0_ from jc_user cmsuser0_ where 1=1 and cmsuser0_.register_ ...

  4. XML 映射文件

    MyBatis 的真正强大在于它的映射语句,这是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% ...

  5. Echarts在Vue中的使用

    1.使用 cnpm 或 npm 安装 Echarts cnpm方式 cnpm install echarts -S 或者 npm方式 npm install echarts --save 2.在项目文 ...

  6. Redis源码解析:27集群(三)主从复制、故障转移

    一:主从复制 在集群中,为了保证集群的健壮性,通常设置一部分集群节点为主节点,另一部分集群节点为这些主节点的从节点.一般情况下,需要保证每个主节点至少有一个从节点. 集群初始化时,每个集群节点都是以独 ...

  7. ajax--表单带file数据提交报错Uncaught TypeError: Illegal invocation

    只要设置 contentType: false, //不设置内容类型 processData: false, //不处理数据 $("#btn").on("click&qu ...

  8. CSS3实现3D地球自转行星公转

    截图效果:实际效果是动态的:地球自西向东自转,行星绕着地球公转,轨道也会转动 HTML页面代码: <!DOCTYPE html> <html lang="en"& ...

  9. java实体类的属性名首字母不能大写,不然el表达式无法取值

    摘要:Java命名规范中,实体类属性名以小写字母开头,但并没有说不能以大写字母开头,然而事实告诉我,大写真不行 https://www.cnblogs.com/jnhs/p/10025757.html

  10. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥