소스 검색

Bug fixes

Panagiotis Christopoulos Charitos 7 년 전
부모
커밋
a4a91b13aa

+ 10 - 0
shaders/ClearTextureCompute.glslp

@@ -5,6 +5,8 @@
 
 // A slow compute program to clear an image with a contant color
 
+#pragma anki mutator IS_2D 0 1
+
 #pragma anki start comp
 #include <shaders/Common.glsl>
 
@@ -16,11 +18,19 @@ struct PushConsts
 };
 ANKI_PUSH_CONSTANTS(PushConsts, u_regs);
 
+#if IS_2D
 layout(ANKI_IMAGE_BINDING(0, 0)) uniform writeonly image2D u_img;
+#else
+layout(ANKI_IMAGE_BINDING(0, 0)) uniform writeonly image3D u_img;
+#endif
 
 void main()
 {
+#if IS_2D
 	imageStore(u_img, IVec2(gl_GlobalInvocationID.xy), u_regs.m_clearColor);
+#else
+	imageStore(u_img, IVec3(gl_GlobalInvocationID), u_regs.m_clearColor);
+#endif
 }
 
 #pragma anki end

+ 14 - 11
shaders/VolumetricLightingAccumulation.glslp

@@ -10,6 +10,7 @@
 #pragma anki input const UVec3 VOLUME_SIZE
 #pragma anki input const UVec3 CLUSTER_COUNT
 #pragma anki input const U32 FINAL_CLUSTER_Z
+#pragma anki input const UVec3 FRACTION
 #pragma anki input const UVec3 WORKGROUP_SIZE
 #pragma anki input const UVec3 NOISE_TEX_SIZE
 
@@ -17,7 +18,7 @@
 
 layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = WORKGROUP_SIZE.z) in;
 
-layout(ANKI_IMAGE_BINDING(0, 0)) writeonly uniform image3D out_volume;
+layout(ANKI_IMAGE_BINDING(0, 0), r11f_g11f_b10f) uniform image3D out_volume;
 layout(ANKI_TEX_BINDING(0, 0)) uniform sampler3D u_noiseTex;
 
 struct PushConsts
@@ -36,7 +37,6 @@ ANKI_PUSH_CONSTANTS(PushConsts, u_regs);
 #define LIGHT_COMMON_UNIS
 #include <shaders/ClusteredShadingCommon.glsl>
 
-const UVec3 FRACTION = UVec3(VOLUME_SIZE.xy / CLUSTER_COUNT.xy, VOLUME_SIZE.z / (FINAL_CLUSTER_Z + 1));
 Vec3 g_globalInvocationID = Vec3(gl_GlobalInvocationID);
 
 Vec3 readRand()
@@ -52,13 +52,12 @@ Vec3 randWPos()
 	Vec3 rand = readRand();
 
 	// Compute the cluster Z as float
-	F32 clusterK = g_globalInvocationID.z * (F32(FINAL_CLUSTER_Z + 1u) / F32(VOLUME_SIZE.z));
-	F32 clusterK_1 = (g_globalInvocationID.z + 1.0) * (F32(FINAL_CLUSTER_Z + 1u) / F32(VOLUME_SIZE.z));
+	F32 clusterKNear = g_globalInvocationID.z * (F32(FINAL_CLUSTER_Z + 1u) / F32(VOLUME_SIZE.z));
+	F32 clusterKFar = (g_globalInvocationID.z + 1.0) * (F32(FINAL_CLUSTER_Z + 1u) / F32(VOLUME_SIZE.z));
+	F32 clusterK = mix(clusterKNear, clusterKFar, rand.z);
 
 	// Get a Z value
-	F32 zVSpaceNear = computeClusterNearf(u_clustererMagic, clusterK);
-	F32 zVSpaceFar = computeClusterNearf(u_clustererMagic, clusterK_1);
-	F32 zVSpace = -mix(zVSpaceNear, zVSpaceFar, rand.z);
+	F32 zVSpace = -computeClusterNearf(u_clustererMagic, clusterK);
 
 	// Get a XY value
 	Vec2 uvMin = g_globalInvocationID.xy / Vec2(VOLUME_SIZE.xy);
@@ -143,16 +142,20 @@ void main()
 		return;
 	}
 
+	// Find the cluster
+	UVec3 clusterXYZ = gl_GlobalInvocationID / FRACTION;
+	U32 clusterIdx = clusterXYZ.z * (CLUSTER_COUNT.x * CLUSTER_COUNT.y) + clusterXYZ.y * CLUSTER_COUNT.x + clusterXYZ.x;
+
 	// Find a random pos inside the cluster
 	Vec3 worldPos = randWPos();
 
-	// Find the cluster
-	UVec3 clusterXYZ = gl_GlobalInvocationID / CLUSTER_COUNT;
-	U32 clusterIdx = clusterXYZ.z * (CLUSTER_COUNT.x * CLUSTER_COUNT.y) * clusterXYZ.y * CLUSTER_COUNT.x + clusterXYZ.x;
-
 	// Get lighting
 	Vec3 color = accumulateLights(clusterIdx, worldPos);
 
+	// Read the prev result
+	Vec3 prev = imageLoad(out_volume, IVec3(gl_GlobalInvocationID)).rgb;
+	color = mix(prev, color, 1.0 / 16.0);
+
 	// Write result
 	imageStore(out_volume, IVec3(gl_GlobalInvocationID), Vec4(color, 0.0));
 }

+ 2 - 1
src/anki/core/Config.cpp

@@ -20,7 +20,8 @@ Config::Config()
 	newOption("r.clusterSizeZ", 32);
 	newOption("r.avgObjectsPerCluster", 16);
 
-	newOption("r.volumetricLightingAccumulation.clusterFraction", 2);
+	newOption("r.volumetricLightingAccumulation.clusterFractionXY", 2);
+	newOption("r.volumetricLightingAccumulation.clusterFractionZ", 4);
 	newOption("r.volumetricLightingAccumulation.finalClusterInZ", 16);
 
 	newOption("r.shadowMapping.enabled", true);

+ 6 - 2
src/anki/renderer/Renderer.cpp

@@ -492,8 +492,11 @@ TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, cons
 				else
 				{
 					// Compute
+					ShaderProgramResourceMutationInitList<1> mutators(m_clearTexComputeProg);
+					mutators.add("IS_2D", U32((inf.m_type != TextureType::_3D) ? 1 : 0));
+
 					const ShaderProgramResourceVariant* variant;
-					m_clearTexComputeProg->getOrCreateVariant(variant);
+					m_clearTexComputeProg->getOrCreateVariant(mutators.get(), variant);
 
 					cmdb->bindShaderProgram(variant->getProgram());
 
@@ -505,7 +508,8 @@ TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, cons
 					cmdb->setTextureSurfaceBarrier(
 						tex, TextureUsageBit::NONE, TextureUsageBit::IMAGE_COMPUTE_WRITE, surf);
 
-					cmdb->dispatchCompute(tex->getWidth() >> mip, tex->getHeight() >> mip, 1);
+					const U wgSizeZ = (inf.m_type == TextureType::_3D) ? (tex->getDepth() >> mip) : 1;
+					cmdb->dispatchCompute(tex->getWidth() >> mip, tex->getHeight() >> mip, wgSizeZ);
 
 					if(!!inf.m_initialUsage)
 					{

+ 11 - 7
src/anki/renderer/VolumetricLightingAccumulation.cpp

@@ -24,14 +24,16 @@ VolumetricLightingAccumulation::~VolumetricLightingAccumulation()
 Error VolumetricLightingAccumulation::init(const ConfigSet& config)
 {
 	// Misc
-	const U fraction = config.getNumber("r.volumetricLightingAccumulation.clusterFraction");
-	ANKI_ASSERT(fraction >= 1);
+	const U fractionXY = config.getNumber("r.volumetricLightingAccumulation.clusterFractionXY");
+	ANKI_ASSERT(fractionXY >= 1);
+	const U fractionZ = config.getNumber("r.volumetricLightingAccumulation.clusterFractionZ");
+	ANKI_ASSERT(fractionZ >= 1);
 	const U finalClusterZ = config.getNumber("r.volumetricLightingAccumulation.finalClusterInZ");
 	ANKI_ASSERT(finalClusterZ > 0 && finalClusterZ < m_r->getClusterCount()[2]);
 
-	m_volumeSize[0] = m_r->getClusterCount()[0] * fraction;
-	m_volumeSize[1] = m_r->getClusterCount()[1] * fraction;
-	m_volumeSize[2] = (finalClusterZ + 1) * fraction;
+	m_volumeSize[0] = m_r->getClusterCount()[0] * fractionXY;
+	m_volumeSize[1] = m_r->getClusterCount()[1] * fractionXY;
+	m_volumeSize[2] = (finalClusterZ + 1) * fractionZ;
 	ANKI_R_LOGI("Initializing volumetric lighting accumulation. Size %ux%ux%u",
 		m_volumeSize[0],
 		m_volumeSize[1],
@@ -45,10 +47,11 @@ Error VolumetricLightingAccumulation::init(const ConfigSet& config)
 	ShaderProgramResourceMutationInitList<1> mutators(m_prog);
 	mutators.add("ENABLE_SHADOWS", 1);
 
-	ShaderProgramResourceConstantValueInitList<5> consts(m_prog);
+	ShaderProgramResourceConstantValueInitList<6> consts(m_prog);
 	consts.add("VOLUME_SIZE", UVec3(m_volumeSize[0], m_volumeSize[1], m_volumeSize[2]))
 		.add("CLUSTER_COUNT", UVec3(m_r->getClusterCount()[0], m_r->getClusterCount()[1], m_r->getClusterCount()[2]))
 		.add("FINAL_CLUSTER_Z", U32(finalClusterZ))
+		.add("FRACTION", UVec3(fractionXY, fractionXY, fractionZ))
 		.add("WORKGROUP_SIZE", UVec3(m_workgroupSize[0], m_workgroupSize[1], m_workgroupSize[2]))
 		.add("NOISE_TEX_SIZE", UVec3(m_noiseTex->getWidth(), m_noiseTex->getHeight(), m_noiseTex->getDepth()));
 
@@ -114,7 +117,8 @@ void VolumetricLightingAccumulation::run(RenderPassWorkContext& rgraphCtx)
 		Vec4 m_noiseOffsetPad3;
 	} regs;
 	regs.m_noiseOffsetPad3 = Vec4(0.0f);
-	regs.m_noiseOffsetPad3.x() = 1.0f / F32(m_r->getFrameCount() % m_noiseTex->getDepth()) * 0.5f;
+	const F32 texelSize = 1.0f / m_noiseTex->getDepth();
+	regs.m_noiseOffsetPad3.x() = texelSize * F32(m_r->getFrameCount() % m_noiseTex->getDepth()) + texelSize / 2.0f;
 
 	cmdb->setPushConstants(&regs, sizeof(regs));