首先的本节教程旨在实现雾的特效,程序结构跟SpecularMap那节教程差不多,如下所示:

第一,雾的简介和原理。

雾的实现能帮助游戏实现一种朦朦胧胧的感觉,并且由于视锥体的存在,有些靠近视锥体但是没在视锥体内的物体,进入视锥体后在视觉上有种非常突兀的感觉,如果能在远处附着上一些雾,可减弱物体突然进入视锥体的突兀感。
来看看雾的计算原型模型:
假设雾气因子为FogFactor,E点位摄像机的位置,P点位看到的点的位置,dis(P,E)为相机和看到的点之间的距离。
则存在三种雾模型:
(1)线性雾:线性雾 指的的以眼睛(Camera)和看那到的点之间的距离为计算,雾的强度是随距离的距离变换而呈现线性变换。

线性雾的计算公式

FogFactor=(FogEnd-dis(P,E))/(FogEnd-FogStart);

               其中FogEnd=FogStart+FogRange;
(2)指数雾: 线性雾 指的的 以眼睛(Camera)和看那到的点之间的距离为计算,雾的强度是随距离的距离变换而呈现指数变化

指数雾的计算公式

                  FogFator=1.0/2.71828power(dis(P,E)*FogDensity);
                其中FogDensity为雾的密度。
(3)指数平方雾:跟指数雾差不多

指数平方雾的计算公式

     FogFator=1.0/2.71828power((dis(P,E)*FogDensity)*(dis(P,E)*FogDensity));
                           其中FogDensity为雾的密度。
计算出雾气因子(FogFactor)之后,将计算场景颜色,假设场景物体的颜色为SceneColor,最终输出的颜色为color
           color=FogFactor*SceneColor+(1-FogFactor)*FogColor;
            其中FogColor为雾气的颜色

下面看看我的shader代码:
Texture2D ShaderTexture[3];  //纹理资源数组
SamplerState SampleType:register(s0);   //采样方式//VertexShader
cbuffer CBMatrix:register(b0)
{matrix World;matrix View;matrix Proj;matrix WorldInvTranpose;
};cbuffer CBLight:register(b1)
{float4 SpecularColor;float4 AmbientColor;float4 DiffuseColor;float3 LightDirection;float SpecularPow;
};cbuffer CBCamera:register(b2)
{float3 CameraPos;float Pad;
};cbuffer CBFog:register(b3)
{float FogStart;float FogEnd;float pad1;float pad2;
};struct VertexIn
{float3 Pos:POSITION;float2 Tex:TEXCOORD0;  //多重纹理可以用其它数字float3 Normal:NORMAL;float3 Tangent:TANGENT;float3 Binormal:BINORMAL;
};struct VertexOut
{float4 Pos:SV_POSITION;float3 Pos_W:POSITION;float2 Tex:TEXCOORD0;float3 Normal_W:NORMAL;float3 Tangent_W:TANGENT;float3 Binormal_W:BINORMAL;float3 LookDirection:NORMAL1;
};VertexOut VS(VertexIn ina)
{VertexOut outa;//变换坐标到齐次裁剪空间(CVV)outa.Pos = mul(float4(ina.Pos,1.0f), World);outa.Pos = mul(outa.Pos, View);outa.Pos = mul(outa.Pos, Proj);outa.Tex= ina.Tex;//将法线量由局部空间变换到世界空间,并进行规格化outa.Normal_W = mul(ina.Normal, (float3x3)WorldInvTranpose);outa.Normal_W = normalize(outa.Normal_W);//将切向量由局部空间变换到世界空间,并且进行规格化outa.Tangent_W = mul(ina.Tangent,(float3x3)World);outa.Tangent_W = normalize(outa.Tangent_W);//将切向量由局部空间变换到世界空间,并且进行规格化outa.Binormal_W = mul(ina.Binormal, (float3x3)World);outa.Binormal_W = normalize(outa.Binormal_W);//求出顶点在世界空间的位置float3 worldPos= (float3)mul(float4(ina.Pos, 1.0f), World);outa.Pos_W = worldPos;//计算出每个顶点到相机的单位向量,之后在光栅化阶段进行插值outa.LookDirection =CameraPos.xyz - worldPos.xyz;outa.LookDirection = normalize(outa.LookDirection);return outa;
}float4 PS(VertexOut outa) : SV_Target
{float4 BasePixel; float3 BumpNormal;  //隆起法向量float4 color;float DiffuseFactor;  //漫反射因子float SpecularFactor; //镜面反射因子float4 Specular; //镜面反射颜色float4 SpecularIntensity; //镜面强度float FogFactor;//增加漫反射光颜色color = AmbientColor;//求每个像素的纹理像素颜色BasePixel = ShaderTexture[0].Sample(SampleType, outa.Tex);//求每个像素的隆起法向量(切线空间)BumpNormal=(float3)ShaderTexture[1].Sample(SampleType, outa.Tex);BumpNormal = (2.0f*BumpNormal) - 1.0f;//-----求出TBN矩阵(已经和世界变换矩阵结合在一起)--------float3 N = outa.Normal_W;float3 T = outa.Tangent_W;float3 B = outa.Binormal_W;//将隆起法向量由切线空间变换到局部空间,再到世界空间,然后规格化//BumpNormal= mul(BumpNormal,float3x3(T,B,N));BumpNormal = N + BumpNormal.x*T + BumpNormal.y*B;BumpNormal = normalize(BumpNormal);//求出漫反射因子float3 InvLightDirection = -LightDirection;DiffuseFactor = saturate(dot(BumpNormal, InvLightDirection));color += DiffuseColor*DiffuseFactor;color = saturate(color);//乘以基础纹理颜色color = color*BasePixel;//如果漫射因子为正时,漫反射光和镜面才存在意义if (DiffuseFactor > 0){//求出入射光的反射向量,此时的法线量应该为法线贴图的法向量,别把参数位置搞反了float3 ReflectLightDir = normalize(reflect(LightDirection,BumpNormal));//float3 ReflectLightDir = normalize(2 * DiffuseFactor*BumpNormal - InvLightDirection);//求每个像素的镜面强度SpecularIntensity = ShaderTexture[2].Sample(SampleType, outa.Tex);//求出镜面反射因子SpecularFactor = pow(saturate(dot(outa.LookDirection, ReflectLightDir)), SpecularPow);//求出镜面颜色,为什么这里用不上SpecularColor??Specular = SpecularFactor  *SpecularIntensity;color = color + Specular;  //确实只有镜面光被计算 才加上}color = saturate(color);//求出相机到像素点的距离float EyeToPixelDistance = length(CameraPos - outa.Pos_W);//计算出线性雾气因子FogFactor = (FogEnd - EyeToPixelDistance) / (FogEnd - FogStart);//计算融合雾气后的颜色float4 FogColor = float4(0.5f, 0.5f, 0.5f, 1.0f);color = FogFactor*color + (1 - FogFactor)*FogColor;return color;
}
其中背后缓存清除为灰色背景(0.5f,0.5f,0.5f,1.0f);
//第一,清除缓存开始绘制场景,清除背后缓存为灰色,模拟雾的背景mD3D->BeginScene(0.5f, 0.5f, 0.5f, 1.0f);

我的程序运行图:

你看距离立方体我们近处部分看的比远处部分要清楚。不过最后得记得清楚背景为灰色,要不输出的效果不够模拟雾天气,
如图:背景颜色为黑色的
最后我的源代码链接如下:
点击打开链接

Directx11教程十五之Fog(雾)相关推荐

  1. 【STM32】HAL库 STM32CubeMX教程十五---FMC-SDRAM(二)

    前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 上一讲我们说了CubeMX配置SDRAM的一些基本配置,还有FMC跟SDRAM的讲解,这一讲我们 ...

  2. 【STM32】HAL库 STM32CubeMX教程十五---FMC-SDRAM(一)

    前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 本文 1首先讲解什么是FMC及SDRAM,W9825G6KH芯片原理,2基于CubeMx创建工程 ...

  3. 【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界 摄像机的实现

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 本系列文章由zhm ...

  4. 【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界:摄像机的实现...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhmxy555/article/details/8657656 作者:毛星云(浅墨) ...

  5. 【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界:摄像机的实现

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处.   文章链接: http://blog.csdn.net/zhmxy555/article/details/8657656 作者:毛星云( ...

  6. nCode:DesignLife案例教程十五

    nCode:DesignLife 案例十五--蠕变分析 15.1 案例文件 15.2 目标 15.3 设计问题 在本案例中,我们将使用DesignLife的Creep Engine和Hybrid Lo ...

  7. WebGL简易教程(十五):加载gltf模型

    文章目录 1. 概述 2. 实例 2.1. 数据 2.2. 程序 2.2.1. 文件读取 2.2.2. glTF格式解析 2.2.2.1. 场景节点 2.2.2.2. 网格 2.2.2.3. 缓冲,缓 ...

  8. twisted系列教程十五–测试twisted代码

    Introduction 在这个系列中我们也已经写了很多twisted 代码了,但目前为止我们忽略了一个很重要的事情-测试.你可能也一直在想我们怎样用一个同步的测试框架unitest来测试我们的异步的 ...

  9. [转]轻松掌握Ajax.net系列教程十五:使用AutoCompleteExtender

    本章介绍AutoCompleteExtender的使用方法.用过Google的朋友都会发现,当我们在搜索框输入关键字的时候,Google会自动列出相关关键字提示.那么用Ajax.net也能做到么?答案 ...

最新文章

  1. C# 窗体实例化一次
  2. 隐藏Nginx或Apache以及PHP的版本号的方法
  3. PE结构绑定导入实现
  4. L1为什么具有稀疏性
  5. Wpf控件ListBox使用实例2
  6. ASP.NET Core Kestrel部署HTTPS
  7. Codeforces Round #717 (Div. 2) D. Cut 倍增
  8. java9-1.类,抽象类,接口的综合小练习
  9. W3 Total Cache+Hacklog Remote Attachment Upyun
  10. 视频教程-学透JavaScript-JavaScript
  11. pi控制直流电机c语言,一种基于PI控制的直流电机调速控制系统及控制方法与流程...
  12. 图灵计算机模型意义,图灵机有什么意义_学习图灵机模型中遇到的问题 - 人工智能 - 电子发烧友网...
  13. Delphi Android 下的定时对话框
  14. 数据结构算法---八大排序
  15. 用C语言散列表实现电话薄
  16. 参加ACM比赛所需的基础知识(转)
  17. 《调色师手册:电影和视频调色专业技法(第2版)》——调色所需的其他硬件...
  18. 数据仓库(11)什么是大数据治理,数据治理的范围是哪些
  19. 温故而知新的知识蒸馏 Distilling Knowledge
  20. docker导入MySQL数据库

热门文章

  1. 计算机组成原理乘法器组成图,计算机组成原理阵列乘法器课程设计报告
  2. 计算机科学与技术 色盲限制,2021男生色盲学什么专业比较好 受限专业有哪些
  3. TypeError: “_vm.xxxxx is not a function“
  4. Vue中播放音频和语音合成
  5. 卷积、互相关、自相关
  6. 机器学习方法(六):随机森林Random Forest,bagging
  7. 从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---07. AOP功能实现以及讲解
  8. 腾讯QQ2009顶级技巧18条
  9. 企业上云之路-如何评估上云风险(读书笔记)
  10. 计算机网络基础(四)