Browse Source

Convert VolumetricFogAccumulation to HLSL

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
ec45869ea0

+ 3 - 4
AnKi/Renderer/VolumetricFog.cpp

@@ -33,10 +33,6 @@ Error VolumetricFog::init()
 		"ShaderBinaries/VolumetricFogAccumulation.ankiprogbin", m_prog));
 
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
-	variantInitInfo.addConstant("kVolumeSize", UVec3(m_volumeSize[0], m_volumeSize[1], m_volumeSize[2]));
-	variantInitInfo.addConstant("kZSplitCount", m_r->getZSplitCount());
-	variantInitInfo.addConstant("kFinalZSplit", m_finalZSplit);
-
 	const ShaderProgramResourceVariant* variant;
 	m_prog->getOrCreateVariant(variantInitInfo, variant);
 	m_grProg = variant->getProgram();
@@ -81,6 +77,9 @@ void VolumetricFog::populateRenderGraph(RenderingContext& ctx)
 		regs.m_fogAbsorptionCoeff = el.m_fog.m_absorptionCoeff;
 		regs.m_near = ctx.m_renderQueue->m_cameraNear;
 		regs.m_far = ctx.m_renderQueue->m_cameraFar;
+		regs.m_zSplitCountf = F32(m_r->getZSplitCount());
+		regs.m_volumeSize = UVec3(m_volumeSize);
+		regs.m_maxZSplitsToProcessf = F32(m_finalZSplit + 1);
 
 		cmdb->setPushConstants(&regs, sizeof(regs));
 

+ 4 - 1
AnKi/Shaders/Include/MiscRendererTypes.h

@@ -110,7 +110,10 @@ struct VolumetricFogUniforms
 	RF32 m_fogAbsorptionCoeff;
 	RF32 m_near;
 	RF32 m_far;
-	F32 m_padding;
+	F32 m_zSplitCountf;
+
+	UVec3 m_volumeSize;
+	F32 m_maxZSplitsToProcessf;
 };
 
 // Vol lighting

+ 29 - 38
AnKi/Shaders/VolumetricFogAccumulation.ankiprog

@@ -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;
 	}
 }