|
|
@@ -3,73 +3,64 @@
|
|
|
// Code licensed under the BSD License.
|
|
|
// http://www.anki3d.org/LICENSE
|
|
|
|
|
|
+#pragma anki hlsl
|
|
|
+
|
|
|
#pragma anki start comp
|
|
|
|
|
|
#include <AnKi/Shaders/Include/MiscRendererTypes.h>
|
|
|
-#include <AnKi/Shaders/Common.glsl>
|
|
|
-
|
|
|
-ANKI_SPECIALIZATION_CONSTANT_UVEC3(kVolumeSize, 0u);
|
|
|
-ANKI_SPECIALIZATION_CONSTANT_U32(kFinalZSplit, 3u);
|
|
|
-ANKI_SPECIALIZATION_CONSTANT_U32(kZSplitCount, 4u);
|
|
|
+#include <AnKi/Shaders/Common.hlsl>
|
|
|
|
|
|
-const UVec2 kWorkgroupSize = UVec2(8, 8);
|
|
|
-layout(local_size_x = kWorkgroupSize.x, local_size_y = kWorkgroupSize.y, local_size_z = 1) in;
|
|
|
+[[vk::binding(0)]] SamplerState g_linearAnyClampSampler;
|
|
|
+[[vk::binding(1)]] Texture3D<RVec4> g_lightVolume;
|
|
|
+[[vk::binding(2)]] RWTexture3D<RVec4> g_fogVolume;
|
|
|
|
|
|
-layout(set = 0, binding = 0) uniform sampler u_linearAnyClampSampler;
|
|
|
-layout(set = 0, binding = 1) uniform ANKI_RP texture3D u_lightVolume;
|
|
|
-layout(set = 0, binding = 2) writeonly uniform ANKI_RP image3D u_fogVolume;
|
|
|
-
|
|
|
-layout(push_constant, std140) uniform b_pc
|
|
|
-{
|
|
|
- VolumetricFogUniforms u_unis;
|
|
|
-};
|
|
|
+[[vk::push_constant]] ConstantBuffer<VolumetricFogUniforms> g_unis;
|
|
|
|
|
|
-void main()
|
|
|
+[numthreads(8, 8, 1)] void main(UVec3 svDispatchThreadId : SV_DISPATCHTHREADID)
|
|
|
{
|
|
|
- if(any(greaterThanEqual(gl_GlobalInvocationID.xy, kVolumeSize.xy)))
|
|
|
+ if(any(svDispatchThreadId.xy >= g_unis.m_volumeSize.xy))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- const Vec2 uv = (Vec2(gl_GlobalInvocationID.xy) + 0.5) / Vec2(kVolumeSize.xy);
|
|
|
+ const Vec2 uv = (Vec2(svDispatchThreadId.xy) + 0.5) / Vec2(g_unis.m_volumeSize.xy);
|
|
|
|
|
|
- ANKI_RP Vec4 colorAndDensityFront = Vec4(0.0);
|
|
|
- [[dont_unroll]] for(U32 i = 0u; i < kVolumeSize.z; ++i)
|
|
|
+ RVec4 colorAndDensityFront = 0.0;
|
|
|
+ [loop] for(U32 i = 0u; i < g_unis.m_volumeSize.z; ++i)
|
|
|
{
|
|
|
- const ANKI_RP F32 fi = F32(i);
|
|
|
+ const RF32 fi = F32(i);
|
|
|
|
|
|
// Compute the linear depth
|
|
|
- const ANKI_RP F32 maxLinearDepth = F32(kFinalZSplit + 1u) / F32(kZSplitCount);
|
|
|
- const ANKI_RP F32 linearDepthFraction = maxLinearDepth / F32(kVolumeSize.z);
|
|
|
- const ANKI_RP F32 linearDepthNear = fi * linearDepthFraction;
|
|
|
- const ANKI_RP F32 linearDepthFar = (fi + 1.0) * linearDepthFraction;
|
|
|
+ const RF32 maxLinearDepth = g_unis.m_maxZSplitsToProcessf / g_unis.m_zSplitCountf;
|
|
|
+ const RF32 linearDepthFraction = maxLinearDepth / F32(g_unis.m_volumeSize.z);
|
|
|
+ const RF32 linearDepthNear = fi * linearDepthFraction;
|
|
|
+ const RF32 linearDepthFar = (fi + 1.0) * linearDepthFraction;
|
|
|
|
|
|
// Compute the min and max Z in view space if this cluster fragment
|
|
|
- const ANKI_RP F32 zVSpaceNear = -linearDepthNear * (u_unis.m_far - u_unis.m_near) + u_unis.m_near;
|
|
|
- const ANKI_RP F32 zVSpaceFar = -linearDepthFar * (u_unis.m_far - u_unis.m_near) + u_unis.m_near;
|
|
|
+ const RF32 zVSpaceNear = -linearDepthNear * (g_unis.m_far - g_unis.m_near) + g_unis.m_near;
|
|
|
+ const RF32 zVSpaceFar = -linearDepthFar * (g_unis.m_far - g_unis.m_near) + g_unis.m_near;
|
|
|
|
|
|
// Compute the thikness of this fragment
|
|
|
- const ANKI_RP F32 layerThinkness = abs(zVSpaceNear - zVSpaceFar);
|
|
|
+ const RF32 layerThinkness = abs(zVSpaceNear - zVSpaceFar);
|
|
|
|
|
|
// Read the light value and the fog density from the fog volumes
|
|
|
- const ANKI_RP F32 w = (fi + 0.5) / F32(kVolumeSize.z);
|
|
|
- ANKI_RP Vec4 lightAndFogDensity = textureLod(u_lightVolume, u_linearAnyClampSampler, Vec3(uv, w), 0.0);
|
|
|
- lightAndFogDensity.xyz *= u_unis.m_fogDiffuse / kPi;
|
|
|
+ const RF32 w = (fi + 0.5) / F32(g_unis.m_volumeSize.z);
|
|
|
+ RVec4 lightAndFogDensity = g_lightVolume.SampleLevel(g_linearAnyClampSampler, Vec3(uv, w), 0.0);
|
|
|
+ lightAndFogDensity.xyz *= g_unis.m_fogDiffuse / kPi;
|
|
|
|
|
|
// Scattering & absorption
|
|
|
- const ANKI_RP F32 scattering = lightAndFogDensity.w * u_unis.m_fogScatteringCoeff * layerThinkness;
|
|
|
- const ANKI_RP F32 absorption = lightAndFogDensity.w * u_unis.m_fogAbsorptionCoeff * layerThinkness;
|
|
|
+ const RF32 scattering = lightAndFogDensity.w * g_unis.m_fogScatteringCoeff * layerThinkness;
|
|
|
+ const RF32 absorption = lightAndFogDensity.w * g_unis.m_fogAbsorptionCoeff * layerThinkness;
|
|
|
|
|
|
// Integrate
|
|
|
- const ANKI_RP Vec4 colorAndDensityBack = Vec4(lightAndFogDensity.xyz * scattering, scattering + absorption);
|
|
|
+ const RVec4 colorAndDensityBack = Vec4(lightAndFogDensity.xyz * scattering, scattering + absorption);
|
|
|
|
|
|
- const ANKI_RP Vec3 l =
|
|
|
- colorAndDensityFront.rgb + saturate(exp(-colorAndDensityFront.a)) * colorAndDensityBack.rgb;
|
|
|
+ const RVec3 l = colorAndDensityFront.rgb + saturate(exp(-colorAndDensityFront.a)) * colorAndDensityBack.rgb;
|
|
|
colorAndDensityFront = Vec4(l.rgb, colorAndDensityFront.a + colorAndDensityBack.a);
|
|
|
|
|
|
// Write the value
|
|
|
- const ANKI_RP Vec4 valToWrite = Vec4(colorAndDensityFront.rgb, saturate(exp(-colorAndDensityFront.a)));
|
|
|
- imageStore(u_fogVolume, IVec3(UVec3(gl_GlobalInvocationID.xy, i)), valToWrite);
|
|
|
+ const RVec4 valToWrite = Vec4(colorAndDensityFront.rgb, saturate(exp(-colorAndDensityFront.a)));
|
|
|
+ g_fogVolume[UVec3(svDispatchThreadId.xy, i)] = valToWrite;
|
|
|
}
|
|
|
}
|
|
|
|