add simple fog

This commit is contained in:
2026-04-06 19:06:04 +08:00
parent 1f4d7eff71
commit 3c64abd77e
16 changed files with 171 additions and 18 deletions

View File

@ -75,6 +75,9 @@ const float Epsilon = 0.00001;
const int LightCount = 1;
const vec3 Fdielectric = vec3(0.04);
layout(location = 0) out vec4 color;
layout(location = 1) out vec4 o_BloomColor;
struct DirectionalLight {
vec3 Direction;
vec3 Radiance;
@ -113,8 +116,6 @@ in VertexOutput
vec4 FragPosLightSpace;
} vs_Input;
layout(location = 0) out vec4 color;
layout(location = 1) out vec4 o_BloomColor;
uniform DirectionalLight u_DirectionalLights;
uniform vec3 u_CameraPosition;

View File

@ -61,6 +61,9 @@ const float Epsilon = 0.00001;
const int LightCount = 1;
const vec3 Fdielectric = vec3(0.04);
layout(location = 0) out vec4 color;
layout(location = 1) out vec4 o_BloomColor;
struct DirectionalLight {
vec3 Direction;
vec3 Radiance;
@ -100,9 +103,6 @@ in VertexOutput
vec4 FragPosLightSpace;
} vs_Input;
layout(location = 0) out vec4 color;
layout(location = 1) out vec4 o_BloomColor;
uniform DirectionalLight u_DirectionalLights;
uniform int u_PointLightCount;

View File

@ -22,8 +22,20 @@ layout(location = 1) out vec4 o_BloomTexture;
in vec2 v_TexCoord;
uniform sampler2DMS u_Texture;
uniform sampler2DMS u_DepthTexture;
uniform sampler2D u_BloomTexture;
uniform mat4 u_InvProjection;
uniform mat4 u_InvView;
// Fog
uniform float u_FogEnabled;
uniform vec3 u_FogColor;
uniform float u_FogDensity; // 雾密度,典型值 0.01~0.05
uniform float u_FogHeight; // 雾的起始高度(世界 Y 坐标),低于此高度雾最浓
uniform float u_FogHeightFalloff; // 高度衰减系数,值越大高度影响越剧烈(典型 0.5~2.0
uniform bool u_EnableAutoExposure;
uniform float u_ManualExposure;
@ -62,7 +74,7 @@ float MultiSampleDepth(sampler2DMS tex, vec2 tc)
ivec2 texCoord = ivec2(tc * texSize);
float result = 0.0;
for (int i = 0; i < u_TextureSamples; i++)
result += texelFetch(tex, texCoord, i).r;
result += texelFetch(tex, texCoord, i).r;
result /= float(u_TextureSamples);
return result;
}
@ -82,10 +94,14 @@ void main()
color += bloomColor;
}
float exposure = 1.0f;
if(u_EnableAutoExposure)
color *= u_Exposure;
exposure = u_Exposure;
else
color *= u_ManualExposure;
exposure = u_ManualExposure;
color *= exposure;
// Reinhard tonemapping operator.
// see: "Photographic Tone Reproduction for Digital Images", eq. 4
@ -95,6 +111,49 @@ void main()
// Scale color by ratio of average luminances.
vec3 mappedColor = (mappedLuminance / luminance) * color;
if (u_FogEnabled > 0.5)
{
// 1. 获取深度并重建视空间坐标
float depth = MultiSampleDepth(u_DepthTexture, v_TexCoord);
vec4 clipPos = vec4(v_TexCoord * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
vec4 viewPos4 = u_InvProjection * clipPos;
viewPos4 /= viewPos4.w;
vec3 viewPos = viewPos4.xyz; // 视空间坐标相机为原点Z 轴向内)
// 2. 距离雾因子(指数雾)
float distance = length(viewPos);
float distanceFactor = 1.0 - exp(-distance * u_FogDensity);
// 可选:指数平方雾(更平滑)
// float distanceFactor = 1.0 - exp(-pow(distance * u_FogDensity, 2.0));
// 3. 高度雾因子(基于世界 Y
// 将视空间坐标转换到世界空间
vec4 worldPos4 = u_InvView* vec4(viewPos, 1.0);
vec3 worldPos = worldPos4.xyz / worldPos4.w;
float worldY = worldPos.y;
float heightFactor = 0.0;
if (worldY < u_FogHeight)
{
// 低于起始高度:雾最浓,因子为 1
heightFactor = 1.0;
}
else
{
// 高于起始高度:指数衰减,高度越高雾越淡
float deltaY = worldY - u_FogHeight;
heightFactor = exp(-deltaY * u_FogHeightFalloff);
}
// 可选:使用 clamp 限制范围
heightFactor = clamp(heightFactor, 0.0, 1.0);
// 4. 综合雾因子(可相乘,也可取最大值,通常相乘)
float fogFactor = distanceFactor * heightFactor;
// 5. 混合雾颜色(雾颜色直接使用 u_FogColor已在 LDR 空间)
mappedColor = mix(mappedColor, u_FogColor, fogFactor);
}
// Gamma correction.
o_Color = vec4(pow(mappedColor, vec3(1.0 / gamma)), 1.0);