Bladeren bron

Some reflection probe work

Panagiotis Christopoulos Charitos 10 jaren geleden
bovenliggende
commit
fbca51a5b6

+ 1 - 3
include/anki/Scene.h

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_SCENE_SCENE_H
-#define ANKI_SCENE_SCENE_H
+#pragma once
 
 #include "anki/scene/SceneGraph.h"
 #include "anki/scene/LensFlareComponent.h"
@@ -20,4 +19,3 @@
 #include "anki/scene/StaticCollisionNode.h"
 #include "anki/scene/BodyNode.h"
 
-#endif

+ 6 - 4
include/anki/scene/FrustumComponent.h

@@ -38,12 +38,14 @@ public:
 		TEST_LIGHT_COMPONENTS = 1 << 1,
 		TEST_LENS_FLARE_COMPONENTS = 1 << 2,
 		TEST_SHADOW_CASTERS = 1 << 3,
+		TEST_REFLECTION_PROBES = 1 << 4,
 
 		ALL_TESTS =
-			VisibilityTestFlag::TEST_RENDER_COMPONENTS
-			| VisibilityTestFlag::TEST_LIGHT_COMPONENTS
-			| VisibilityTestFlag::TEST_LENS_FLARE_COMPONENTS
-			| VisibilityTestFlag::TEST_SHADOW_CASTERS
+			TEST_RENDER_COMPONENTS
+			| TEST_LIGHT_COMPONENTS
+			| TEST_LENS_FLARE_COMPONENTS
+			| TEST_SHADOW_CASTERS
+			| TEST_REFLECTION_PROBES
 	};
 	ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(VisibilityTestFlag, friend)
 

+ 13 - 8
include/anki/scene/ReflectionProbe.h

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_SCENE_REFLECTION_PROBE_H
-#define ANKI_SCENE_REFLECTION_PROBE_H
+#pragma once
 
 #include "anki/scene/SceneNode.h"
 #include "anki/collision/Frustum.h"
@@ -36,6 +35,8 @@ class ReflectionProbe: public SceneNode
 	friend class ReflectionProbeMoveFeedbackComponent;
 
 public:
+	const F32 FRUSTUM_NEAR_PLANE = 0.1 / 4.0;
+
 	ReflectionProbe(SceneGraph* scene)
 		: SceneNode(scene)
 	{}
@@ -45,12 +46,18 @@ public:
 	ANKI_USE_RESULT Error create(const CString& name, F32 radius);
 
 private:
-	Array<PerspectiveFrustum, 6> m_frustums;
+	class CubeSide
+	{
+	public:
+		PerspectiveFrustum m_frustum;
+		Transform m_localTrf;
+		FramebufferPtr m_fb;
+	};
+
+	Array<CubeSide, 6> m_cubeSides;
+
 	TexturePtr m_colorTex;
-	TexturePtr m_depthTex;
-	Array<FramebufferPtr, 6> m_fbs;
 	U32 m_fbSize = 128;
-	Array<Transform, 6> m_localFrustumTrfs;
 	Sphere m_spatialSphere;
 
 	void onMoveUpdate(MoveComponent& move);
@@ -61,5 +68,3 @@ private:
 
 } // end namespace anki
 
-#endif
-

+ 0 - 1
include/anki/scene/SceneComponent.h

@@ -28,7 +28,6 @@ public:
 		RENDER,
 		SPATIAL,
 		LIGHT,
-		INSTANCE,
 		LENS_FLARE,
 		BODY,
 		SECTOR_PORTAL,

+ 68 - 38
include/anki/scene/Visibility.h

@@ -5,12 +5,12 @@
 
 #pragma once
 
-#include "anki/scene/Common.h"
-#include "anki/collision/Forward.h"
-#include "anki/scene/SceneNode.h"
-#include "anki/scene/SpatialComponent.h"
-#include "anki/scene/RenderComponent.h"
-#include "anki/util/NonCopyable.h"
+#include <anki/scene/Common.h>
+#include <anki/collision/Forward.h>
+#include <anki/scene/SceneNode.h>
+#include <anki/scene/SpatialComponent.h>
+#include <anki/scene/RenderComponent.h>
+#include <anki/util/NonCopyable.h>
 
 namespace anki {
 
@@ -73,8 +73,6 @@ public:
 class VisibilityTestResults
 {
 public:
-	using Container = DArray<VisibleNode>;
-
 	~VisibilityTestResults()
 	{
 		ANKI_ASSERT(0 && "It's supposed to be deallocated on frame start");
@@ -86,75 +84,95 @@ public:
 		U32 lightsReservedSize,
 		U32 lensFlaresReservedSize);
 
-	void prepareMerge()
-	{
-		ANKI_ASSERT(m_renderablesCount == 0
-			&& m_lightsCount == 0
-			&& m_flaresCount == 0);
-		m_renderablesCount = m_renderables.getSize();
-		m_lightsCount = m_lights.getSize();
-		m_flaresCount = m_flares.getSize();
-	}
+	void prepareMerge();
 
 	VisibleNode* getRenderablesBegin()
 	{
-		return (m_renderablesCount) ? &m_renderables[0] : nullptr;
+		return (getRenderablesCount())
+			? &m_groups[RENDERABLES].m_nodes[0] : nullptr;
 	}
 
 	VisibleNode* getRenderablesEnd()
 	{
-		return (m_renderablesCount)
-			? (&m_renderables[0] + m_renderablesCount) : nullptr;
+		return (getRenderablesCount())
+			? (&m_groups[RENDERABLES].m_nodes[0] + getRenderablesCount())
+			: nullptr;
 	}
 
 	VisibleNode* getLightsBegin()
 	{
-		return (m_lightsCount) ? &m_lights[0] : nullptr;
+		return (getLightsCount()) ? &m_groups[LIGHTS].m_nodes[0] : nullptr;
 	}
 
 	VisibleNode* getLightsEnd()
 	{
-		return (m_lightsCount) ? (&m_lights[0] + m_lightsCount) : nullptr;
+		return (getLightsCount())
+			? (&m_groups[LIGHTS].m_nodes[0] + getLightsCount()) : nullptr;
 	}
 
 	VisibleNode* getLensFlaresBegin()
 	{
-		return (m_flaresCount) ? &m_flares[0] : nullptr;
+		return (getLensFlaresCount()) ? &m_groups[FLARES].m_nodes[0] : nullptr;
 	}
 
 	VisibleNode* getLensFlaresEnd()
 	{
-		return (m_flaresCount) ? (&m_flares[0] + m_flaresCount) : nullptr;
+		return (getLensFlaresCount())
+			? (&m_groups[FLARES].m_nodes[0] + getLightsCount()) : nullptr;
+	}
+
+	VisibleNode* getReflectionProbesBegin()
+	{
+		return (getReflectionProbeCount())
+			? &m_groups[REFLECTION_PROBES].m_nodes[0] : nullptr;
+	}
+
+	VisibleNode* getReflectionProbesEnd()
+	{
+		return (getReflectionProbeCount())
+			? (&m_groups[REFLECTION_PROBES].m_nodes[0]
+			+ getReflectionProbeCount())
+			: nullptr;
 	}
 
 	U32 getRenderablesCount() const
 	{
-		return m_renderablesCount;
+		return m_groups[RENDERABLES].m_count;
 	}
 
 	U32 getLightsCount() const
 	{
-		return m_lightsCount;
+		return m_groups[LIGHTS].m_count;
 	}
 
 	U32 getLensFlaresCount() const
 	{
-		return m_flaresCount;
+		return m_groups[FLARES].m_count;
+	}
+
+	U32 getReflectionProbeCount() const
+	{
+		return m_groups[REFLECTION_PROBES].m_count;
 	}
 
 	void moveBackRenderable(SceneFrameAllocator<U8> alloc, VisibleNode& x)
 	{
-		moveBack(alloc, m_renderables, m_renderablesCount, x);
+		moveBack(alloc, RENDERABLES, x);
 	}
 
 	void moveBackLight(SceneFrameAllocator<U8> alloc, VisibleNode& x)
 	{
-		moveBack(alloc, m_lights, m_lightsCount, x);
+		moveBack(alloc, LIGHTS, x);
 	}
 
 	void moveBackLensFlare(SceneFrameAllocator<U8> alloc, VisibleNode& x)
 	{
-		moveBack(alloc, m_flares, m_flaresCount, x);
+		moveBack(alloc, FLARES, x);
+	}
+
+	void moveBackReflectionProbe(SceneFrameAllocator<U8> alloc, VisibleNode& x)
+	{
+		moveBack(alloc, REFLECTION_PROBES, x);
 	}
 
 	Timestamp getShapeUpdateTimestamp() const
@@ -168,17 +186,29 @@ public:
 	}
 
 private:
-	Container m_renderables;
-	Container m_lights;
-	Container m_flares;
-	U32 m_renderablesCount = 0;
-	U32 m_lightsCount = 0;
-	U32 m_flaresCount = 0;
+	using Container = DArray<VisibleNode>;
+
+	enum GroupType
+	{
+		RENDERABLES,
+		LIGHTS,
+		FLARES,
+		REFLECTION_PROBES,
+		TYPE_COUNT
+	};
+
+	class Group
+	{
+	public:
+		Container m_nodes;
+		U32 m_count = 0;
+	};
+
+	Array<Group, TYPE_COUNT> m_groups;
 
 	Timestamp m_shapeUpdateTimestamp = 0;
 
-	void moveBack(SceneFrameAllocator<U8> alloc,
-		Container& c, U32& count, VisibleNode& x);
+	void moveBack(SceneFrameAllocator<U8> alloc, GroupType, VisibleNode& x);
 };
 
 /// Do visibility tests bypassing portals

+ 2 - 2
src/renderer/Is.cpp

@@ -147,8 +147,8 @@ public:
 	Atomic<U32> m_lightIdsCount = {0};
 
 	// Misc
-	VisibilityTestResults::Container::ConstIterator m_lightsBegin = nullptr;
-	VisibilityTestResults::Container::ConstIterator m_lightsEnd = nullptr;
+	const VisibleNode* m_lightsBegin = nullptr;
+	const VisibleNode* m_lightsEnd = nullptr;
 
 	Is* m_is = nullptr;
 };

+ 2 - 1
src/scene/Camera.cpp

@@ -94,7 +94,8 @@ Error Camera::create(const CString& name, Frustum* frustum)
 	frc->setEnabledVisibilityTests(
 		FrustumComponent::VisibilityTestFlag::TEST_RENDER_COMPONENTS
 		| FrustumComponent::VisibilityTestFlag::TEST_LIGHT_COMPONENTS
-		| FrustumComponent::VisibilityTestFlag::TEST_LENS_FLARE_COMPONENTS);
+		| FrustumComponent::VisibilityTestFlag::TEST_LENS_FLARE_COMPONENTS
+		| FrustumComponent::VisibilityTestFlag::TEST_REFLECTION_PROBES);
 	addComponent(frc, true);
 
 	// Feedback component #2

+ 1 - 3
src/scene/Light.cpp

@@ -200,9 +200,7 @@ void PointLight::onMoveUpdate(MoveComponent& move)
 		[&](FrustumComponent& fr) -> Error
 	{
 		Transform trf = m_shadowData[count].m_localTrf;
-		trf.setOrigin(
-			move.getWorldTransform().getOrigin()
-			+ m_shadowData[count].m_localTrf.getOrigin());
+		trf.setOrigin(move.getWorldTransform().getOrigin());
 
 		fr.getFrustum().resetTransform(trf);
 		fr.markTransformForUpdate();

+ 36 - 31
src/scene/ReflectionProbe.cpp

@@ -3,10 +3,12 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#include "anki/scene/ReflectionProbe.h"
-#include "anki/scene/MoveComponent.h"
-#include "anki/scene/FrustumComponent.h"
-#include "anki/scene/SceneGraph.h"
+#include <anki/scene/ReflectionProbe.h>
+#include <anki/scene/MoveComponent.h>
+#include <anki/scene/FrustumComponent.h>
+#include <anki/scene/SceneGraph.h>
+#include <anki/scene/SceneGraph.h>
+#include <anki/renderer/Is.h>
 
 namespace anki {
 
@@ -59,35 +61,47 @@ Error ReflectionProbe::create(const CString& name, F32 radius)
 	addComponent(comp, true);
 
 	// The frustum components
-	Array<Transform, 6>& trfs = m_localFrustumTrfs;
-	const F32 PI_2 = toRad(90.0);
-	const F32 PI = toRad(180.0);
-	trfs[0] = Transform(Vec4(0.0), Mat3x4(Euler(0.0, -PI_2, 0.0)), 1.0);
-	trfs[1] = Transform(Vec4(0.0), Mat3x4(Euler(PI_2, 0.0, 0.0)), 1.0);
-	trfs[2] = Transform(Vec4(0.0), Mat3x4(Euler(0.0, PI, 0.0)), 1.0);
-	trfs[3] = Transform(Vec4(0.0), Mat3x4(Euler(0.0, PI_2, 0.0)), 1.0);
-	trfs[4] = Transform(Vec4(0.0), Mat3x4(Euler(-PI_2, 0.0, 0.0)), 1.0);
-	trfs[5] = Transform(Vec4(0.0), Mat3x4::getIdentity(), 1.0);
+	const F32 ang = toRad(90.0);
+	const F32 zNear = FRUSTUM_NEAR_PLANE;
+
+	Mat3 rot;
+	const F32 PI = getPi<F32>();
+
+	rot = Mat3(Euler(0.0, -PI / 2.0, 0.0)) * Mat3(Euler(0.0, 0.0, PI));
+	m_cubeSides[0].m_localTrf.setRotation(Mat3x4(rot));
+	rot = Mat3(Euler(0.0, PI / 2.0, 0.0)) * Mat3(Euler(0.0, 0.0, PI));
+	m_cubeSides[1].m_localTrf.setRotation(Mat3x4(rot));
+	rot = Mat3(Euler(PI / 2.0, 0.0, 0.0));
+	m_cubeSides[2].m_localTrf.setRotation(Mat3x4(rot));
+	rot = Mat3(Euler(-PI / 2.0, 0.0, 0.0));
+	m_cubeSides[3].m_localTrf.setRotation(Mat3x4(rot));
+	rot = Mat3(Euler(0.0, PI, 0.0)) * Mat3(Euler(0.0, 0.0, PI));
+	m_cubeSides[4].m_localTrf.setRotation(Mat3x4(rot));
+	rot = Mat3(Euler(0.0, 0.0, PI));
+	m_cubeSides[5].m_localTrf.setRotation(Mat3x4(rot));
 
 	for(U i = 0; i < 6; ++i)
 	{
+		m_cubeSides[i].m_localTrf.setOrigin(Vec4(0.0));
+		m_cubeSides[i].m_localTrf.setScale(1.0);
+
+		m_cubeSides[i].m_frustum.setAll(ang, ang, zNear, radius);
+		m_cubeSides[i].m_frustum.resetTransform(m_cubeSides[i].m_localTrf);
+
 		FrustumComponent* frc =
 			getSceneAllocator().newInstance<FrustumComponent>(
-			this, &m_frustums[i]);
+			this, &m_cubeSides[i].m_frustum);
 
 		frc->setEnabledVisibilityTests(
 			FrustumComponent::VisibilityTestFlag::TEST_RENDER_COMPONENTS
 			| FrustumComponent::VisibilityTestFlag::TEST_LIGHT_COMPONENTS);
 
 		addComponent(frc, true);
-
-		m_frustums[i].setAll(toRad(90.0), toRad(90.0), 0.5, radius);
-		m_frustums[i].resetTransform(trfs[i]);
 	}
 
 	// Spatial component
 	m_spatialSphere.setCenter(Vec4(0.0));
-	m_spatialSphere.setRadius(0.1);
+	m_spatialSphere.setRadius(radius);
 	comp = getSceneAllocator().newInstance<SpatialComponent>(
 		this, &m_spatialSphere);
 
@@ -108,15 +122,11 @@ void ReflectionProbe::createGraphics()
 	TextureInitializer init;
 	init.m_type = TextureType::CUBE;
 	init.m_width = init.m_height = m_fbSize;
-	init.m_format =
-		PixelFormat(ComponentFormat::R8G8B8, TransformFormat::UNORM);
+	init.m_format = Is::RT_PIXEL_FORMAT;
 	init.m_sampling.m_minMagFilter = SamplingFilter::LINEAR;
 
 	m_colorTex = getSceneGraph().getGrManager().newInstance<Texture>(init);
 
-	init.m_format = PixelFormat(ComponentFormat::D16, TransformFormat::FLOAT);
-	m_depthTex = getSceneGraph().getGrManager().newInstance<Texture>(init);
-
 	// Create framebuffers
 	for(U i = 0; i < 6; ++i)
 	{
@@ -127,11 +137,7 @@ void ReflectionProbe::createGraphics()
 		fbInit.m_colorAttachments[0].m_loadOperation =
 			AttachmentLoadOperation::DONT_CARE;
 
-		fbInit.m_depthStencilAttachment.m_texture = m_depthTex;
-		fbInit.m_depthStencilAttachment.m_loadOperation =
-			AttachmentLoadOperation::CLEAR;
-
-		m_fbs[i] =
+		m_cubeSides[i].m_fb =
 			getSceneGraph().getGrManager().newInstance<Framebuffer>(fbInit);
 	}
 }
@@ -144,11 +150,10 @@ void ReflectionProbe::onMoveUpdate(MoveComponent& move)
 	Error err = iterateComponentsOfType<FrustumComponent>(
 		[&](FrustumComponent& frc) -> Error
 	{
-		Transform trf = m_localFrustumTrfs[count].combineTransformations(
-			move.getWorldTransform());
+		Transform trf = m_cubeSides[count].m_localTrf;
+		trf.setOrigin(move.getWorldTransform().getOrigin());
 
 		frc.getFrustum().resetTransform(trf);
-
 		frc.markTransformForUpdate();
 		++count;
 

+ 48 - 18
src/scene/Visibility.cpp

@@ -3,15 +3,16 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#include "anki/scene/Visibility.h"
-#include "anki/scene/SceneGraph.h"
-#include "anki/scene/Sector.h"
-#include "anki/scene/FrustumComponent.h"
-#include "anki/scene/LensFlareComponent.h"
-#include "anki/scene/Light.h"
-#include "anki/scene/MoveComponent.h"
-#include "anki/renderer/MainRenderer.h"
-#include "anki/util/Logger.h"
+#include <anki/scene/Visibility.h>
+#include <anki/scene/SceneGraph.h>
+#include <anki/scene/Sector.h>
+#include <anki/scene/FrustumComponent.h>
+#include <anki/scene/LensFlareComponent.h>
+#include <anki/scene/ReflectionProbe.h>
+#include <anki/scene/Light.h>
+#include <anki/scene/MoveComponent.h>
+#include <anki/renderer/MainRenderer.h>
+#include <anki/util/Logger.h>
 
 namespace anki {
 
@@ -175,6 +176,9 @@ void VisibilityTestTask::test(FrustumComponent& testedFrc,
 	Bool wantsShadowCasters = testedFrc.visibilityTestsEnabled(
 		FrustumComponent::VisibilityTestFlag::TEST_SHADOW_CASTERS);
 
+	Bool wantsReflectionProbes = testedFrc.visibilityTestsEnabled(
+		FrustumComponent::VisibilityTestFlag::TEST_REFLECTION_PROBES);
+
 #if 0
 	ANKI_LOGW("Running test code");
 
@@ -235,6 +239,13 @@ void VisibilityTestTask::test(FrustumComponent& testedFrc,
 			wantNode = true;
 		}
 
+		ReflectionProbeComponent* reflc =
+			node.tryGetComponent<ReflectionProbeComponent>();
+		if(reflc && wantsReflectionProbes)
+		{
+			wantNode = true;
+		}
+
 		if(ANKI_UNLIKELY(!wantNode))
 		{
 			// Skip node
@@ -325,6 +336,11 @@ void VisibilityTestTask::test(FrustumComponent& testedFrc,
 			visible->moveBackLensFlare(alloc, visibleNode);
 		}
 
+		if(reflc && wantsReflectionProbes)
+		{
+			visible->moveBackReflectionProbe(alloc, visibleNode);
+		}
+
 		// Add more frustums to the list
 		err = node.iterateComponentsOfType<FrustumComponent>(
 			[&](FrustumComponent& frc)
@@ -455,23 +471,37 @@ void VisibilityTestResults::create(
 	U32 lightsReservedSize,
 	U32 lensFlaresReservedSize)
 {
-	m_renderables.create(alloc, renderablesReservedSize);
-	m_lights.create(alloc, lightsReservedSize);
-	m_flares.create(alloc, lensFlaresReservedSize);
+	m_groups[RENDERABLES].m_nodes.create(alloc, renderablesReservedSize);
+	m_groups[LIGHTS].m_nodes.create(alloc, lightsReservedSize);
+	m_groups[FLARES].m_nodes.create(alloc, lensFlaresReservedSize);
 }
 
 //==============================================================================
-void VisibilityTestResults::moveBack(
-	SceneFrameAllocator<U8> alloc, Container& c, U32& count, VisibleNode& x)
+void VisibilityTestResults::moveBack(SceneFrameAllocator<U8> alloc,
+	GroupType type, VisibleNode& x)
 {
-	if(count + 1 > c.getSize())
+	Group& group = m_groups[type];
+	if(group.m_count + 1 > group.m_nodes.getSize())
 	{
 		// Need to grow
-		U newSize = (c.getSize() != 0) ? c.getSize() * 2 : 2;
-		c.resize(alloc, newSize);
+		U newSize = (group.m_nodes.getSize() != 0)
+			? group.m_nodes.getSize() * 2
+			: 2;
+		group.m_nodes.resize(alloc, newSize);
 	}
 
-	c[count++] = x;
+	group.m_nodes[group.m_count++] = x;
+}
+
+//==============================================================================
+void VisibilityTestResults::prepareMerge()
+{
+	for(U i = 0; i < TYPE_COUNT; ++i)
+	{
+		Group& group = m_groups[i];
+		ANKI_ASSERT(group.m_count == 0);
+		group.m_count = group.m_nodes.getSize();
+	}
 }
 
 //==============================================================================