Browse Source

Add more GPU scene structures

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
5fffd728f1

+ 24 - 0
AnKi/Scene/Components/DecalComponent.cpp

@@ -15,6 +15,8 @@ DecalComponent::DecalComponent(SceneNode* node)
 	, m_node(node)
 	, m_spatial(this)
 {
+	m_gpuSceneDecalOffset =
+		U32(node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(GpuSceneContiguousArrayType::kDecals));
 }
 
 DecalComponent::~DecalComponent()
@@ -22,6 +24,12 @@ DecalComponent::~DecalComponent()
 	m_spatial.removeFromOctree(m_node->getSceneGraph().getOctree());
 }
 
+void DecalComponent::onDestroy(SceneNode& node)
+{
+	node.getSceneGraph().getAllGpuSceneContiguousArrays().deferredFree(GpuSceneContiguousArrayType::kDecals,
+																	   m_gpuSceneDecalOffset);
+}
+
 void DecalComponent::setLayer(CString fname, F32 blendFactor, LayerType type)
 {
 	Layer& l = m_layers[type];
@@ -72,6 +80,22 @@ Error DecalComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		const Obb obbL(center, Mat3x4::getIdentity(), extend);
 		m_obb = obbL.getTransformed(info.m_node->getWorldTransform());
 		m_spatial.setBoundingShape(m_obb);
+
+		// Upload to the GPU scene
+		GpuSceneDecal gpuDecal;
+		gpuDecal.m_diffuseTexture = m_layers[LayerType::kDiffuse].m_bindlessTextureIndex;
+		gpuDecal.m_roughnessMetalnessTexture = m_layers[LayerType::kRoughnessMetalness].m_bindlessTextureIndex;
+		gpuDecal.m_diffuseBlendFactor = m_layers[LayerType::kDiffuse].m_blendFactor;
+		gpuDecal.m_roughnessMetalnessFactor = m_layers[LayerType::kRoughnessMetalness].m_blendFactor;
+		gpuDecal.m_textureMatrix = m_biasProjViewMat;
+
+		const Mat4 trf(m_obb.getCenter().xyz1(), m_obb.getRotation().getRotationPart(), 1.0f);
+		gpuDecal.m_invertedTransform = trf.getInverse();
+
+		gpuDecal.m_obbExtend = m_obb.getExtend().xyz();
+
+		getExternalSubsystems(*info.m_node)
+			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, m_gpuSceneDecalOffset, sizeof(gpuDecal), &gpuDecal);
 	}
 
 	const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());

+ 4 - 0
AnKi/Scene/Components/DecalComponent.h

@@ -93,11 +93,15 @@ private:
 	Vec3 m_boxSize = Vec3(1.0f);
 	Obb m_obb = Obb(Vec4(0.0f), Mat3x4::getIdentity(), Vec4(0.5f, 0.5f, 0.5f, 0.0f));
 
+	U32 m_gpuSceneDecalOffset = kMaxU32;
+
 	Bool m_dirty = true;
 
 	void setLayer(CString fname, F32 blendFactor, LayerType type);
 
 	Error update(SceneComponentUpdateInfo& info, Bool& updated);
+
+	void onDestroy(SceneNode& node);
 };
 /// @}
 

+ 29 - 0
AnKi/Scene/Components/FogDensityComponent.cpp

@@ -9,9 +9,20 @@
 
 namespace anki {
 
+FogDensityComponent::FogDensityComponent(SceneNode* node)
+	: SceneComponent(node, getStaticClassId())
+	, m_spatial(this)
+{
+	m_gpuSceneOffset = U32(node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(
+		GpuSceneContiguousArrayType::kFogDensityVolumes));
+}
+
 void FogDensityComponent::onDestroy(SceneNode& node)
 {
 	m_spatial.removeFromOctree(node.getSceneGraph().getOctree());
+
+	node.getSceneGraph().getAllGpuSceneContiguousArrays().deferredFree(GpuSceneContiguousArrayType::kFogDensityVolumes,
+																	   m_gpuSceneOffset);
 }
 
 Error FogDensityComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
@@ -34,6 +45,24 @@ Error FogDensityComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 			const Sphere sphere(m_worldPos, m_sphereRadius);
 			m_spatial.setBoundingShape(sphere);
 		}
+
+		// Upload to the GPU scene
+		GpuSceneFogDensityVolume gpuVolume;
+		if(m_isBox)
+		{
+			gpuVolume.m_aabbMinOrSphereCenter = m_aabbMin.xyz();
+			gpuVolume.m_aabbMaxOrSphereRadiusSquared = m_aabbMax.xyz();
+		}
+		else
+		{
+			gpuVolume.m_aabbMaxOrSphereRadiusSquared = Vec3(m_sphereRadius * m_sphereRadius);
+			gpuVolume.m_aabbMinOrSphereCenter = m_worldPos.xyz();
+		}
+		gpuVolume.m_isBox = m_isBox;
+		gpuVolume.m_density = m_density;
+
+		getExternalSubsystems(*info.m_node)
+			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, m_gpuSceneOffset, sizeof(gpuVolume), &gpuVolume);
 	}
 
 	const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());

+ 6 - 7
AnKi/Scene/Components/FogDensityComponent.h

@@ -24,11 +24,7 @@ class FogDensityComponent : public SceneComponent
 public:
 	static constexpr F32 kMinShapeSize = 1.0_cm;
 
-	FogDensityComponent(SceneNode* node)
-		: SceneComponent(node, getStaticClassId())
-		, m_spatial(this)
-	{
-	}
+	FogDensityComponent(SceneNode* node);
 
 	void setBoxVolumeSize(Vec3 sizeXYZ)
 	{
@@ -71,6 +67,7 @@ public:
 	void setDensity(F32 d)
 	{
 		ANKI_ASSERT(d >= 0.0f);
+		m_dirty = true;
 		m_density = d;
 	}
 
@@ -109,8 +106,10 @@ private:
 	Vec3 m_worldPos = Vec3(0.0f);
 	F32 m_density = 1.0f;
 
-	Bool m_isBox : 1 = true;
-	Bool m_dirty : 1 = true;
+	U32 m_gpuSceneOffset = kMaxU32;
+
+	Bool m_isBox = true;
+	Bool m_dirty = true;
 
 	Error update(SceneComponentUpdateInfo& info, Bool& updated);
 

+ 17 - 0
AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp

@@ -25,6 +25,9 @@ GlobalIlluminationProbeComponent::GlobalIlluminationProbeComponent(SceneNode* no
 		m_frustums[i].setShadowCascadeCount(1);
 		m_frustums[i].update();
 	}
+
+	m_gpuSceneOffset = U32(node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(
+		GpuSceneContiguousArrayType::kGlobalIlluminationProbes));
 }
 
 GlobalIlluminationProbeComponent::~GlobalIlluminationProbeComponent()
@@ -34,6 +37,9 @@ GlobalIlluminationProbeComponent::~GlobalIlluminationProbeComponent()
 void GlobalIlluminationProbeComponent::onDestroy(SceneNode& node)
 {
 	m_spatial.removeFromOctree(node.getSceneGraph().getOctree());
+
+	node.getSceneGraph().getAllGpuSceneContiguousArrays().deferredFree(
+		GpuSceneContiguousArrayType::kGlobalIlluminationProbes, m_gpuSceneOffset);
 }
 
 Error GlobalIlluminationProbeComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
@@ -51,6 +57,17 @@ Error GlobalIlluminationProbeComponent::update(SceneComponentUpdateInfo& info, B
 
 		const Aabb aabb(-m_halfSize + m_worldPos, m_halfSize + m_worldPos);
 		m_spatial.setBoundingShape(aabb);
+
+		// Upload to the GPU scene
+		GpuSceneGlobalIlluminationProbe gpuProbe;
+		gpuProbe.m_aabbMin = aabb.getMin().xyz();
+		gpuProbe.m_aabbMax = aabb.getMax().xyz();
+		gpuProbe.m_textureIndex = 0; // Unknown at this point
+		gpuProbe.m_halfTexelSizeU = 1.0f / F32(m_cellCounts.y()) / 2.0f;
+		gpuProbe.m_fadeDistance = m_fadeDistance;
+
+		getExternalSubsystems(*info.m_node)
+			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, m_gpuSceneOffset, sizeof(gpuProbe), &gpuProbe);
 	}
 
 	if(m_markedForRendering) [[unlikely]]

+ 2 - 0
AnKi/Scene/Components/GlobalIlluminationProbeComponent.h

@@ -105,6 +105,8 @@ private:
 	F32 m_cellSize = 4.0f; ///< Cell size in meters.
 	F32 m_fadeDistance = 0.2f;
 
+	U32 m_gpuSceneOffset = kMaxU32;
+
 	Array<Frustum, 6> m_frustums;
 
 	Spatial m_spatial;

+ 1 - 1
AnKi/Scene/Components/LightComponent.cpp

@@ -29,7 +29,7 @@ LightComponent::LightComponent(SceneNode* node)
 	m_worldTransform = node->getWorldTransform();
 
 	m_gpuSceneLightOffset =
-		node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(GpuSceneContiguousArrayType::kLights);
+		U32(node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(GpuSceneContiguousArrayType::kLights));
 }
 
 LightComponent::~LightComponent()

+ 15 - 0
AnKi/Scene/Components/ReflectionProbeComponent.cpp

@@ -27,6 +27,9 @@ ReflectionProbeComponent::ReflectionProbeComponent(SceneNode* node)
 		m_frustums[i].setShadowCascadeCount(1);
 		m_frustums[i].update();
 	}
+
+	m_gpuSceneOffset = U32(node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(
+		GpuSceneContiguousArrayType::kReflectionProbes));
 }
 
 ReflectionProbeComponent::~ReflectionProbeComponent()
@@ -71,6 +74,15 @@ Error ReflectionProbeComponent::update(SceneComponentUpdateInfo& info, Bool& upd
 
 		const Aabb aabbWorld(-m_halfSize + m_worldPos, m_halfSize + m_worldPos);
 		m_spatial.setBoundingShape(aabbWorld);
+
+		// Upload to the GPU scene
+		GpuSceneReflectionProbe gpuProbe;
+		gpuProbe.m_position = m_worldPos;
+		gpuProbe.m_cubemapIndex = 0; // Unknown at this point
+		gpuProbe.m_aabbMin = aabbWorld.getMin().xyz();
+		gpuProbe.m_aabbMax = aabbWorld.getMax().xyz();
+		getExternalSubsystems(*info.m_node)
+			.m_gpuSceneMicroPatcher->newCopy(*info.m_framePool, m_gpuSceneOffset, sizeof(gpuProbe), &gpuProbe);
 	}
 
 	const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());
@@ -88,6 +100,9 @@ Error ReflectionProbeComponent::update(SceneComponentUpdateInfo& info, Bool& upd
 void ReflectionProbeComponent::onDestroy(SceneNode& node)
 {
 	m_spatial.removeFromOctree(node.getSceneGraph().getOctree());
+
+	node.getSceneGraph().getAllGpuSceneContiguousArrays().deferredFree(GpuSceneContiguousArrayType::kParticleEmitters,
+																	   m_gpuSceneOffset);
 }
 
 } // end namespace anki

+ 2 - 0
AnKi/Scene/Components/ReflectionProbeComponent.h

@@ -65,6 +65,8 @@ private:
 	Vec3 m_worldPos = Vec3(kMaxF32);
 	Vec3 m_halfSize = Vec3(1.0f);
 
+	U32 m_gpuSceneOffset = kMaxU32;
+
 	Spatial m_spatial;
 
 	Array<Frustum, 6> m_frustums;

+ 7 - 0
AnKi/Scene/ConfigVars.defs.h

@@ -33,3 +33,10 @@ ANKI_CONFIG_VAR_U32(SceneMinGpuSceneMeshes, 8 * 1024, 8, 100 * 1024, "The min nu
 ANKI_CONFIG_VAR_U32(SceneMinGpuSceneParticleEmitters, 1 * 1024, 8, 100 * 1024,
 					"The min number of particle emitters stored in the GPU scene")
 ANKI_CONFIG_VAR_U32(SceneMinGpuSceneLights, 2 * 1024, 8, 100 * 1024, "The min number of lights stored in the GPU scene")
+ANKI_CONFIG_VAR_U32(SceneMinGpuSceneReflectionProbes, 128, 8, 100 * 1024,
+					"The min number of reflection probes stored in the GPU scene")
+ANKI_CONFIG_VAR_U32(SceneMinGpuSceneGlobalIlluminationProbes, 128, 8, 100 * 1024,
+					"The min number of GI probes stored in the GPU scene")
+ANKI_CONFIG_VAR_U32(SceneMinGpuSceneDecals, 2 * 1024, 8, 100 * 1024, "The min number of decals stored in the GPU scene")
+ANKI_CONFIG_VAR_U32(SceneMinGpuSceneFogDensityVolumes, 512, 8, 100 * 1024,
+					"The min number fog density volumes stored in the GPU scene")

+ 4 - 2
AnKi/Scene/ContiguousArrayAllocator.cpp

@@ -114,8 +114,10 @@ void AllGpuSceneContiguousArrays::init(SceneGraph* scene)
 	constexpr F32 kGrowRate = 2.0;
 
 	const Array<U32, U32(GpuSceneContiguousArrayType::kCount)> minElementCount = {
-		cfg.getSceneMinGpuSceneTransforms(), cfg.getSceneMinGpuSceneMeshes(), cfg.getSceneMinGpuSceneParticleEmitters(),
-		cfg.getSceneMinGpuSceneLights()};
+		cfg.getSceneMinGpuSceneTransforms(),       cfg.getSceneMinGpuSceneMeshes(),
+		cfg.getSceneMinGpuSceneParticleEmitters(), cfg.getSceneMinGpuSceneLights(),
+		cfg.getSceneMinGpuSceneReflectionProbes(), cfg.getSceneMinGpuSceneGlobalIlluminationProbes(),
+		cfg.getSceneMinGpuSceneDecals(),           cfg.getSceneMinGpuSceneFogDensityVolumes()};
 
 	for(GpuSceneContiguousArrayType type : EnumIterable<GpuSceneContiguousArrayType>())
 	{

+ 14 - 3
AnKi/Scene/ContiguousArrayAllocator.h

@@ -19,6 +19,10 @@ enum class GpuSceneContiguousArrayType : U8
 	kMeshLods,
 	kParticleEmitters,
 	kLights,
+	kReflectionProbes,
+	kGlobalIlluminationProbes,
+	kDecals,
+	kFogDensityVolumes,
 
 	kCount,
 	kFirst = 0
@@ -105,10 +109,17 @@ private:
 
 	U8 m_frame = 0;
 
-	static constexpr Array<U8, U32(GpuSceneContiguousArrayType::kCount)> m_componentCount = {2, kMaxLodCount, 1, 1};
+	static constexpr Array<U8, U32(GpuSceneContiguousArrayType::kCount)> m_componentCount = {
+		2, kMaxLodCount, 1, 1, 1, 1, 1, 1};
 	static constexpr Array<U8, U32(GpuSceneContiguousArrayType::kCount)> m_componentSize = {
-		sizeof(Mat3x4), sizeof(GpuSceneMeshLod), sizeof(GpuSceneParticleEmitter),
-		max<U8>(sizeof(GpuScenePointLight), sizeof(GpuSceneSpotLight))};
+		sizeof(Mat3x4),
+		sizeof(GpuSceneMeshLod),
+		sizeof(GpuSceneParticleEmitter),
+		max<U8>(sizeof(GpuScenePointLight), sizeof(GpuSceneSpotLight)),
+		sizeof(GpuSceneReflectionProbe),
+		sizeof(GpuSceneGlobalIlluminationProbe),
+		sizeof(GpuSceneDecal),
+		sizeof(GpuSceneFogDensityVolume)};
 };
 /// @}
 

+ 63 - 0
AnKi/Shaders/Include/GpuSceneTypes.h

@@ -81,4 +81,67 @@ struct GpuSceneSpotLight
 constexpr U32 kSizeof_GpuSceneSpotLight = 12u * sizeof(Vec4);
 static_assert(sizeof(GpuSceneSpotLight) == kSizeof_GpuSceneSpotLight);
 
+/// Representation of a reflection probe.
+struct GpuSceneReflectionProbe
+{
+	Vec3 m_position; ///< Position of the probe in world space.
+	F32 m_cubemapIndex; ///< Index in the cubemap array texture.
+
+	Vec3 m_aabbMin;
+	F32 m_padding0;
+
+	Vec3 m_aabbMax;
+	F32 m_padding1;
+};
+constexpr U32 kSizeof_GpuSceneReflectionProbe = 3u * sizeof(Vec4);
+static_assert(sizeof(GpuSceneReflectionProbe) == kSizeof_GpuSceneReflectionProbe);
+
+/// Global illumination probe
+struct GpuSceneGlobalIlluminationProbe
+{
+	Vec3 m_aabbMin;
+	F32 m_padding0;
+
+	Vec3 m_aabbMax;
+	F32 m_padding1;
+
+	U32 m_textureIndex; ///< Index to the array of volume textures.
+	F32 m_halfTexelSizeU; ///< (1.0 / textureSize(texArr[textureIndex]).x) / 2.0
+	/// Used to calculate a factor that is zero when fragPos is close to AABB bounds and 1.0 at fadeDistance and less.
+	RF32 m_fadeDistance;
+	F32 m_padding2;
+};
+constexpr U32 kSizeof_GpuSceneGlobalIlluminationProbe = 3u * sizeof(Vec4);
+static_assert(sizeof(GpuSceneGlobalIlluminationProbe) == kSizeof_GpuSceneGlobalIlluminationProbe);
+
+/// Decal.
+struct GpuSceneDecal
+{
+	U32 m_diffuseTexture;
+	U32 m_roughnessMetalnessTexture;
+	RF32 m_diffuseBlendFactor;
+	RF32 m_roughnessMetalnessFactor;
+
+	Mat4 m_textureMatrix;
+
+	Mat4 m_invertedTransform;
+
+	Vec3 m_obbExtend;
+	F32 m_padding0;
+};
+constexpr U32 kSizeof_GpuSceneDecal = 2u * sizeof(Vec4) + 2u * sizeof(Mat4);
+static_assert(sizeof(GpuSceneDecal) == kSizeof_GpuSceneDecal);
+
+/// Fog density volume.
+struct GpuSceneFogDensityVolume
+{
+	Vec3 m_aabbMinOrSphereCenter;
+	U32 m_isBox;
+
+	Vec3 m_aabbMaxOrSphereRadiusSquared;
+	RF32 m_density;
+};
+constexpr U32 kSizeof_GpuSceneFogDensityVolume = 2u * sizeof(Vec4);
+static_assert(sizeof(GpuSceneFogDensityVolume) == kSizeof_GpuSceneFogDensityVolume);
+
 ANKI_END_NAMESPACE