Directx11教程十五之Fog(雾)
首先的本节教程旨在实现雾的特效,程序结构跟SpecularMap那节教程差不多,如下所示:
第一,雾的简介和原理。
![](/assets/blank.gif)
线性雾的计算公式
FogFactor=(FogEnd-dis(P,E))/(FogEnd-FogStart);
指数雾的计算公式
指数平方雾的计算公式
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;
}
//第一,清除缓存开始绘制场景,清除背后缓存为灰色,模拟雾的背景mD3D->BeginScene(0.5f, 0.5f, 0.5f, 1.0f);
我的程序运行图:
![](/assets/blank.gif)
![](/assets/blank.gif)
Directx11教程十五之Fog(雾)相关推荐
- 【STM32】HAL库 STM32CubeMX教程十五---FMC-SDRAM(二)
前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 上一讲我们说了CubeMX配置SDRAM的一些基本配置,还有FMC跟SDRAM的讲解,这一讲我们 ...
- 【STM32】HAL库 STM32CubeMX教程十五---FMC-SDRAM(一)
前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 本文 1首先讲解什么是FMC及SDRAM,W9825G6KH芯片原理,2基于CubeMx创建工程 ...
- 【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界 摄像机的实现
分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 本系列文章由zhm ...
- 【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界:摄像机的实现...
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhmxy555/article/details/8657656 作者:毛星云(浅墨) ...
- 【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界:摄像机的实现
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8657656 作者:毛星云( ...
- nCode:DesignLife案例教程十五
nCode:DesignLife 案例十五--蠕变分析 15.1 案例文件 15.2 目标 15.3 设计问题 在本案例中,我们将使用DesignLife的Creep Engine和Hybrid Lo ...
- 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. 缓冲,缓 ...
- twisted系列教程十五–测试twisted代码
Introduction 在这个系列中我们也已经写了很多twisted 代码了,但目前为止我们忽略了一个很重要的事情-测试.你可能也一直在想我们怎样用一个同步的测试框架unitest来测试我们的异步的 ...
- [转]轻松掌握Ajax.net系列教程十五:使用AutoCompleteExtender
本章介绍AutoCompleteExtender的使用方法.用过Google的朋友都会发现,当我们在搜索框输入关键字的时候,Google会自动列出相关关键字提示.那么用Ajax.net也能做到么?答案 ...
最新文章
- C# 窗体实例化一次
- 隐藏Nginx或Apache以及PHP的版本号的方法
- PE结构绑定导入实现
- L1为什么具有稀疏性
- Wpf控件ListBox使用实例2
- ASP.NET Core Kestrel部署HTTPS
- Codeforces Round #717 (Div. 2) D. Cut 倍增
- java9-1.类,抽象类,接口的综合小练习
- W3 Total Cache+Hacklog Remote Attachment Upyun
- 视频教程-学透JavaScript-JavaScript
- pi控制直流电机c语言,一种基于PI控制的直流电机调速控制系统及控制方法与流程...
- 图灵计算机模型意义,图灵机有什么意义_学习图灵机模型中遇到的问题 - 人工智能 - 电子发烧友网...
- Delphi Android 下的定时对话框
- 数据结构算法---八大排序
- 用C语言散列表实现电话薄
- 参加ACM比赛所需的基础知识(转)
- 《调色师手册:电影和视频调色专业技法(第2版)》——调色所需的其他硬件...
- 数据仓库(11)什么是大数据治理,数据治理的范围是哪些
- 温故而知新的知识蒸馏 Distilling Knowledge
- docker导入MySQL数据库
热门文章
- 计算机组成原理乘法器组成图,计算机组成原理阵列乘法器课程设计报告
- 计算机科学与技术 色盲限制,2021男生色盲学什么专业比较好 受限专业有哪些
- TypeError: “_vm.xxxxx is not a function“
- Vue中播放音频和语音合成
- 卷积、互相关、自相关
- 机器学习方法(六):随机森林Random Forest,bagging
- 从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---07. AOP功能实现以及讲解
- 腾讯QQ2009顶级技巧18条
- 企业上云之路-如何评估上云风险(读书笔记)
- 计算机网络基础(四)