From b9b184020f587f837152e10a8647c985d9526d25 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 14 Jan 2024 15:59:33 +0100 Subject: [PATCH] volumetric: support for volumetric fog added for terrain --- data/base/shaders/vk/pointlights.glsl | 44 +++++++++++++++++++ .../shaders/vk/terrain_combined_frag.glsl | 6 +-- .../shaders/vk/terrain_combined_high.frag | 11 ++++- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/data/base/shaders/vk/pointlights.glsl b/data/base/shaders/vk/pointlights.glsl index 8856b95f34b..87635f75b7c 100644 --- a/data/base/shaders/vk/pointlights.glsl +++ b/data/base/shaders/vk/pointlights.glsl @@ -74,6 +74,50 @@ vec4 iterateOverAllPointLights( return light; } +//volumetric +vec4 volumetricIterateOverAllPointLights( + vec2 clipSpaceCoord, + vec3 cameraPosition, + vec3 WorldFragPos +) { + vec3 result = vec3(0); + ivec2 bucket = ivec2(WZ_BUCKET_DIMENSION * clipSpaceCoord); + int bucketId = min(bucket.y + bucket.x * WZ_BUCKET_DIMENSION, WZ_BUCKET_DIMENSION * WZ_BUCKET_DIMENSION - 1); + + + vec3 viewLine = cameraPosition.xyz - WorldFragPos; + vec3 currentTransmittence = vec3(1); + vec3 transMittance = vec3(1); + + +#define STEPS 64 + for (int i = 0; i < STEPS; i++) + { + vec3 od = fogColor.xyz * length(viewLine / STEPS) / 10000; + vec3 posOnViewLine = WorldFragPos + viewLine * i / STEPS; + + + float sunLightEnergy = getShadowVisibility(posOnViewLine); + vec3 scatteredLight = vec3(sunLightEnergy) * od; + + for (int i = 0; i < bucketOffsetAndSize[bucketId].y; i++) + { + int entryInLightList = bucketOffsetAndSize[bucketId].x + i; + int lightIndex = PointLightsIndex[entryInLightList / 4][entryInLightList % 4]; + vec4 position = PointLightsPosition[lightIndex]; + vec4 colorAndEnergy = PointLightsColorAndEnergy[lightIndex]; + vec3 tmp = position.xyz * vec3(1., 1., -1.); + scatteredLight += colorAndEnergy.xyz * pointLightEnergyAtPosition(posOnViewLine, tmp, colorAndEnergy.w) * od; + } + + result += scatteredLight * currentTransmittence; + + currentTransmittence *= exp2(od); + transMittance *= exp2(-od); + } + return vec4(result * transMittance, transMittance); +} + vec3 toneMap(vec3 x) { return x; diff --git a/data/base/shaders/vk/terrain_combined_frag.glsl b/data/base/shaders/vk/terrain_combined_frag.glsl index 287a4ab6916..57d7eb0f389 100644 --- a/data/base/shaders/vk/terrain_combined_frag.glsl +++ b/data/base/shaders/vk/terrain_combined_frag.glsl @@ -6,7 +6,7 @@ float getShadowMapDepthComp(vec2 base_uv, float u, float v, vec2 shadowMapSizeIn return texture( shadowMap, vec4(uv, cascadeIndex, z) ); } -float getShadowVisibility() +float getShadowVisibility(vec3 fragPos) { if (WZ_SHADOW_MODE == 0 || WZ_SHADOW_FILTER_SIZE == 0) { @@ -17,7 +17,7 @@ float getShadowVisibility() { // Shadow Mapping - vec4 fragPosViewSpace = ViewMatrix * vec4(frag.fragPos, 1.0); + vec4 fragPosViewSpace = ViewMatrix * vec4(fragPos, 1.0); float depthValue = abs(fragPosViewSpace.z); int cascadeIndex = 0; @@ -51,7 +51,7 @@ float getShadowVisibility() } } - vec4 shadowPos = ShadowMapMVPMatrix[cascadeIndex] * vec4(frag.fragPos, 1.0); + vec4 shadowPos = ShadowMapMVPMatrix[cascadeIndex] * vec4(fragPos, 1.0); vec3 pos = shadowPos.xyz / shadowPos.w; if (pos.z > 1.0f) diff --git a/data/base/shaders/vk/terrain_combined_high.frag b/data/base/shaders/vk/terrain_combined_high.frag index b0fb656d8d5..fca0ac85354 100644 --- a/data/base/shaders/vk/terrain_combined_high.frag +++ b/data/base/shaders/vk/terrain_combined_high.frag @@ -66,7 +66,7 @@ vec3 blendAddEffectLighting(vec3 a, vec3 b) { vec4 doBumpMapping(BumpData b, vec3 lightDir, vec3 halfVec) { vec3 L = normalize(lightDir); vec3 H = normalize(halfVec); - float visibility = getShadowVisibility(); + float visibility = getShadowVisibility(frag.fragPos); MaterialInfo materialInfo; materialInfo.albedo = b.color; @@ -125,6 +125,12 @@ void main() { vec4 fragColor = main_bumpMapping(); +#if 1 + + vec2 clipSpaceCoord = gl_FragCoord.xy / vec2(viewportWidth, viewportHeight); + vec4 volumetric = volumetricIterateOverAllPointLights(clipSpaceCoord, cameraPos.xyz, frag.fragPos); + fragColor.xyz = toneMap(fragColor.xyz * volumetric.a + volumetric.xyz); +#else if (fogEnabled > 0) { // Calculate linear fog @@ -134,5 +140,6 @@ void main() // Return fragment color fragColor = mix(fragColor, vec4(fogColor.xyz, fragColor.w), fogFactor); } - FragColor = vec4(toneMap(fragColor.xyz), fragColor.w); +#endif + FragColor = fragColor; }