Browse Source

Finalize before testing

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
c2cd9c2ccf

+ 8 - 7
shaders/VolumetricFogAccumulation.glslp

@@ -55,16 +55,17 @@ void main()
 		// Compute the thikness of this fragment
 		// Compute the thikness of this fragment
 		F32 layerThinkness = abs(zVSpaceNear - zVSpaceFar);
 		F32 layerThinkness = abs(zVSpaceNear - zVSpaceFar);
 
 
-		// Scattering & absorption
-		F32 scattering = u_density * u_fogScatteringCoeff * layerThinkness;
-		F32 absorption = u_density * u_fogAbsorptionCoeff * layerThinkness;
+		// Read the light value and the fog density from the fog volumes
+		Vec4 lightAndFogDensity = textureLod(u_lightVolume, Vec3(uv, clusterKFar / F32(FINAL_CLUSTER_Z + 1u)), 0.0);
+		lightAndFogDensity.xyz *= u_fogDiffuse / PI;
+		lightAndFogDensity.w += u_density; // Apply the default density
 
 
-		// Read the light value
-		Vec3 light = textureLod(u_lightVolume, Vec3(uv, clusterKFar / F32(FINAL_CLUSTER_Z + 1u)), 0.0).rgb;
-		light *= u_fogDiffuse / PI;
+		// Scattering & absorption
+		F32 scattering = lightAndFogDensity.w * u_fogScatteringCoeff * layerThinkness;
+		F32 absorption = lightAndFogDensity.w * u_fogAbsorptionCoeff * layerThinkness;
 
 
 		// Integrate
 		// Integrate
-		Vec4 colorAndDensityBack = Vec4(light * scattering, scattering + absorption);
+		Vec4 colorAndDensityBack = Vec4(lightAndFogDensity.xyz * scattering, scattering + absorption);
 
 
 		Vec3 l = colorAndDensityFront.rgb + saturate(exp(-colorAndDensityFront.a)) * colorAndDensityBack.rgb;
 		Vec3 l = colorAndDensityFront.rgb + saturate(exp(-colorAndDensityFront.a)) * colorAndDensityBack.rgb;
 		colorAndDensityFront = Vec4(l.rgb, colorAndDensityFront.a + colorAndDensityBack.a);
 		colorAndDensityFront = Vec4(l.rgb, colorAndDensityFront.a + colorAndDensityBack.a);

+ 32 - 6
shaders/VolumetricLightingAccumulation.glslp

@@ -42,6 +42,7 @@ ANKI_PUSH_CONSTANTS(PushConsts, u_regs);
 #define LIGHT_LIGHTS
 #define LIGHT_LIGHTS
 #define LIGHT_COMMON_UNIS
 #define LIGHT_COMMON_UNIS
 #define LIGHT_INDIRECT
 #define LIGHT_INDIRECT
+#define LIGHT_FOG_DENSITY_VOLUMES
 #include <shaders/ClusteredShadingCommon.glsl>
 #include <shaders/ClusteredShadingCommon.glsl>
 
 
 Vec3 g_globalInvocationID = Vec3(gl_GlobalInvocationID);
 Vec3 g_globalInvocationID = Vec3(gl_GlobalInvocationID);
@@ -90,7 +91,7 @@ F32 phaseFunction(Vec3 viewDir, Vec3 lightDir, F32 g)
 	return saturate(a * b);
 	return saturate(a * b);
 }
 }
 
 
-Vec3 accumulateLights(U32 clusterIdx, Vec3 worldPos)
+Vec4 accumulateLightsAndFog(U32 clusterIdx, Vec3 worldPos)
 {
 {
 	Vec3 color = Vec3(0.0);
 	Vec3 color = Vec3(0.0);
 	Vec3 viewDir = normalize(u_cameraPos - worldPos);
 	Vec3 viewDir = normalize(u_cameraPos - worldPos);
@@ -169,7 +170,32 @@ Vec3 accumulateLights(U32 clusterIdx, Vec3 worldPos)
 	diffIndirect /= totalBlendWeight;
 	diffIndirect /= totalBlendWeight;
 	color += diffIndirect;
 	color += diffIndirect;
 
 
-	return color;
+	// Fog density
+	F32 fogDensity = 0.0;
+	idx = u_lightIndices[clusterIdx];
+	idx = u_lightIndices[idx - 1];
+	ANKI_LOOP while((idx = u_lightIndices[idxOffset++]) != MAX_U32)
+	{
+		FogDensityVolume vol = u_fogDensityVolumes[idx];
+
+		F32 factor;
+		ANKI_BRANCH if(vol.m_isBox != 0u)
+		{
+			factor =
+				computeProbeBlendWeight(worldPos, vol.m_aabbMinOrSphereCenter, vol.m_aabbMaxOrSphereRadiusSquared, 0.2);
+		}
+		else
+		{
+			Vec3 diff = worldPos - vol.m_aabbMinOrSphereCenter;
+			F32 distSq = dot(diff, diff) / vol.m_aabbMaxOrSphereRadiusSquared.x;
+			distSq = min(1.0, distSq);
+			factor = distSq * distSq;
+		}
+
+		fogDensity += vol.m_density * factor;
+	}
+
+	return Vec4(color, fogDensity);
 }
 }
 
 
 void main()
 void main()
@@ -187,7 +213,7 @@ void main()
 	Vec3 worldPos = worldPosInsideCluster(readRand());
 	Vec3 worldPos = worldPosInsideCluster(readRand());
 
 
 	// Get lighting
 	// Get lighting
-	Vec3 color = accumulateLights(clusterIdx, worldPos);
+	Vec4 lightAndFog = accumulateLightsAndFog(clusterIdx, worldPos);
 
 
 	// Read the prev result
 	// Read the prev result
 	{
 	{
@@ -206,15 +232,15 @@ void main()
 		Vec3 uvw = Vec3(prevUv, k);
 		Vec3 uvw = Vec3(prevUv, k);
 		if(all(lessThan(abs(uvw), Vec3(1.0))))
 		if(all(lessThan(abs(uvw), Vec3(1.0))))
 		{
 		{
-			Vec3 prev = textureLod(u_prevVolume, uvw, 0.0).rgb;
+			Vec4 prev = textureLod(u_prevVolume, uvw, 0.0);
 
 
 			// Modulate
 			// Modulate
-			color = mix(prev, color, 1.0 / 16.0);
+			lightAndFog = mix(prev, lightAndFog, 1.0 / 16.0);
 		}
 		}
 	}
 	}
 
 
 	// Write result
 	// Write result
-	imageStore(u_volume, IVec3(gl_GlobalInvocationID), Vec4(color, 0.0));
+	imageStore(u_volume, IVec3(gl_GlobalInvocationID), lightAndFog);
 }
 }
 
 
 #pragma anki end
 #pragma anki end

+ 2 - 2
shaders/glsl_cpp_common/ClusteredShading.h

@@ -69,8 +69,8 @@ struct FogDensityVolume
 {
 {
 	Vec3 m_aabbMinOrSphereCenter;
 	Vec3 m_aabbMinOrSphereCenter;
 	U32 m_isBox;
 	U32 m_isBox;
-	Vec3 m_aabbMaxOrSphereRadius;
-	U32 m_padding;
+	Vec3 m_aabbMaxOrSphereRadiusSquared;
+	F32 m_density;
 };
 };
 const U32 SIZEOF_FOG_DENSITY_VOLUME = 2 * SIZEOF_VEC4;
 const U32 SIZEOF_FOG_DENSITY_VOLUME = 2 * SIZEOF_VEC4;
 ANKI_SHADER_STATIC_ASSERT(sizeof(FogDensityVolume) == SIZEOF_FOG_DENSITY_VOLUME)
 ANKI_SHADER_STATIC_ASSERT(sizeof(FogDensityVolume) == SIZEOF_FOG_DENSITY_VOLUME)

+ 6 - 0
src/anki/collision/Sphere.h

@@ -49,9 +49,15 @@ public:
 
 
 	void setCenter(const Vec4& x)
 	void setCenter(const Vec4& x)
 	{
 	{
+		ANKI_ASSERT(x.w() == 0.0f);
 		m_center = x;
 		m_center = x;
 	}
 	}
 
 
+	void setCenter(const Vec3& x)
+	{
+		m_center = x.xyz0();
+	}
+
 	F32 getRadius() const
 	F32 getRadius() const
 	{
 	{
 		return m_radius;
 		return m_radius;

+ 1 - 1
src/anki/gr/Common.h

@@ -44,7 +44,7 @@ const U MAX_TEXTURE_LAYERS = 32;
 const U MAX_SPECIALIZED_CONSTS = 64;
 const U MAX_SPECIALIZED_CONSTS = 64;
 
 
 const U MAX_TEXTURE_BINDINGS = 16;
 const U MAX_TEXTURE_BINDINGS = 16;
-const U MAX_UNIFORM_BUFFER_BINDINGS = 4;
+const U MAX_UNIFORM_BUFFER_BINDINGS = 6;
 const U MAX_STORAGE_BUFFER_BINDINGS = 4;
 const U MAX_STORAGE_BUFFER_BINDINGS = 4;
 const U MAX_IMAGE_BINDINGS = 4;
 const U MAX_IMAGE_BINDINGS = 4;
 const U MAX_TEXTURE_BUFFER_BINDINGS = 4;
 const U MAX_TEXTURE_BUFFER_BINDINGS = 4;

+ 18 - 5
src/anki/gr/vulkan/ShaderImpl.cpp

@@ -120,12 +120,16 @@ void ShaderImpl::doReflection(ConstWeakArray<U8> spirv, SpecConstsVector& specCo
 	}};
 	}};
 	Array2d<DescriptorBinding, MAX_DESCRIPTOR_SETS, MAX_BINDINGS_PER_DESCRIPTOR_SET> descriptors;
 	Array2d<DescriptorBinding, MAX_DESCRIPTOR_SETS, MAX_BINDINGS_PER_DESCRIPTOR_SET> descriptors;
 
 
-	auto func = [&](const std::vector<spirv_cross::Resource>& resources, DescriptorType type) -> void {
+	auto func = [&](const std::vector<spirv_cross::Resource>& resources,
+					DescriptorType type,
+					U minVkBinding,
+					U maxVkBinding) -> void {
 		for(const spirv_cross::Resource& r : resources)
 		for(const spirv_cross::Resource& r : resources)
 		{
 		{
 			const U32 id = r.id;
 			const U32 id = r.id;
 			const U32 set = spvc.get_decoration(id, spv::Decoration::DecorationDescriptorSet);
 			const U32 set = spvc.get_decoration(id, spv::Decoration::DecorationDescriptorSet);
 			const U32 binding = spvc.get_decoration(id, spv::Decoration::DecorationBinding);
 			const U32 binding = spvc.get_decoration(id, spv::Decoration::DecorationBinding);
+			ANKI_ASSERT(binding >= minVkBinding && binding <= maxVkBinding);
 
 
 			m_descriptorSetMask.set(set);
 			m_descriptorSetMask.set(set);
 			m_activeBindingMask[set].set(set);
 			m_activeBindingMask[set].set(set);
@@ -143,10 +147,19 @@ void ShaderImpl::doReflection(ConstWeakArray<U8> spirv, SpecConstsVector& specCo
 		}
 		}
 	};
 	};
 
 
-	func(rsrc.uniform_buffers, DescriptorType::UNIFORM_BUFFER);
-	func(rsrc.sampled_images, DescriptorType::TEXTURE);
-	func(rsrc.storage_buffers, DescriptorType::STORAGE_BUFFER);
-	func(rsrc.storage_images, DescriptorType::IMAGE);
+	func(rsrc.uniform_buffers,
+		DescriptorType::UNIFORM_BUFFER,
+		MAX_TEXTURE_BINDINGS,
+		MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS - 1);
+	func(rsrc.sampled_images, DescriptorType::TEXTURE, 0, MAX_TEXTURE_BINDINGS - 1);
+	func(rsrc.storage_buffers,
+		DescriptorType::STORAGE_BUFFER,
+		MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS,
+		MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS + MAX_STORAGE_BUFFER_BINDINGS - 1);
+	func(rsrc.storage_images,
+		DescriptorType::IMAGE,
+		MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS + MAX_STORAGE_BUFFER_BINDINGS,
+		MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS + MAX_STORAGE_BUFFER_BINDINGS + MAX_IMAGE_BINDINGS - 1);
 
 
 	for(U set = 0; set < MAX_DESCRIPTOR_SETS; ++set)
 	for(U set = 0; set < MAX_DESCRIPTOR_SETS; ++set)
 	{
 	{

+ 71 - 1
src/anki/renderer/ClusterBin.cpp

@@ -455,7 +455,41 @@ void ClusterBin::binTile(U32 tileIdx, BinCtx& ctx, TileCtx& tileCtx)
 
 
 	// Fog volumes
 	// Fog volumes
 	{
 	{
-		// TODO
+		Aabb box;
+		Sphere sphere;
+		for(U i = 0; i < ctx.m_in->m_renderQueue->m_fogDensityVolumes.getSize(); ++i)
+		{
+			const FogDensityQueueElement& fogVol = ctx.m_in->m_renderQueue->m_fogDensityVolumes[i];
+
+			CollisionShape* shape;
+			if(fogVol.m_isBox)
+			{
+				box.setMin(fogVol.m_aabbMin);
+				box.setMax(fogVol.m_aabbMax);
+				shape = &box;
+			}
+			else
+			{
+				sphere.setCenter(fogVol.m_sphereCenter.xyz0());
+				sphere.setRadius(fogVol.m_sphereRadius);
+				shape = &sphere;
+			}
+
+			if(!insideClusterFrustum(frustumPlanes, *shape))
+			{
+				continue;
+			}
+
+			for(U clusterZ = 0; clusterZ < m_clusterCounts[2]; ++clusterZ)
+			{
+				if(!testCollisionShapes(*shape, clusterBoxes[clusterZ]))
+				{
+					continue;
+				}
+
+				ANKI_SET_IDX(4);
+			}
+		}
 	}
 	}
 
 
 	// Upload the indices for all clusters of the tile
 	// Upload the indices for all clusters of the tile
@@ -659,6 +693,42 @@ void ClusterBin::writeTypedObjectsToGpuBuffers(BinCtx& ctx) const
 	{
 	{
 		ctx.m_out->m_probesToken.markUnused();
 		ctx.m_out->m_probesToken.markUnused();
 	}
 	}
+
+	// Fog volumes
+	const U visibleFogVolumeCount = rqueue.m_fogDensityVolumes.getSize();
+	if(visibleFogVolumeCount)
+	{
+		FogDensityVolume* data = static_cast<FogDensityVolume*>(
+			ctx.m_in->m_stagingMem->allocateFrame(sizeof(FogDensityVolume) * visibleFogVolumeCount,
+				StagingGpuMemoryType::UNIFORM,
+				ctx.m_out->m_fogDensityVolumesToken));
+
+		WeakArray<FogDensityVolume> gpuFogVolumes(data, visibleFogVolumeCount);
+
+		for(U i = 0; i < visibleFogVolumeCount; ++i)
+		{
+			const FogDensityQueueElement& in = rqueue.m_fogDensityVolumes[i];
+			FogDensityVolume& out = gpuFogVolumes[i];
+
+			out.m_density = in.m_density;
+			if(in.m_isBox)
+			{
+				out.m_isBox = 1;
+				out.m_aabbMinOrSphereCenter = in.m_aabbMin;
+				out.m_aabbMaxOrSphereRadiusSquared = in.m_aabbMax;
+			}
+			else
+			{
+				out.m_isBox = 0;
+				out.m_aabbMinOrSphereCenter = in.m_sphereCenter;
+				out.m_aabbMaxOrSphereRadiusSquared = Vec3(in.m_sphereRadius * in.m_sphereRadius);
+			}
+		}
+	}
+	else
+	{
+		ctx.m_out->m_fogDensityVolumesToken.markUnused();
+	}
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 1 - 0
src/anki/renderer/ClusterBin.h

@@ -40,6 +40,7 @@ public:
 	StagingGpuMemoryToken m_spotLightsToken;
 	StagingGpuMemoryToken m_spotLightsToken;
 	StagingGpuMemoryToken m_probesToken;
 	StagingGpuMemoryToken m_probesToken;
 	StagingGpuMemoryToken m_decalsToken;
 	StagingGpuMemoryToken m_decalsToken;
+	StagingGpuMemoryToken m_fogDensityVolumesToken;
 	StagingGpuMemoryToken m_clustersToken;
 	StagingGpuMemoryToken m_clustersToken;
 	StagingGpuMemoryToken m_indicesToken;
 	StagingGpuMemoryToken m_indicesToken;
 
 

+ 2 - 1
src/anki/renderer/VolumetricLightingAccumulation.cpp

@@ -63,7 +63,7 @@ Error VolumetricLightingAccumulation::init(const ConfigSet& config)
 	// Create RTs
 	// Create RTs
 	TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(m_volumeSize[0],
 	TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(m_volumeSize[0],
 		m_volumeSize[1],
 		m_volumeSize[1],
-		LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT,
+		Format::R16G16B16A16_SFLOAT,
 		TextureUsageBit::IMAGE_COMPUTE_READ_WRITE | TextureUsageBit::SAMPLED_FRAGMENT
 		TextureUsageBit::IMAGE_COMPUTE_READ_WRITE | TextureUsageBit::SAMPLED_FRAGMENT
 			| TextureUsageBit::SAMPLED_COMPUTE,
 			| TextureUsageBit::SAMPLED_COMPUTE,
 		"VolLight");
 		"VolLight");
@@ -124,6 +124,7 @@ void VolumetricLightingAccumulation::run(RenderPassWorkContext& rgraphCtx)
 	bindUniforms(cmdb, 0, 1, rsrc.m_pointLightsToken);
 	bindUniforms(cmdb, 0, 1, rsrc.m_pointLightsToken);
 	bindUniforms(cmdb, 0, 2, rsrc.m_spotLightsToken);
 	bindUniforms(cmdb, 0, 2, rsrc.m_spotLightsToken);
 	bindUniforms(cmdb, 0, 3, rsrc.m_probesToken);
 	bindUniforms(cmdb, 0, 3, rsrc.m_probesToken);
+	bindUniforms(cmdb, 0, 4, rsrc.m_fogDensityVolumesToken);
 	bindStorage(cmdb, 0, 0, rsrc.m_clustersToken);
 	bindStorage(cmdb, 0, 0, rsrc.m_clustersToken);
 	bindStorage(cmdb, 0, 1, rsrc.m_indicesToken);
 	bindStorage(cmdb, 0, 1, rsrc.m_indicesToken);