Browse Source

Some refactoring & avoid particle self-collision

Panagiotis Christopoulos Charitos 6 years ago
parent
commit
9b75ff8054

+ 19 - 0
shaders/LightFunctions.glsl

@@ -162,7 +162,26 @@ F32 computeShadowFactorPointLight(PointLight light, Vec3 frag2Light, texture2D s
 F32 computeShadowFactorDirLight(
 	DirectionalLight light, U32 cascadeIdx, Vec3 worldPos, texture2D shadowMap, sampler shadowMapSampler)
 {
+#if defined(ANKI_VENDOR_NVIDIA)
+	// Assumes MAX_SHADOW_CASCADES is 4
+	Mat4 lightProjectionMat;
+	switch(cascadeIdx)
+	{
+	case 0:
+		lightProjectionMat = light.m_textureMatrices[0];
+		break;
+	case 1:
+		lightProjectionMat = light.m_textureMatrices[1];
+		break;
+	case 2:
+		lightProjectionMat = light.m_textureMatrices[2];
+		break;
+	default:
+		lightProjectionMat = light.m_textureMatrices[3];
+	}
+#else
 	const Mat4 lightProjectionMat = light.m_textureMatrices[cascadeIdx];
+#endif
 
 	const Vec4 texCoords4 = lightProjectionMat * Vec4(worldPos, 1.0);
 	const Vec3 texCoords3 = texCoords4.xyz / texCoords4.w;

+ 12 - 25
src/anki/scene/GpuParticleEmitterNode.cpp

@@ -38,20 +38,6 @@ public:
 	}
 };
 
-class GpuParticleEmitterNode::MyRenderComponent : public MaterialRenderComponent
-{
-public:
-	MyRenderComponent(SceneNode* node)
-		: MaterialRenderComponent(node, static_cast<GpuParticleEmitterNode*>(node)->m_emitterRsrc->getMaterial())
-	{
-	}
-
-	void setupRenderableQueueElement(RenderableQueueElement& el) const override
-	{
-		static_cast<const GpuParticleEmitterNode&>(getSceneNode()).setupRenderableQueueElement(el);
-	}
-};
-
 GpuParticleEmitterNode::GpuParticleEmitterNode(SceneGraph* scene, CString name)
 	: SceneNode(scene, name)
 {
@@ -163,7 +149,16 @@ Error GpuParticleEmitterNode::init(const CString& filename)
 			static_cast<const GpuParticleEmitterNode*>(userData)->simulate(ctx);
 		},
 		this);
-	newComponent<MyRenderComponent>(this);
+	MaterialRenderComponent* rcomp = newComponent<MaterialRenderComponent>(this, m_emitterRsrc->getMaterial());
+	rcomp->setup(
+		[](RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData) {
+			ANKI_ASSERT(userData.getSize() == 1);
+			static_cast<const GpuParticleEmitterNode*>(userData[0])->draw(ctx);
+		},
+		this,
+		0 // No merging
+	);
+	rcomp->setFlags(rcomp->getFlags() | RenderComponentFlag::SORT_LAST);
 
 	return Error::NONE;
 }
@@ -214,16 +209,6 @@ void GpuParticleEmitterNode::simulate(GenericGpuComputeJobQueueElementContext& c
 	cmdb->dispatchCompute(workgroupCount, 1, 1);
 }
 
-void GpuParticleEmitterNode::setupRenderableQueueElement(RenderableQueueElement& el) const
-{
-	el.m_callback = [](RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData) {
-		ANKI_ASSERT(userData.getSize() == 1);
-		static_cast<const GpuParticleEmitterNode*>(userData[0])->draw(ctx);
-	};
-	el.m_mergeKey = 0; // No merging
-	el.m_userData = this;
-}
-
 void GpuParticleEmitterNode::draw(RenderQueueDrawContext& ctx) const
 {
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
@@ -252,7 +237,9 @@ void GpuParticleEmitterNode::draw(RenderQueueDrawContext& ctx) const
 
 		// Draw
 		cmdb->setLineWidth(8.0f);
+		cmdb->setDepthWrite(false);
 		cmdb->drawArrays(PrimitiveTopology::LINES, m_particleCount * 2);
+		cmdb->setDepthWrite(true);
 	}
 	else
 	{

+ 0 - 3
src/anki/scene/GpuParticleEmitterNode.h

@@ -41,7 +41,6 @@ private:
 	static constexpr U MAX_RAND_FACTORS = 32;
 
 	class MoveFeedbackComponent;
-	class MyRenderComponent;
 
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramPtr m_grProg;
@@ -65,8 +64,6 @@ private:
 
 	void simulate(GenericGpuComputeJobQueueElementContext& ctx) const;
 
-	void setupRenderableQueueElement(RenderableQueueElement& el) const;
-
 	void draw(RenderQueueDrawContext& ctx) const;
 };
 /// @}

+ 9 - 15
src/anki/scene/ModelNode.cpp

@@ -41,20 +41,6 @@ public:
 	}
 };
 
-class ModelNode::MyRenderComponent : public MaterialRenderComponent
-{
-public:
-	MyRenderComponent(ModelNode* node)
-		: MaterialRenderComponent(node, node->m_model->getModelPatches()[node->m_modelPatchIdx]->getMaterial())
-	{
-	}
-
-	void setupRenderableQueueElement(RenderableQueueElement& el) const override
-	{
-		static_cast<const ModelNode&>(getSceneNode()).setupRenderableQueueElement(el);
-	}
-};
-
 ModelNode::ModelNode(SceneGraph* scene, CString name)
 	: SceneNode(scene, name)
 {
@@ -86,7 +72,15 @@ Error ModelNode::init(ModelResourcePtr resource, U32 modelPatchIdx)
 	newComponent<MoveComponent>();
 	newComponent<MoveFeedbackComponent>();
 	newComponent<SpatialComponent>(this, &m_obb);
-	newComponent<MyRenderComponent>(this);
+	MaterialRenderComponent* rcomp =
+		newComponent<MaterialRenderComponent>(this, m_model->getModelPatches()[m_modelPatchIdx]->getMaterial());
+	rcomp->setup(
+		[](RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData) {
+			const ModelNode& self = *static_cast<const ModelNode*>(userData[0]);
+			self.draw(ctx, userData);
+		},
+		this,
+		m_mergeKey);
 
 	return Error::NONE;
 }

+ 0 - 14
src/anki/scene/ModelNode.h

@@ -39,7 +39,6 @@ public:
 
 private:
 	class MoveFeedbackComponent;
-	class MyRenderComponent;
 
 	ModelResourcePtr m_model; ///< The resource
 
@@ -52,19 +51,6 @@ private:
 	void onMoveComponentUpdate(const MoveComponent& move);
 
 	void draw(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData) const;
-
-	static void drawCallback(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData)
-	{
-		const ModelNode& self = *static_cast<const ModelNode*>(userData[0]);
-		self.draw(ctx, userData);
-	}
-
-	void setupRenderableQueueElement(RenderableQueueElement& el) const
-	{
-		el.m_callback = drawCallback;
-		el.m_userData = this;
-		el.m_mergeKey = m_mergeKey;
-	}
 };
 /// @}
 

+ 3 - 17
src/anki/scene/ParticleEmitterNode.cpp

@@ -204,22 +204,6 @@ public:
 	}
 };
 
-/// The derived render component for particle emitters.
-class ParticleEmitterNode::MyRenderComponent : public MaterialRenderComponent
-{
-public:
-	MyRenderComponent(SceneNode* node)
-		: MaterialRenderComponent(
-			  node, static_cast<ParticleEmitterNode*>(node)->m_particleEmitterResource->getMaterial())
-	{
-	}
-
-	void setupRenderableQueueElement(RenderableQueueElement& el) const override
-	{
-		static_cast<const ParticleEmitterNode&>(getSceneNode()).setupRenderableQueueElement(el);
-	}
-};
-
 /// Feedback component
 class ParticleEmitterNode::MoveFeedbackComponent : public SceneComponent
 {
@@ -274,7 +258,9 @@ Error ParticleEmitterNode::init(const CString& filename)
 	newComponent<SpatialComponent>(this, &m_obb);
 
 	// Render component
-	newComponent<MyRenderComponent>(this);
+	MaterialRenderComponent* rcomp =
+		newComponent<MaterialRenderComponent>(this, m_particleEmitterResource->getMaterial());
+	rcomp->setup(drawCallback, this, 0); // No merging
 
 	// Other
 	m_obb.setCenter(Vec4(0.0));

+ 0 - 8
src/anki/scene/ParticleEmitterNode.h

@@ -33,7 +33,6 @@ public:
 	/// @}
 
 private:
-	class MyRenderComponent;
 	class MoveFeedbackComponent;
 	class ParticleBase;
 	class ParticleSimple;
@@ -72,13 +71,6 @@ private:
 
 	void onMoveComponentUpdate(MoveComponent& move);
 
-	void setupRenderableQueueElement(RenderableQueueElement& el) const
-	{
-		el.m_callback = drawCallback;
-		el.m_mergeKey = 0;
-		el.m_userData = this;
-	}
-
 	static void drawCallback(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData);
 };
 /// @}

+ 5 - 15
src/anki/scene/PhysicsDebugNode.cpp

@@ -26,8 +26,11 @@ public:
 		, m_physDbgDrawer(&m_dbgDrawer)
 	{
 		ANKI_ASSERT(node);
-		m_castsShadow = false;
-		m_isForwardShading = false;
+		setFlags(RenderComponentFlag::NONE);
+		setup([](RenderQueueDrawContext& ctx,
+				  ConstWeakArray<void*> userData) { static_cast<MyRenderComponent*>(userData[0])->draw(ctx); },
+			this,
+			0);
 	}
 
 	ANKI_USE_RESULT Error init()
@@ -35,19 +38,6 @@ public:
 		return m_dbgDrawer.init(&m_node->getSceneGraph().getResourceManager());
 	}
 
-	void setupRenderableQueueElement(RenderableQueueElement& el) const override
-	{
-		el.m_callback = drawCallback;
-		el.m_mergeKey = 1;
-		el.m_userData = this;
-	}
-
-	/// RenderableQueueElement draw callback.
-	static void drawCallback(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData)
-	{
-		static_cast<MyRenderComponent*>(userData[0])->draw(ctx);
-	}
-
 	/// Draw the world.
 	void draw(RenderQueueDrawContext& ctx)
 	{

+ 2 - 16
src/anki/scene/StaticGeometryNode.cpp

@@ -11,21 +11,6 @@
 namespace anki
 {
 
-/// The implementation of static geometry node renderable component.
-class StaticGeometryPatchNode::RenderComponent : public MaterialRenderComponent
-{
-public:
-	RenderComponent(SceneNode* node)
-		: MaterialRenderComponent(node, static_cast<StaticGeometryPatchNode*>(node)->m_modelPatch->getMaterial())
-	{
-	}
-
-	void setupRenderableQueueElement(RenderableQueueElement& el) const override
-	{
-		ANKI_ASSERT(!"TODO");
-	}
-};
-
 StaticGeometryPatchNode::StaticGeometryPatchNode(SceneGraph* scene, CString name)
 	: SceneNode(scene, name)
 {
@@ -50,7 +35,8 @@ Error StaticGeometryPatchNode::init(const ModelPatch* modelPatch)
 	}
 
 	// Create render component
-	newComponent<RenderComponent>(this);
+	MaterialRenderComponent* rcomp = newComponent<MaterialRenderComponent>(this, m_modelPatch->getMaterial());
+	rcomp->setup([](RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData) { ANKI_ASSERT(!"TODO"); }, this, 0);
 
 	return Error::NONE;
 }

+ 0 - 2
src/anki/scene/StaticGeometryNode.h

@@ -30,8 +30,6 @@ public:
 	ANKI_USE_RESULT Error init(const ModelPatch* modelPatch);
 
 private:
-	class RenderComponent;
-
 	const ModelPatch* m_modelPatch;
 };
 

+ 8 - 4
src/anki/scene/Visibility.cpp

@@ -286,7 +286,8 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 		const RenderComponent* rc = nullptr;
 		wantNode |= wantsRenderComponents && (rc = node.tryGetComponent<RenderComponent>());
 
-		wantNode |= wantsShadowCasters && (rc = node.tryGetComponent<RenderComponent>()) && rc->getCastsShadow();
+		wantNode |= wantsShadowCasters && (rc = node.tryGetComponent<RenderComponent>())
+					&& !!(rc->getFlags() & RenderComponentFlag::CASTS_SHADOW);
 
 		const LightComponent* lc = nullptr;
 		wantNode |= wantsLightComponents && (lc = node.tryGetComponent<LightComponent>());
@@ -366,7 +367,7 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 		if(rc)
 		{
 			RenderableQueueElement* el;
-			if(rc->isForwardShading())
+			if(!!(rc->getFlags() & RenderComponentFlag::FORWARD_SHADING))
 			{
 				el = result.m_forwardShadingRenderables.newElement(alloc);
 			}
@@ -379,9 +380,12 @@ void VisibilityTestTask::test(ThreadHive& hive, U32 taskId)
 
 			// Compute distance from the frustum
 			const Plane& nearPlane = testedFrc.getViewPlanes()[FrustumPlaneType::NEAR];
-			el->m_distanceFromCamera = max(0.0f, testPlane(nearPlane, sps[0].m_sp->getAabb()));
+			el->m_distanceFromCamera = !!(rc->getFlags() & RenderComponentFlag::SORT_LAST)
+										   ? testedFrc.getFar()
+										   : max(0.0f, testPlane(nearPlane, sps[0].m_sp->getAabb()));
 
-			if(wantsEarlyZ && el->m_distanceFromCamera < m_frcCtx->m_visCtx->m_earlyZDist && !rc->isForwardShading())
+			if(wantsEarlyZ && el->m_distanceFromCamera < m_frcCtx->m_visCtx->m_earlyZDist
+				&& !(rc->getFlags() & RenderComponentFlag::FORWARD_SHADING))
 			{
 				RenderableQueueElement* el2 = result.m_earlyZRenderables.newElement(alloc);
 				*el2 = *el;

+ 4 - 2
src/anki/scene/components/RenderComponent.cpp

@@ -26,8 +26,10 @@ MaterialRenderComponent::MaterialRenderComponent(SceneNode* node, MaterialResour
 		m_vars[count++].m_mvar = &mv;
 	}
 
-	m_isForwardShading = mtl->isForwardShading();
-	m_castsShadow = mtl->castsShadow();
+	RenderComponentFlag flags =
+		(mtl->isForwardShading()) ? RenderComponentFlag::FORWARD_SHADING : RenderComponentFlag::NONE;
+	flags |= (mtl->castsShadow()) ? RenderComponentFlag::CASTS_SHADOW : RenderComponentFlag::NONE;
+	setFlags(flags);
 }
 
 MaterialRenderComponent::~MaterialRenderComponent()

+ 37 - 8
src/anki/scene/components/RenderComponent.h

@@ -17,6 +17,15 @@ namespace anki
 /// @addtogroup scene
 /// @{
 
+enum class RenderComponentFlag : U8
+{
+	NONE = 0,
+	CASTS_SHADOW = 1 << 0,
+	FORWARD_SHADING = 1 << 1,
+	SORT_LAST = 1 << 2, ///< Push it last when sorting the visibles.
+};
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(RenderComponentFlag, inline)
+
 /// Render component interface. Implemented by renderable scene nodes
 class RenderComponent : public SceneComponent
 {
@@ -28,21 +37,41 @@ public:
 	{
 	}
 
-	Bool getCastsShadow() const
+	RenderComponentFlag getFlags() const
 	{
-		return m_castsShadow;
+		return m_flags;
 	}
 
-	Bool isForwardShading() const
+	void setFlags(RenderComponentFlag flags)
 	{
-		return m_isForwardShading;
+		m_flags = flags;
 	}
 
-	virtual void setupRenderableQueueElement(RenderableQueueElement& el) const = 0;
+	void setup(RenderQueueDrawCallback callback, const void* userData, U64 mergeKey)
+	{
+		ANKI_ASSERT(callback != nullptr);
+		ANKI_ASSERT(userData != nullptr);
+		ANKI_ASSERT(mergeKey != MAX_U64);
+		m_callback = callback;
+		m_userData = userData;
+		m_mergeKey = mergeKey;
+	}
 
-protected:
-	Bool m_castsShadow = false;
-	Bool m_isForwardShading = false;
+	void setupRenderableQueueElement(RenderableQueueElement& el) const
+	{
+		ANKI_ASSERT(el.m_callback != nullptr);
+		el.m_callback = m_callback;
+		ANKI_ASSERT(el.m_userData != nullptr);
+		el.m_userData = m_userData;
+		ANKI_ASSERT(el.m_mergeKey != MAX_U64);
+		el.m_mergeKey = m_mergeKey;
+	}
+
+private:
+	RenderQueueDrawCallback m_callback ANKI_DEBUG_CODE(= nullptr);
+	const void* m_userData ANKI_DEBUG_CODE(= nullptr);
+	U64 m_mergeKey ANKI_DEBUG_CODE(= MAX_U64);
+	RenderComponentFlag m_flags = RenderComponentFlag::NONE;
 };
 
 /// A wrapper on top of MaterialVariable