https://zhuanlan.zhihu.com/p/76627240
指数密度高度雾总共分为4个板块,完成了其中的两个板块


https://blog.csdn.net/netyeaxi/article/details/87437880

控制台设置

SceneRendering.cpp
FSceneRenderer::PostVisibilityFrameSetup
InitFogConstants();

Common.ush

// also see ConvertToDeviceZ()
// @param DeviceZ value that is stored in the depth buffer (Z/W)
// @return SceneDepth (linear in world units, W)
float ConvertFromDeviceZ(float DeviceZ)
{// Supports ortho and perspective, see CreateInvDeviceZToWorldZTransform()return DeviceZ * View.InvDeviceZToWorldZTransform[0] + View.InvDeviceZToWorldZTransform[1] + 1.0f / (DeviceZ * View.InvDeviceZToWorldZTransform[2] - View.InvDeviceZToWorldZTransform[3]);
}

shader中关于View相关的代码在:SceneView.cpp
L2424

ViewUniformShaderParameters.ScreenToTranslatedWorld = FMatrix(FPlane(1, 0, 0, 0),FPlane(0, 1, 0, 0),FPlane(0, 0, ProjectionMatrixUnadjustedForRHI.M[2][2], 1),FPlane(0, 0, ProjectionMatrixUnadjustedForRHI.M[3][2], 0))* InViewMatrices.GetInvTranslatedViewProjectionMatrix();

L2251

 // to bring NDC (-1..1, 1..-1) into 0..1 UV for BufferSize texturesconst FVector4 ScreenPositionScaleBias(EffectiveViewRect.Width() * InvBufferSizeX / +2.0f,EffectiveViewRect.Height() * InvBufferSizeY / (-2.0f * GProjectionSignY),(EffectiveViewRect.Height() / 2.0f + EffectiveViewRect.Min.Y) * InvBufferSizeY,(EffectiveViewRect.Width() / 2.0f + EffectiveViewRect.Min.X) * InvBufferSizeX);

RenderUtils.cpp
QuadVertex

 virtual void InitRHI() override{// create a static vertex bufferFRHIResourceCreateInfo CreateInfo;VertexBufferRHI = RHICreateVertexBuffer(sizeof(FVector2D) * 4, BUF_Static, CreateInfo);void* VoidPtr = RHILockVertexBuffer(VertexBufferRHI, 0, sizeof(FVector2D) * 4, RLM_WriteOnly);static const FVector2D Vertices[4] ={FVector2D(-1,-1),FVector2D(-1,+1),FVector2D(+1,-1),FVector2D(+1,+1),};FMemory::Memcpy(VoidPtr, Vertices, sizeof(FVector2D) * 4);RHIUnlockVertexBuffer(VertexBufferRHI);}
// FogStruct.ExponentialFogParameters: FogDensity * exp2(-FogHeightFalloff * (CameraWorldPosition.z - FogHeight)) in x, FogHeightFalloff in y, MaxWorldObserverHeight in z, StartDistance in w.
// FogStruct.ExponentialFogParameters2: FogDensitySecond * exp2(-FogHeightFalloffSecond * (CameraWorldPosition.z - FogHeightSecond)) in x, FogHeightFalloffSecond in y, FogDensitySecond in z, FogHeightSecond in w
// FogStruct.ExponentialFogParameters3: FogDensity in x, FogHeight in y, whether to use cubemap fog color in z, FogCutoffDistance in w.

//ExponentialFogParameters

y和雾高度衰减有关
z=65536+HeiFog的z
w=



y=雾高度
w=


w=1-雾最大不透明度


引擎版

复制版

shader

参数设置

// FogStruct.ExponentialFogParameters: FogDensity * exp2(-FogHeightFalloff * (CameraWorldPosition.z - FogHeight)) in x, FogHeightFalloff in y, MaxWorldObserverHeight in z, StartDistance in w.
// FogStruct.ExponentialFogParameters2: FogDensitySecond * exp2(-FogHeightFalloffSecond * (CameraWorldPosition.z - FogHeightSecond)) in x, FogHeightFalloffSecond in y, FogDensitySecond in z, FogHeightSecond in w
// FogStruct.ExponentialFogParameters3: FogDensity in x, FogHeight in y, whether to use cubemap fog color in z, FogCutoffDistance in w.
static const float3 MyFogColor = float3(0.528, 0.646, 1.0);
static const float FogHeightFalloff = 0.001;
//Why not 0 or 1 or 2 .when set FogHeightFalloff value to 2 in editor it set 0.002 actually??Why
//it becomes constance when value=0
static const float GlobalDensity = 0.0003;
//this value is used to control the global fog density//using a special starting distance to limit the inscattering to the distance
static const float DirectionalInscatteringStartDistance=10312;
static const float3 DirectionalInscatteringColor = float3(0.0, 2.594,0.615);
static const float3 InscatterinLightDirection = float3(0.506, 0.863, 0.00);
static const float DirectionalInscatteringStrenthFactor = 8.0;

雾密度计算+积分计算

float CalculateLineIntegralShared(float RayDirectionZ)
{//积分拟合函数//RayDirectionZ 人眼与物体的相对高度//雾效影响程度受到 物体高度的影响。越高的物体,到达人眼雾效消失的越严重,越低的物体,到达人眼以后,雾效会加强。float Falloff = max(-127.0f, FogHeightFalloff * RayDirectionZ); // if it's lower than -127.0, then exp2() goes crazy in OpenGL's GLSL.float LineIntegral = (1.0f - exp2(-Falloff)) / Falloff;float LineIntegralTaylor = log(2.0) - (0.5 * Pow2(log(2.0))) * Falloff; // Taylor expansion around 0//float FogDensity = GlobalDensity * exp2(-FogHeightFalloff * (CameraWorldPosition.z - FogHeight));//we set fogheight to 0//雾密度呈指数变化。//摄像机与雾的相对高度越大,这个密度值越小,且最小为0;相对高度越小,雾密度越大,最高为正无穷。//当摄像机的高度比雾高度小时,雾的密度始终大于1,且变化剧烈;反之,雾密度始终小于1, 且随着高度的增加,逐渐衰减为0//GlobalDensity ,高度雾全局密度,通过这个参数来控制整体的密度,人工干预修正曲线//FogHeightFalloff的引入,是为了缩小高度变化的程度,当衰减值为0时,变化程度缩小最大化,所有高度只有同一个密度值,当那个衰减值为2时,加强了高度对密度的影响程度。float FogDensity = GlobalDensity * exp2(-FogHeightFalloff * (View.WorldCameraOrigin.z-0.0));//abs(Falloff) > FLT_EPSILON2 avoid dvide zero//return RayOriginTerms * (abs(Falloff) > FLT_EPSILON2 ? LineIntegral : LineIntegralTaylor);//RayOriginTerms=FogDensity * exp2(-FogHeightFalloff * (CameraWorldPosition.z - FogHeight)) which is FogStruct.ExponentialFogParameters.xreturn FogDensity * (abs(Falloff) > FLT_EPSILON2 ? LineIntegral : LineIntegralTaylor);}

计算指数高度雾+DirectionalLightInscattering

half4 GetExponentialHeightFog(float3 WorldPositionRelativeToCamera, float ExcludeDistance)
{float3 CameraToReceiver = WorldPositionRelativeToCamera;//const float3 WorldObserverOrigin = View.WorldCameraOrigin.xyz;float CameraToReceiverLengthSqr = dot(CameraToReceiver, CameraToReceiver);float CameraToReceiverLengthInv = rsqrt(CameraToReceiverLengthSqr);float CameraToReceiverLength = CameraToReceiverLengthSqr * CameraToReceiverLengthInv;half3 CameraToReceiverNormalized = CameraToReceiver * CameraToReceiverLengthInv;float RayLength = CameraToReceiverLength;float RayDirectionZ = CameraToReceiver.z;float ExponentialHeightLineIntegralShared = CalculateLineIntegralShared(RayDirectionZ);//RayLength 加上距离的影响float ExponentialHeightLineIntegral = ExponentialHeightLineIntegralShared * RayLength;half MinFogOpacity = 0.0;//设置最小不透明度为0.0 观察低处的影响half ExpFogFactor = max(saturate(exp2(-ExponentialHeightLineIntegral)), 0.5);//Shader type 2:DirectionalLightInscattering--------------------------------------------------------------half3 DirectionalLightInscattering = DirectionalInscatteringColor * pow(saturate(dot(CameraToReceiverNormalized, InscatterinLightDirection)), DirectionalInscatteringStrenthFactor);//距离影响因子float DirExponentialHeightLineIntegral = ExponentialHeightLineIntegralShared * max(RayLength - DirectionalInscatteringStartDistance, 0.0f);// Calculate the amount of light that made it through the fog using the transmission equationhalf DirectionalInscatteringFogFactor = saturate(exp2(-DirExponentialHeightLineIntegral));// Final inscattering from the lighthalf3 DirectionalInscattering = DirectionalLightInscattering * (1 - DirectionalInscatteringFogFactor);//-----------------------------------------------------------------------------------------------------------half3 FogColor = (MyFogColor.xyz) * (1 - ExpFogFactor) + DirectionalInscattering;//return half4(0.0, 0.0, 0.0, 1.0);return half4(FogColor, ExpFogFactor);
}
void MainPS(in float2 UV: TEXCOORD0,in float3 ScreenVector : TEXCOORD1,in float4 Position : SV_POSITION,out float4 OutColor : SV_Target0
)
{float DeviceZ = Texture2DSampleLevel(SceneTexturesStruct.SceneDepthTexture, SceneTexturesStruct_SceneDepthTextureSampler, UV, 0).r;// @param DeviceZ value that is stored in the depth buffer (Z/W)// @return SceneDepth (linear in world units, W)float SceneDepth = ConvertFromDeviceZ(DeviceZ); // Fetch the depth buffer Z / W value, solve for Wbool bIsRendered = (DeviceZ != 0.0);float3 WorldPositionRelativeToCamera = ScreenVector.xyz * SceneDepth;//scale xyz ??float4 HeightFogInscatteringAndOpacity = CalculateHeightFog(WorldPositionRelativeToCamera);float LightShaftMask = Texture2DSample(OcclusionTexture, OcclusionSampler, UV).x;HeightFogInscatteringAndOpacity.xyz *= LightShaftMask;if (!bIsRendered){HeightFogInscatteringAndOpacity.rgb = 0;HeightFogInscatteringAndOpacity.a = 1;}OutColor = float4(HeightFogInscatteringAndOpacity.xyz, HeightFogInscatteringAndOpacity.w);//recompileshaders changed
}

【UE4】指数密度高度雾相关推荐

  1. UE4-(雾效)指数级高度雾

    指数高度雾在地图上较低位置处 密度较大,而在较高位置处 密度较小,其过渡十分平滑,随着海拔升高,也不会出现明显切换. 将指数级高度雾拖拽到场景中,它会影响整个场景,但是指数高度雾actor的位置会决定 ...

  2. 虚幻引擎图文笔记:使用指数级高度雾(Exponential Height Fog)实现体积光

    所谓 体积光(Volumetric Lighting) 是光线在充满灰尘等杂质的空间中传播,由于漫反射产生的,好像光线经过之处形成了"体积"的现象. 效果图 基础场景 体积光实现步 ...

  3. Unity Shader PostProcessing - 11 - Depth Fog/Height Fog - 雾效/深度雾效/高度雾/深度+高度雾

    文章目录 观察生活中的雾 Scenario 1 - Pure Depth Fog - 纯深度雾 提取有用信息 Scenario 2 - Height Fog - 带高度的雾 提取有用信息 Scenar ...

  4. GIS融合之路(五)给CesiumJS加上体积云(Volumetric Cloud)和高度雾(Height Fog)

    同样在这篇文章开始前重申一下,山海鲸并没有使用ThreeJS引擎.但由于ThreeJS引擎使用广泛,下文中直接用ThreeJS同CesiumJS的整合方案代替山海鲸中3D引擎和CesiumJS整合. ...

  5. Unity URP高度雾效果Shader

    实现原理 见这篇文章Unity Shader-深度相关知识总结与效果实现(LinearDepth,Reverse Z,世界坐标重建,软粒子,高度雾,运动模糊,扫描线效果)_puppet_master的 ...

  6. Shader之——高效率高度雾 云海

    在网上研究了好长一段时间的高度雾 ,大概的方法分两种,一种是屏幕特效,一种是区域的模拟,都是需要开启相机的深度图,对移动端来说效率还是有一定的影响的,最后都放弃了.用我的野路子方法实现了个物体上的高度 ...

  7. Unity Shader - Post Processing 15 - Height Fog (Plus) - 后效 高度雾 改进版 (Parallax)、模拟闪电在云层中SSS

    文章目录 环境 问题 Parallax 原理 GGB 效果 模拟闪电在云层中SSS 测试脚本 效果 GIF Project References 环境 Unity : 2018.2.11f1, 201 ...

  8. unity urp自定义后处理 雾效 深度雾,高度雾 简版

    1,c#代码 using System.Collections; using System.Collections.Generic; using UnityEngine;public static c ...

  9. android屏幕密度高度,Android获取常用辅助方法(获取屏幕高度、宽度、密度、通知栏高度、截图)...

    我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现.下面就分享一下Android中常用的一些辅助方法: 获取屏幕高度: /** * 获得屏幕高度 * @para ...

最新文章

  1. GPS 气压计高度测量
  2. P1552 [APIO2012]派遣
  3. python程序设计实践教程陈东_Python
  4. luogu P3244 [HNOI2015]落忆枫音
  5. Kaggle新赛:通过音频识别鸟类和青蛙物种
  6. mvc源码解读(10)-ParameterDescriptor方法Action方法的参数描述对象
  7. 随手记_论文读写策略
  8. 毕马威深度解读北京自贸试验区方案
  9. MySql常用SQL语句
  10. 智能小车——循迹、避障小车(附详细代码)
  11. 广告法违禁词替换工具_广告法违禁词、敏感词检测工具
  12. 图片放大后失真不清晰,怎么办?
  13. ionic4基础教程(案例和实战小demo)
  14. 网络工程师笔记--广域网和接入网
  15. html中如何访问ftp中的图片,CSS FTP上传网页图解教程
  16. mysql锁粒度是什么意思_mysql锁粒度是什么
  17. IntelliJ IDEA优化
  18. iPad国内降价!在内地开启教育优惠
  19. 解决ora-01861文字与格式字符串不匹配(转)
  20. 胡适:中国公学十八年级毕业赠言-不要抛弃学问

热门文章

  1. Android-Data Storage
  2. Your branch is behind ‘origin/index-recommend‘ by 1 commit, and can be fast-forwarded.
  3. 如何在网页标题栏中插入图片图标
  4. android 选择年月日历,Android_java万年历,获取该年月日历表,这篇文章应用java技术输入年份 - phpStudy...
  5. Linux操作系统-标准IO库(1)
  6. 解决安装mmdet报错- ERROR: Could not build wheels for pycocotools, which is required to install pyproject.t
  7. 苹果新手Mac OS X 使用笔记--------系统目录结构
  8. 启用Microsoft loopback Adapte
  9. Android 5.0 以上开机音乐实现
  10. 解除封印 可以写博客啦