雾效果设计文档
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.需求概述
1.1.天气效果
整个天气效果,除了雨雪之外,还应该包含大气、天空、雾
所有这些效果组合起来,才能形成一个接近实际的仿真效果。
雾
功能标识
功能名称雾
优先级
功能描述创建过程
点击创建雾按钮,可以在场景中增加一个雾对象,模拟起雾的效果。
雾对象类型
从雾范围来看,雾对象分为两种:一种为全局雾,一种为局部雾。
全局雾:在任何地方都有雾效果。
局部雾:绘制一个多边形,设置一个雾高度,那么,雾范围被限定在以
这个多边形为边界,沿地面到雾高度所形成的柱体里面。
雾对象参数
雾对象可设置的参数包括:
1 雾浓度
可理解为雾的密度
2 雾的颜色
雾颜色应该是从近到远有一个渐变的过程。
输入点击按钮
处理
输出雾效果显示
补充说明
2.实现原理
2.1.基础知识
现实世界对于雾的定义,雾是指在接近地球表面的大气中悬浮的由小水滴或冰晶组成的水汽凝结物,是一种常见的天气现象,雾能影响能见度。
在虚拟现实中一般雾的效果实现是比较简单的,所谓雾效,就是在远离我们视角的方向上,物体看起来像被蒙上了某种颜色(通常是灰色)。这种技术的实现实际上非常简单,就是根据物体距离摄像机的远近,来混合雾的颜色和物体本身的颜色即可。
在传统的固定管线的中,已经内置了雾的效果,模拟雾的浓度计算有三种算法:线性雾Linear,指数雾Exponential,二阶指数雾Exp2。
∙Linear:
,其中Dmax和Dmin分别表示受雾影响的距离起点和终点。
∙Exponential:
,其中d表示雾的浓度。
∙Exp2:
,其中d表示雾的浓度。
1 原始场景
2 线性雾效果
3 指数雾效果
4 二阶指数雾效果
UGlobe3.0版本中采用的就是固定管线方式实现的雾,由于固定管线方式实现的雾可定制性不好,因此在UGlobe3.0中雾的效果存在一些比较问题:
1、Globe的可视域和可视范围远远超过普通的场景,并且雾的最大浓度不可控制,雾效开启后很容易出现场景的全部都是雾颜色。
2、开启雾效后,远距离查看地球,应该一定程度的关闭雾效,3.0版本控制效果不太好。
3、体积雾(Volumn Fog)、深度雾等效果,固定管线方式无法实现。
对于目前我们的应用,因为大部分都是使用可编程脚本渲染,所以继续采用固定管线方式的雾方案不可行。为了能够更好的进行大范围和局部范围的雾效果模拟,我们才结合传统距离雾和深度雾的方式进行模拟。
2.2.体积雾效果及原理
为了表现我们将来的实现效果,下图是采用Unity的GlobeFog的实现的效果。
5 体积雾(Volumetric Fog)
6 传统基于距离的雾效果
7 深度雾+距离雾混合效果
8 近距离深度雾(现实中经常见到的情况,雾只出现在距离地表一段距离内)
在现实世界中,云雾效果
9 云雾效果(Volumetric clouds)
10 云雾效果
体积雾的实现原理:
1、假定在距离水平面高H的处,构建一个虚拟平面FogPlane(其中F为平面的法线,P点世界空间内的一点,H为雾的高度)。平面下的部分会存在雾的效果,平面上的部分不存在雾。
2、渲染场景对象(主要地形、模型)到深度纹理(DepthTexture),注意如果天空不需要雾效果是不用渲染到深度纹理(而且我们一般不不会渲染天空到深度纹理中)。
3、渲染所有场景对象到颜色纹理(ColorTexture)。在Ogre中可以使用Composite进行控制颜色纹理和深度纹理的渲染流程。
4、使用cg进行雾效果合成。
//计算目标点的雾效因子
float ComputeHalfSpace (float3 wsDir)
{
float3 wpos = _CameraWS + wsDir;
float FH = _HeightParams.x;
float3 C = _CameraWS;
float3 V = wsDir;
float3 P = wpos;
float3 aV = _HeightParams.w * V;
float FdotC = _HeightParams.y;
float k = _HeightParams.z;
float FdotP = P.y-FH;
float FdotV = wsDir.y;
float c1 = k * (FdotP + FdotC);
float c2 = (1-2*k) * FdotP;
float g = min(c2, 0.0);
g = -length(aV) * (c1 - g * g / abs(FdotV+1.0e-5f));
return g;
}
//从深度纹理计算像素点距离相机的深度值
float rawDepth =
SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth);
float dpth = Linear01Depth(rawDepth);
float4 wsDir = dpth * i.interpolatedRay;
float4 wsPos = _CameraWS + wsDir;
g += ComputeHalfSpace (wsDir);
// Compute fog amount