Browse Source

Unify spot and point lights in the GPU scene

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
52c33c7227

+ 2 - 5
AnKi/Renderer/Common.h

@@ -175,11 +175,8 @@ inline GpuSceneContiguousArrayType gpuSceneNonRenderableObjectTypeToGpuSceneCont
 	GpuSceneContiguousArrayType out;
 	switch(type)
 	{
-	case GpuSceneNonRenderableObjectType::kPointLight:
-		out = GpuSceneContiguousArrayType::kPointLights;
-		break;
-	case GpuSceneNonRenderableObjectType::kSpotLight:
-		out = GpuSceneContiguousArrayType::kSpotLights;
+	case GpuSceneNonRenderableObjectType::kLight:
+		out = GpuSceneContiguousArrayType::kLights;
 		break;
 	case GpuSceneNonRenderableObjectType::kDecal:
 		out = GpuSceneContiguousArrayType::kDecals;

+ 34 - 9
AnKi/Renderer/PackVisibleClusteredObjects.cpp

@@ -10,6 +10,7 @@
 #include <AnKi/Shaders/Include/GpuSceneTypes.h>
 #include <AnKi/Shaders/Include/MiscRendererTypes.h>
 #include <AnKi/Core/GpuMemory/GpuSceneBuffer.h>
+#include <AnKi/Scene/ContiguousArrayAllocator.h>
 
 namespace anki {
 
@@ -54,7 +55,7 @@ Error PackVisibleClusteredObjects::init()
 }
 
 template<typename TClustererType, ClusteredObjectType kType, typename TRenderQueueElement>
-void PackVisibleClusteredObjects::dispatchType(WeakArray<TRenderQueueElement> array, const RenderQueue& rqueue, CommandBuffer& cmdb)
+void PackVisibleClusteredObjects::dispatchType(WeakArray<TRenderQueueElement> array, CommandBuffer& cmdb)
 {
 	if(array.getSize() == 0)
 	{
@@ -110,8 +111,32 @@ void PackVisibleClusteredObjects::dispatchType(WeakArray<TRenderQueueElement> ar
 		}
 	}
 
-	cmdb.bindStorageBuffer(0, 0, &GpuSceneBuffer::getSingleton().getBuffer(), rqueue.m_clustererObjectsArrayOffsets[kType],
-						   rqueue.m_clustererObjectsArrayRanges[kType]);
+	GpuSceneContiguousArrayType arrayType;
+	switch(kType)
+	{
+	case ClusteredObjectType::kPointLight:
+	case ClusteredObjectType::kSpotLight:
+		arrayType = GpuSceneContiguousArrayType::kLights;
+		break;
+	case ClusteredObjectType::kDecal:
+		arrayType = GpuSceneContiguousArrayType::kDecals;
+		break;
+	case ClusteredObjectType::kFogDensityVolume:
+		arrayType = GpuSceneContiguousArrayType::kFogDensityVolumes;
+		break;
+	case ClusteredObjectType::kGlobalIlluminationProbe:
+		arrayType = GpuSceneContiguousArrayType::kGlobalIlluminationProbes;
+		break;
+	case ClusteredObjectType::kReflectionProbe:
+		arrayType = GpuSceneContiguousArrayType::kReflectionProbes;
+		break;
+	default:
+		arrayType = GpuSceneContiguousArrayType::kCount;
+	}
+
+	cmdb.bindStorageBuffer(0, 0, &GpuSceneBuffer::getSingleton().getBuffer(), GpuSceneContiguousArrays::getSingleton().getArrayBaseOffset(arrayType),
+						   GpuSceneContiguousArrays::getSingleton().getElementCount(arrayType)
+							   * GpuSceneContiguousArrays::getSingleton().getElementSize(arrayType));
 
 	cmdb.bindStorageBuffer(0, 1, m_allClustererObjects.get(), m_structureBufferOffsets[kType], array.getSize() * sizeof(TClustererType));
 
@@ -145,12 +170,12 @@ void PackVisibleClusteredObjects::populateRenderGraph(RenderingContext& ctx)
 		const RenderQueue& rqueue = *ctx.m_renderQueue;
 		CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 
-		dispatchType<PointLight, ClusteredObjectType::kPointLight>(rqueue.m_pointLights, rqueue, cmdb);
-		dispatchType<SpotLight, ClusteredObjectType::kSpotLight>(rqueue.m_spotLights, rqueue, cmdb);
-		dispatchType<Decal, ClusteredObjectType::kDecal>(rqueue.m_decals, rqueue, cmdb);
-		dispatchType<FogDensityVolume, ClusteredObjectType::kFogDensityVolume>(rqueue.m_fogDensityVolumes, rqueue, cmdb);
-		dispatchType<ReflectionProbe, ClusteredObjectType::kReflectionProbe>(rqueue.m_reflectionProbes, rqueue, cmdb);
-		dispatchType<GlobalIlluminationProbe, ClusteredObjectType::kGlobalIlluminationProbe>(rqueue.m_giProbes, rqueue, cmdb);
+		dispatchType<PointLight, ClusteredObjectType::kPointLight>(rqueue.m_pointLights, cmdb);
+		dispatchType<SpotLight, ClusteredObjectType::kSpotLight>(rqueue.m_spotLights, cmdb);
+		dispatchType<Decal, ClusteredObjectType::kDecal>(rqueue.m_decals, cmdb);
+		dispatchType<FogDensityVolume, ClusteredObjectType::kFogDensityVolume>(rqueue.m_fogDensityVolumes, cmdb);
+		dispatchType<ReflectionProbe, ClusteredObjectType::kReflectionProbe>(rqueue.m_reflectionProbes, cmdb);
+		dispatchType<GlobalIlluminationProbe, ClusteredObjectType::kGlobalIlluminationProbe>(rqueue.m_giProbes, cmdb);
 	});
 }
 

+ 1 - 1
AnKi/Renderer/PackVisibleClusteredObjects.h

@@ -44,7 +44,7 @@ private:
 	U32 m_threadGroupSize = 0;
 
 	template<typename TClustererType, ClusteredObjectType kType, typename TRenderQueueElement>
-	void dispatchType(WeakArray<TRenderQueueElement> array, const RenderQueue& rqueue, CommandBuffer& cmdb);
+	void dispatchType(WeakArray<TRenderQueueElement> array, CommandBuffer& cmdb);
 };
 /// @}
 

+ 0 - 3
AnKi/Renderer/RenderQueue.h

@@ -420,9 +420,6 @@ public:
 	ReflectionProbeQueueElementForRefresh* m_reflectionProbeForRefresh = nullptr;
 	GlobalIlluminationProbeQueueElementForRefresh* m_giProbeForRefresh = nullptr;
 
-	Array<PtrSize, U32(ClusteredObjectType::kCount)> m_clustererObjectsArrayOffsets = {};
-	Array<PtrSize, U32(ClusteredObjectType::kCount)> m_clustererObjectsArrayRanges = {};
-
 	RenderQueue()
 	{
 		zeroMemory(m_directionalLight);

+ 4 - 8
AnKi/Scene/Components/LightComponent.cpp

@@ -55,13 +55,9 @@ void LightComponent::setLightComponentType(LightComponentType type)
 		GpuSceneContiguousArrays::getSingleton().deferredFree(m_gpuSceneLightIndex);
 	}
 
-	if(!m_gpuSceneLightIndex.isValid() && type == LightComponentType::kPoint)
+	if(!m_gpuSceneLightIndex.isValid() && (type == LightComponentType::kPoint || type == LightComponentType::kSpot))
 	{
-		m_gpuSceneLightIndex = GpuSceneContiguousArrays::getSingleton().allocate(GpuSceneContiguousArrayType::kPointLights);
-	}
-	else if(!m_gpuSceneLightIndex.isValid() && type == LightComponentType::kSpot)
-	{
-		m_gpuSceneLightIndex = GpuSceneContiguousArrays::getSingleton().allocate(GpuSceneContiguousArrayType::kSpotLights);
+		m_gpuSceneLightIndex = GpuSceneContiguousArrays::getSingleton().allocate(GpuSceneContiguousArrayType::kLights);
 	}
 
 	m_type = type;
@@ -128,7 +124,7 @@ Error LightComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		}
 
 		// Upload to the GPU scene
-		GpuScenePointLight gpuLight;
+		GpuSceneLight gpuLight = {};
 		gpuLight.m_position = m_worldTransform.getOrigin().xyz();
 		gpuLight.m_radius = m_point.m_radius;
 		gpuLight.m_diffuseColor = m_diffColor.xyz();
@@ -195,7 +191,7 @@ Error LightComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		}
 
 		// Upload to the GPU scene
-		GpuSceneSpotLight gpuLight;
+		GpuSceneLight gpuLight = {};
 		gpuLight.m_position = m_worldTransform.getOrigin().xyz();
 		for(U32 i = 0; i < 4; ++i)
 		{

+ 7 - 13
AnKi/Scene/ContiguousArrayAllocator.cpp

@@ -97,19 +97,13 @@ GpuSceneContiguousArrays::GpuSceneContiguousArrays()
 	const ConfigSet& cfg = ConfigSet::getSingleton();
 	constexpr F32 kGrowRate = 2.0;
 
-	const Array<U32, U32(GpuSceneContiguousArrayType::kCount)> minElementCount = {cfg.getSceneMinGpuSceneTransforms(),
-																				  cfg.getSceneMinGpuSceneMeshes(),
-																				  cfg.getSceneMinGpuSceneParticleEmitters(),
-																				  cfg.getSceneMinGpuSceneLights(),
-																				  cfg.getSceneMinGpuSceneLights(),
-																				  cfg.getSceneMinGpuSceneReflectionProbes(),
-																				  cfg.getSceneMinGpuSceneGlobalIlluminationProbes(),
-																				  cfg.getSceneMinGpuSceneDecals(),
-																				  cfg.getSceneMinGpuSceneFogDensityVolumes(),
-																				  cfg.getSceneMinGpuSceneRenderables(),
-																				  cfg.getSceneMinGpuSceneRenderables(),
-																				  cfg.getSceneMinGpuSceneRenderables(),
-																				  cfg.getSceneMinGpuSceneRenderables()};
+	const Array<U32, U32(GpuSceneContiguousArrayType::kCount)> minElementCount = {
+		cfg.getSceneMinGpuSceneTransforms(),       cfg.getSceneMinGpuSceneMeshes(),
+		cfg.getSceneMinGpuSceneParticleEmitters(), cfg.getSceneMinGpuSceneLights(),
+		cfg.getSceneMinGpuSceneReflectionProbes(), cfg.getSceneMinGpuSceneGlobalIlluminationProbes(),
+		cfg.getSceneMinGpuSceneDecals(),           cfg.getSceneMinGpuSceneFogDensityVolumes(),
+		cfg.getSceneMinGpuSceneRenderables(),      cfg.getSceneMinGpuSceneRenderables(),
+		cfg.getSceneMinGpuSceneRenderables(),      cfg.getSceneMinGpuSceneRenderables()};
 
 	for(GpuSceneContiguousArrayType type : EnumIterable<GpuSceneContiguousArrayType>())
 	{

+ 3 - 5
AnKi/Scene/ContiguousArrayAllocator.h

@@ -19,8 +19,7 @@ enum class GpuSceneContiguousArrayType : U8
 	kTransformPairs,
 	kMeshLods,
 	kParticleEmitters,
-	kPointLights,
-	kSpotLights,
+	kLights,
 	kReflectionProbes,
 	kGlobalIlluminationProbes,
 	kDecals,
@@ -198,12 +197,11 @@ private:
 
 	U8 m_frame = 0;
 
-	static constexpr Array<U8, U32(GpuSceneContiguousArrayType::kCount)> m_componentCount = {2, kMaxLodCount, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+	static constexpr Array<U8, U32(GpuSceneContiguousArrayType::kCount)> m_componentCount = {2, kMaxLodCount, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
 	static constexpr Array<U8, U32(GpuSceneContiguousArrayType::kCount)> m_componentSize = {sizeof(Mat3x4),
 																							sizeof(GpuSceneMeshLod),
 																							sizeof(GpuSceneParticleEmitter),
-																							sizeof(GpuScenePointLight),
-																							sizeof(GpuSceneSpotLight),
+																							sizeof(GpuSceneLight),
 																							sizeof(GpuSceneReflectionProbe),
 																							sizeof(GpuSceneGlobalIlluminationProbe),
 																							sizeof(GpuSceneDecal),

+ 0 - 14
AnKi/Scene/Visibility.cpp

@@ -794,20 +794,6 @@ void CombineResultsTask::combine()
 				  }
 			  });
 
-	const GpuSceneContiguousArrays& arrays = GpuSceneContiguousArrays::getSingleton();
-
-	auto setOffset = [&](ClusteredObjectType type, GpuSceneContiguousArrayType type2) {
-		results.m_clustererObjectsArrayOffsets[type] = arrays.getElementCount(type2) ? arrays.getArrayBaseOffset(type2) : 0;
-		results.m_clustererObjectsArrayRanges[type] = arrays.getElementCount(type2) * arrays.getElementSize(type2);
-	};
-
-	setOffset(ClusteredObjectType::kPointLight, GpuSceneContiguousArrayType::kPointLights);
-	setOffset(ClusteredObjectType::kSpotLight, GpuSceneContiguousArrayType::kSpotLights);
-	setOffset(ClusteredObjectType::kDecal, GpuSceneContiguousArrayType::kDecals);
-	setOffset(ClusteredObjectType::kFogDensityVolume, GpuSceneContiguousArrayType::kFogDensityVolumes);
-	setOffset(ClusteredObjectType::kGlobalIlluminationProbe, GpuSceneContiguousArrayType::kGlobalIlluminationProbes);
-	setOffset(ClusteredObjectType::kReflectionProbe, GpuSceneContiguousArrayType::kReflectionProbes);
-
 	// Cleanup
 	if(m_frcCtx->m_r)
 	{

+ 5 - 12
AnKi/Shaders/GpuVisibilityNonRenderables.ankiprog

@@ -4,11 +4,11 @@
 // http://www.anki3d.org/LICENSE
 
 #pragma anki mutator HZB_TEST 0 1
-#pragma anki mutator OBJECT_TYPE 0 1 2 3 4 5 // Same as GpuSceneNonRenderableObjectType
+#pragma anki mutator OBJECT_TYPE 0 1 2 3 4 // Same as GpuSceneNonRenderableObjectType
 #pragma anki mutator CPU_FEEDBACK 0 1
 
+#pragma anki skip_mutation CPU_FEEDBACK 1 OBJECT_TYPE 1
 #pragma anki skip_mutation CPU_FEEDBACK 1 OBJECT_TYPE 2
-#pragma anki skip_mutation CPU_FEEDBACK 1 OBJECT_TYPE 3
 
 #pragma anki start comp
 
@@ -17,10 +17,8 @@
 #include <AnKi/Shaders/Include/GpuVisibilityTypes.h>
 #include <AnKi/Shaders/CollisionFunctions.hlsl>
 
-#if OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_POINT_LIGHT
-typedef GpuScenePointLight ObjectType;
-#elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_SPOT_LIGHT
-typedef GpuSceneSpotLight ObjectType;
+#if OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_LIGHT
+typedef GpuSceneLight ObjectType;
 #elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_DECAL
 typedef GpuSceneDecal ObjectType;
 #elif OBJECT_TYPE == ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_FOG_DENSITY_VOLUME
@@ -43,12 +41,7 @@ typedef GpuSceneGlobalIlluminationProbe ObjectType;
 [[vk::binding(4)]] RWStructuredBuffer<U32> g_counterBuffer;
 #endif
 
-Vec4 getSphere(GpuScenePointLight l)
-{
-	return Vec4(l.m_position, l.m_radius);
-}
-
-Vec4 getSphere(GpuSceneSpotLight l)
+Vec4 getSphere(GpuSceneLight l)
 {
 	return Vec4(l.m_position, l.m_radius);
 }

+ 2 - 5
AnKi/Shaders/Include/GpuSceneFunctions.h

@@ -55,11 +55,8 @@ inline GpuSceneNonRenderableObjectTypeWithFeedback toGpuSceneNonRenderableObject
 	GpuSceneNonRenderableObjectTypeWithFeedback ret;
 	switch(type)
 	{
-	case GpuSceneNonRenderableObjectType::kPointLight:
-		ret = GpuSceneNonRenderableObjectTypeWithFeedback::kPointLight;
-		break;
-	case GpuSceneNonRenderableObjectType::kSpotLight:
-		ret = GpuSceneNonRenderableObjectTypeWithFeedback::kSpotLight;
+	case GpuSceneNonRenderableObjectType::kLight:
+		ret = GpuSceneNonRenderableObjectTypeWithFeedback::kLight;
 		break;
 	case GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe:
 		ret = GpuSceneNonRenderableObjectTypeWithFeedback::kGlobalIlluminationProbe;

+ 19 - 42
AnKi/Shaders/Include/GpuSceneTypes.h

@@ -52,44 +52,25 @@ struct GpuSceneParticleEmitter
 };
 static_assert(sizeof(GpuSceneParticleEmitter) == sizeof(Vec4) * 2);
 
-/// Point light.
-struct GpuScenePointLight
+/// Point or spot light.
+struct GpuSceneLight
 {
 	Vec3 m_position; ///< Position in world space.
-	RF32 m_radius; ///< Radius
+	RF32 m_radius; ///< Radius.
 
 	RVec3 m_diffuseColor;
 	RF32 m_squareRadiusOverOne; ///< 1/(radius^2).
 
+	U32 m_type; ///< 0: point, 1: spot.
 	U32 m_shadow;
 	U32 m_uuid;
-	U32 m_padding0;
-	U32 m_padding1;
-};
-constexpr U32 kSizeof_GpuScenePointLight = 3u * sizeof(Vec4);
-static_assert(sizeof(GpuScenePointLight) == kSizeof_GpuScenePointLight);
-
-/// Spot light.
-struct GpuSceneSpotLight
-{
-	Vec3 m_position;
-	F32 m_padding0;
-
-	Vec4 m_edgePoints[4u]; ///< Edge points in world space.
-
-	RVec3 m_diffuseColor;
-	RF32 m_radius; ///< Max distance.
+	F32 m_innerCos; ///< Only for spot light.
 
 	RVec3 m_direction; ///< Light direction.
-	RF32 m_squareRadiusOverOne; ///< 1/(radius^2).
+	RF32 m_outerCos; ///< Only for spot light.
 
-	U32 m_shadow;
-	RF32 m_outerCos;
-	RF32 m_innerCos;
-	U32 m_uuid;
+	Vec4 m_edgePoints[4u]; ///< Edge points in world space. Only for spot light.
 };
-constexpr U32 kSizeof_GpuSceneSpotLight = 8u * sizeof(Vec4);
-static_assert(sizeof(GpuSceneSpotLight) == kSizeof_GpuSceneSpotLight);
 
 /// Representation of a reflection probe.
 struct GpuSceneReflectionProbe
@@ -158,8 +139,7 @@ static_assert(sizeof(GpuSceneFogDensityVolume) == kSizeof_GpuSceneFogDensityVolu
 
 enum class GpuSceneNonRenderableObjectType : U32
 {
-	kPointLight,
-	kSpotLight,
+	kLight,
 	kDecal,
 	kFogDensityVolume,
 	kReflectionProbe,
@@ -170,31 +150,28 @@ enum class GpuSceneNonRenderableObjectType : U32
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(GpuSceneNonRenderableObjectType)
 
-#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_POINT_LIGHT 0
-#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_SPOT_LIGHT 1
-#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_DECAL 2
-#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_FOG_DENSITY_VOLUME 3
-#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_REFLECTION_PROBE 4
-#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_GLOBAL_ILLUMINATION_PROBE 5
+#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_LIGHT 0
+#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_DECAL 1
+#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_FOG_DENSITY_VOLUME 2
+#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_REFLECTION_PROBE 3
+#define ANKI_GPU_SCENE_NON_RENDERABLE_OBJECT_TYPE_GLOBAL_ILLUMINATION_PROBE 4
 
 enum class GpuSceneNonRenderableObjectTypeBit : U32
 {
 	kNone = 0,
 
-	kPointLight = 1 << 0,
-	kSpotLight = 1 << 1,
-	kDecal = 1 << 2,
-	kFogDensityVolume = 1 << 3,
-	kReflectionProbe = 1 << 4,
-	kGlobalIlluminationProbe = 1 << 5,
+	kPLight = 1 << 0,
+	kDecal = 1 << 1,
+	kFogDensityVolume = 1 << 2,
+	kReflectionProbe = 1 << 3,
+	kGlobalIlluminationProbe = 1 << 4,
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(GpuSceneNonRenderableObjectTypeBit)
 
 /// Non-renderable types that require GPU to CPU feedback.
 enum class GpuSceneNonRenderableObjectTypeWithFeedback : U32
 {
-	kPointLight,
-	kSpotLight,
+	kLight,
 	kReflectionProbe,
 	kGlobalIlluminationProbe,
 

+ 4 - 4
AnKi/Shaders/PackVisibleClusteredObjects.ankiprog

@@ -13,12 +13,12 @@
 
 #if OBJECT_TYPE == 0
 typedef PointLight ClusteredType;
-typedef GpuScenePointLight GpuSceneType;
+typedef GpuSceneLight GpuSceneType;
 
 [[vk::binding(3)]] StructuredBuffer<PointLightExtra> g_extras;
 #elif OBJECT_TYPE == 1
 typedef SpotLight ClusteredType;
-typedef GpuSceneSpotLight GpuSceneType;
+typedef GpuSceneLight GpuSceneType;
 
 [[vk::binding(3)]] StructuredBuffer<SpotLightExtra> g_extras;
 #elif OBJECT_TYPE == 2
@@ -60,7 +60,7 @@ struct Uniforms
 	}
 
 #if OBJECT_TYPE == 0
-	const GpuScenePointLight input = g_inBuffer[g_indices[idxOut]];
+	const GpuSceneLight input = g_inBuffer[g_indices[idxOut]];
 	const PointLightExtra extra = g_extras[idxOut];
 
 	PointLight output;
@@ -74,7 +74,7 @@ struct Uniforms
 
 	g_outBuffer[idxOut] = output;
 #elif OBJECT_TYPE == 1
-	const GpuSceneSpotLight input = g_inBuffer[g_indices[idxOut]];
+	const GpuSceneLight input = g_inBuffer[g_indices[idxOut]];
 	const SpotLightExtra extra = g_extras[idxOut];
 
 	SpotLight output;