1+ #version 460
2+ #pragma PROGRAM_COMPUTE
3+ #include includes/ Lighting.glsl
4+ #include includes/ SharedVolumeFog.glsl
5+ #include includes/ SharedSceneGI.glsl
6+
7+ float Density(float3 pos)
8+ {
9+ float fog = pk_Volume_ConstantFog;
10+
11+ fog += clamp (exp (pk_Volume_HeightFogExponent * (- pos.y + pk_Volume_HeightFogOffset)) * pk_Volume_HeightFogAmount, 0.0 , 1e+ 3f);
12+
13+ float3 warp = pos;
14+
15+ fog *= NoiseScroll(warp, pk_Time.y * pk_Volume_WindSpeed, pk_Volume_NoiseFogScale, pk_Volume_WindDir.xyz, pk_Volume_NoiseFogAmount, - 0.3 , 8.0 );
16+
17+ return max (fog * pk_Volume_Density, 0 .0f);
18+ }
19+
20+ float3 GetAmbientColor(float3 position, float3 direction, float3 viewdir)
21+ {
22+ float anistropy = GetLightAnisotropy(viewdir, direction, pk_Volume_Anisotropy);
23+
24+ float4 scenegi = SampleGIVolumetric(position);
25+ float3 staticgi = SampleEnvironment(OctaUV(direction), 1 .0f) * anistropy;
26+ return staticgi * scenegi.a + scenegi.rgb;
27+ }
28+
29+ layout (local_size_x = 16 , local_size_y = 2 , local_size_z = 16 ) in ;
30+ void main()
31+ {
32+ uint3 id = gl_GlobalInvocationID;
33+ float2 uv = (VOLUME_SIZE_ST.zz + id.xy) * VOLUME_SIZE_ST.xy;
34+
35+ float zmax = VOLUME_LOAD_MAX_DEPTH(GetVolumeDepthTileIndex(uv));
36+
37+ // Triangle dither range is -1.5 - 1.5 and due to trilinear interpolation we also need to have 2 texels worth of coverage.
38+ float zmin = GetVolumeCellDepth(id.z - 3 .0f);
39+
40+ float3 bluenoise = GetVolumeCellNoise(id);
41+
42+ float depth = GetVolumeCellDepth(id.z + NoiseUniformToTriangle(bluenoise.x));
43+
44+ // Texel is inside dither & trilinear interpolation range. Let's clamp it so that we can avoid light leaking through thin surfaces.
45+ if (zmin < zmax)
46+ {
47+ depth = min (zmax, depth);
48+ }
49+
50+ depth = max (pk_ProjectionParams.x, depth);
51+
52+ float3 worldpos = mul(pk_MATRIX_I_V, float4(ClipToViewPos(uv, depth), 1 .0f)).xyz;
53+
54+ float3 viewdir = normalize (worldpos - pk_WorldSpaceCameraPos.xyz);
55+
56+ float3 color = GetAmbientColor(worldpos, normalize (bluenoise - 0 .5f + float3(0 , 1 , 0 )), viewdir);
57+
58+ LightTile tile = GetLightTile(GetTileIndexUV(uv, depth));
59+
60+ for (uint i = tile.start; i < tile.end; ++ i)
61+ {
62+ color += GetVolumeLightColor(i, worldpos, viewdir, tile.cascade, pk_Volume_Anisotropy);
63+ }
64+
65+ float density = Density(worldpos);
66+
67+ float4 preval = tex2D(pk_Volume_InjectRead, ReprojectWorldToCoord(worldpos));
68+ float4 curval = float4(pk_Volume_Intensity * density * color, density);
69+
70+ curval = lerp(preval, curval, VOLUME_ACCUMULATION);
71+ curval.a = VOLUME_MIN_DENSITY + curval.a;
72+
73+ imageStore(pk_Volume_Inject, int3(id), curval);
74+ }
0 commit comments