Browse Source

Editor: Fix skins in object picking

Panagiotis Christopoulos Charitos 2 weeks ago
parent
commit
478fd05452

+ 3 - 3
AnKi/Renderer/Bloom.h

@@ -52,11 +52,11 @@ public:
 		return m_runCtx.m_finalRt;
 	}
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_finalRt;
-		drawStyles[0] = DebugRenderTargetDrawStyle::kTonemap;
+		drawStyle = DebugRenderTargetDrawStyle::kTonemap;
 	}
 
 private:

+ 0 - 2
AnKi/Renderer/Common.h

@@ -53,8 +53,6 @@ constexpr U32 kMinDrawcallsPerSecondaryCommandBuffer = 16;
 /// Bloom size is rendererSize/kBloomFraction.
 constexpr U32 kBloomFraction = 4;
 
-constexpr U32 kMaxDebugRenderTargets = 2;
-
 /// Computes the 'a' and 'b' numbers for linearizeDepthOptimal (see shaders)
 inline void computeLinearizeDepthOptimal(F32 near, F32 far, F32& a, F32& b)
 {

+ 7 - 0
AnKi/Renderer/Dbg.cpp

@@ -206,6 +206,7 @@ static const U16 g_gizmoRingIndices[128][3] = {
 
 Dbg::Dbg()
 {
+	registerDebugRenderTarget("ObjectPicking");
 }
 
 Dbg::~Dbg()
@@ -375,6 +376,8 @@ void Dbg::populateRenderGraph(RenderingContext& ctx)
 {
 	ANKI_TRACE_SCOPED_EVENT(Dbg);
 
+	m_runCtx.m_objectPickingRt = {};
+
 	if(!isEnabled())
 	{
 		return;
@@ -673,6 +676,7 @@ void Dbg::populateRenderGraphObjectPicking(RenderingContext& ctx)
 
 	// The render pass that draws the UUIDs to a buffer
 	const RenderTargetHandle objectPickingRt = rgraph.newRenderTarget(m_objectPickingRtDescr);
+	m_runCtx.m_objectPickingRt = objectPickingRt;
 	const RenderTargetHandle objectPickingDepthRt = rgraph.newRenderTarget(m_objectPickingDepthRtDescr);
 	{
 		GraphicsRenderPass& pass = rgraph.newGraphicsRenderPass("Object Picking: Draw UUIDs");
@@ -711,6 +715,9 @@ void Dbg::populateRenderGraphObjectPicking(RenderingContext& ctx)
 				cmdb.bindSrv(2, 0, GpuSceneArrays::MeshLod::getSingleton().getBufferView());
 				cmdb.bindSrv(3, 0, GpuSceneArrays::Transform::getSingleton().getBufferView());
 				cmdb.bindSrv(4, 0, UnifiedGeometryBuffer::getSingleton().getBufferView(), Format::kR16G16B16A16_Unorm);
+				cmdb.bindSrv(5, 0, UnifiedGeometryBuffer::getSingleton().getBufferView(), Format::kR8G8B8A8_Uint);
+				cmdb.bindSrv(6, 0, UnifiedGeometryBuffer::getSingleton().getBufferView(), Format::kR8G8B8A8_Snorm);
+				cmdb.bindSrv(7, 0, GpuSceneBuffer::getSingleton().getBufferView());
 
 				cmdb.setFastConstants(&ctx.m_matrices.m_viewProjection, sizeof(ctx.m_matrices.m_viewProjection));
 

+ 8 - 0
AnKi/Renderer/Dbg.h

@@ -120,6 +120,7 @@ private:
 	{
 	public:
 		RenderTargetHandle m_rt;
+		RenderTargetHandle m_objectPickingRt;
 		U32 m_objUuid = 0;
 	} m_runCtx;
 
@@ -133,6 +134,13 @@ private:
 						   CommandBuffer& cmdb);
 
 	void drawGizmos(const Mat3x4& worldTransform, const RenderingContext& ctx, CommandBuffer& cmdb) const;
+
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  DebugRenderTargetDrawStyle& drawStyle) const override
+	{
+		handles[DebugRenderTargetRegister::kUintTex] = m_runCtx.m_objectPickingRt;
+		drawStyle = DebugRenderTargetDrawStyle::kIntegerTexture;
+	}
 };
 
 } // end namespace anki

+ 15 - 14
AnKi/Renderer/FinalComposite.cpp

@@ -117,9 +117,9 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 							  TextureUsageBit::kSrvPixel);
 	pass.newTextureDependency(getRenderer().getBloom().getBloomRt(), TextureUsageBit::kSrvPixel);
 
-	Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
-	Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets> drawStyles;
-	const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, drawStyles);
+	Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)> dbgRts;
+	DebugRenderTargetDrawStyle drawStyle = {};
+	const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, drawStyle);
 	if(hasDebugRt)
 	{
 		for(const RenderTargetHandle& handle : dbgRts)
@@ -139,9 +139,9 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 		CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 		const Bool dbgEnabled = !!(getDbg().getOptions() & DbgOption::kDbgScene);
 
-		Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
-		Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets> drawStyles;
-		const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, drawStyles);
+		Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)> dbgRts;
+		DebugRenderTargetDrawStyle drawStyle;
+		const Bool hasDebugRt = getRenderer().getCurrentDebugRenderTarget(dbgRts, drawStyle);
 
 		// Bind program
 		if(hasDebugRt)
@@ -192,24 +192,25 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 		{
 			cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
 
-			U32 count = 0;
-			UVec4 consts;
+			DebugRenderTargetRegister reg = DebugRenderTargetRegister::kFirst;
+			const UVec4 consts((U32)drawStyle);
+			cmdb.setFastConstants(&consts, sizeof(consts));
+
 			for(const RenderTargetHandle& handle : dbgRts)
 			{
 				if(handle.isValid())
 				{
-					consts[count] = U32(drawStyles[count]);
-					rgraphCtx.bindSrv(count, 0, handle);
+					rgraphCtx.bindSrv(U32(reg), 0, handle);
 				}
 				else
 				{
-					cmdb.bindSrv(count, 0, TextureView(getDummyGpuResources().m_texture2DSrv.get(), TextureSubresourceDesc::all()));
+					Texture* tex = (reg == DebugRenderTargetRegister::kUintTex) ? getDummyGpuResources().m_texture2DUintSrv.get()
+																				: getDummyGpuResources().m_texture2DSrv.get();
+					cmdb.bindSrv(U32(reg), 0, TextureView(tex, TextureSubresourceDesc::all()));
 				}
 
-				++count;
+				++reg;
 			}
-
-			cmdb.setFastConstants(&consts, sizeof(consts));
 		}
 
 		cmdb.setViewport(0, 0, getRenderer().getPostProcessResolution().x(), getRenderer().getPostProcessResolution().y());

+ 7 - 7
AnKi/Renderer/GBuffer.cpp

@@ -269,8 +269,8 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 	}
 }
 
-void GBuffer::getDebugRenderTarget(CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-								   Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const
+void GBuffer::getDebugRenderTarget(CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+								   DebugRenderTargetDrawStyle& drawStyle) const
 {
 	if(rtName == "GBufferAlbedo")
 	{
@@ -279,7 +279,7 @@ void GBuffer::getDebugRenderTarget(CString rtName, Array<RenderTargetHandle, kMa
 	else if(rtName == "GBufferNormals")
 	{
 		handles[0] = m_runCtx.m_colorRts[2];
-		drawStyles[0] = DebugRenderTargetDrawStyle::kGBufferNormal;
+		drawStyle = DebugRenderTargetDrawStyle::kGBufferNormal;
 	}
 	else if(rtName == "GBufferVelocity")
 	{
@@ -288,23 +288,23 @@ void GBuffer::getDebugRenderTarget(CString rtName, Array<RenderTargetHandle, kMa
 	else if(rtName == "GBufferRoughness")
 	{
 		handles[0] = m_runCtx.m_colorRts[1];
-		drawStyles[0] = DebugRenderTargetDrawStyle::kGBufferRoughness;
+		drawStyle = DebugRenderTargetDrawStyle::kGBufferRoughness;
 	}
 	else if(rtName == "GBufferMetallic")
 	{
 		handles[0] = m_runCtx.m_colorRts[0];
-		drawStyles[0] = DebugRenderTargetDrawStyle::kGBufferMetallic;
+		drawStyle = DebugRenderTargetDrawStyle::kGBufferMetallic;
 	}
 	else if(rtName == "GBufferSubsurface")
 	{
 		handles[0] = m_runCtx.m_colorRts[0];
-		drawStyles[0] = DebugRenderTargetDrawStyle::kGBufferSubsurface;
+		drawStyle = DebugRenderTargetDrawStyle::kGBufferSubsurface;
 	}
 	else if(rtName == "GBufferEmission")
 	{
 		handles[0] = m_runCtx.m_colorRts[1];
 		handles[1] = m_runCtx.m_colorRts[2];
-		drawStyles[0] = DebugRenderTargetDrawStyle::kGBufferEmission;
+		drawStyle = DebugRenderTargetDrawStyle::kGBufferEmission;
 	}
 }
 

+ 2 - 2
AnKi/Renderer/GBuffer.h

@@ -61,8 +61,8 @@ public:
 		return m_runCtx.m_hzbRt;
 	}
 
-	void getDebugRenderTarget(CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override;
+	void getDebugRenderTarget(CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  DebugRenderTargetDrawStyle& drawStyle) const override;
 
 	/// Returns a buffer with indices of the visible AABBs. Used in debug drawing.
 	const GpuVisibilityOutput& getVisibilityOutput() const

+ 3 - 3
AnKi/Renderer/HistoryLength.h

@@ -25,11 +25,11 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_rt;
-		drawStyles[0] = DebugRenderTargetDrawStyle::kRedOnly;
+		drawStyle = DebugRenderTargetDrawStyle::kRedOnly;
 	}
 
 	RenderTargetHandle getRt() const

+ 3 - 3
AnKi/Renderer/IndirectDiffuse.h

@@ -26,11 +26,11 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_rt;
-		drawStyles[0] = DebugRenderTargetDrawStyle::kTonemap;
+		drawStyle = DebugRenderTargetDrawStyle::kTonemap;
 	}
 
 	RenderTargetHandle getRt() const

+ 3 - 3
AnKi/Renderer/IndirectDiffuseClipmaps.h

@@ -90,11 +90,11 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_handles.m_appliedIrradiance;
-		drawStyles[0] = DebugRenderTargetDrawStyle::kTonemap;
+		drawStyle = DebugRenderTargetDrawStyle::kTonemap;
 	}
 
 	const IndirectDiffuseClipmapConstants& getClipmapConsts() const

+ 3 - 3
AnKi/Renderer/LightShading.h

@@ -64,11 +64,11 @@ private:
 
 	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_rt;
-		drawStyles[0] = DebugRenderTargetDrawStyle::kTonemap;
+		drawStyle = DebugRenderTargetDrawStyle::kTonemap;
 	}
 };
 /// @}

+ 2 - 2
AnKi/Renderer/MotionBlur.h

@@ -28,8 +28,8 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		ANKI_ASSERT(rtName == "MotionBlur");
 		handles[0] = m_runCtx.m_rt;

+ 2 - 2
AnKi/Renderer/MotionVectors.h

@@ -31,8 +31,8 @@ public:
 		return m_runCtx.m_motionVectorsRtHandle;
 	}
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_motionVectorsRtHandle;
 	}

+ 3 - 3
AnKi/Renderer/Reflections.h

@@ -35,11 +35,11 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_rt;
-		drawStyles[0] = DebugRenderTargetDrawStyle::kTonemap;
+		drawStyle = DebugRenderTargetDrawStyle::kTonemap;
 	}
 
 	RenderTargetHandle getRt() const

+ 24 - 7
AnKi/Renderer/Renderer.cpp

@@ -200,9 +200,13 @@ Error Renderer::initInternal(const RendererInitInfo& inf)
 		texinit.m_format = Format::kR8G8B8A8_Unorm;
 		m_dummyResources.m_texture2DSrv = createAndClearRenderTarget(texinit, TextureUsageBit::kAllSrv);
 
+		texinit.m_format = Format::kR32G32B32A32_Uint;
+		m_dummyResources.m_texture2DUintSrv = createAndClearRenderTarget(texinit, TextureUsageBit::kAllSrv);
+
 		texinit.m_depth = 4;
 		texinit.m_type = TextureType::k3D;
 		texinit.m_usage = TextureUsageBit::kAllSrv | TextureUsageBit::kAllUav;
+		texinit.m_format = Format::kR8G8B8A8_Unorm;
 		m_dummyResources.m_texture3DSrv = createAndClearRenderTarget(texinit, TextureUsageBit::kAllSrv);
 
 		texinit.m_type = TextureType::k2D;
@@ -681,11 +685,11 @@ void Renderer::registerDebugRenderTarget(RendererObject* obj, CString rtName)
 	m_debugRts.emplaceBack(std::move(inf));
 }
 
-Bool Renderer::getCurrentDebugRenderTarget(Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-										   Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles)
+Bool Renderer::getCurrentDebugRenderTarget(Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+										   DebugRenderTargetDrawStyle& drawStyle)
 {
 	handles = {};
-	drawStyles = {};
+	drawStyle = DebugRenderTargetDrawStyle::kPassthrough;
 
 	if(m_currentDebugRtName.isEmpty()) [[likely]]
 	{
@@ -703,14 +707,27 @@ Bool Renderer::getCurrentDebugRenderTarget(Array<RenderTargetHandle, kMaxDebugRe
 
 	if(obj)
 	{
-		obj->getDebugRenderTarget(m_currentDebugRtName, handles, drawStyles);
-		for(DebugRenderTargetDrawStyle& style : drawStyles)
+		obj->getDebugRenderTarget(m_currentDebugRtName, handles, drawStyle);
+
+		Bool valid = false;
+		for(const RenderTargetHandle& handle : handles)
 		{
-			if(m_disableDebugRtTonemapping && style == DebugRenderTargetDrawStyle::kTonemap)
+			if(handle.isValid())
 			{
-				style = DebugRenderTargetDrawStyle::kPassthrough;
+				valid = true;
 			}
 		}
+
+		if(!valid)
+		{
+			return false;
+		}
+
+		if(m_disableDebugRtTonemapping && drawStyle == DebugRenderTargetDrawStyle::kTonemap)
+		{
+			drawStyle = DebugRenderTargetDrawStyle::kPassthrough;
+		}
+
 		return true;
 	}
 	else

+ 3 - 2
AnKi/Renderer/Renderer.h

@@ -61,6 +61,7 @@ class DummyGpuResources
 {
 public:
 	TexturePtr m_texture2DSrv;
+	TexturePtr m_texture2DUintSrv;
 	TexturePtr m_texture3DSrv;
 	TexturePtr m_texture2DUav;
 	TexturePtr m_texture3DUav;
@@ -188,8 +189,8 @@ public:
 	}
 
 	// Need to call it after the handle is set by the RenderGraph.
-	Bool getCurrentDebugRenderTarget(Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-									 Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles);
+	Bool getCurrentDebugRenderTarget(Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+									 DebugRenderTargetDrawStyle& drawStyle);
 	/// @}
 
 	StackMemoryPool& getFrameMemoryPool()

+ 3 - 2
AnKi/Renderer/RendererObject.h

@@ -28,8 +28,9 @@ public:
 
 	virtual ~RendererObject() = default;
 
-	virtual void getDebugRenderTarget([[maybe_unused]] CString rtName, [[maybe_unused]] Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-									  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const
+	virtual void getDebugRenderTarget([[maybe_unused]] CString rtName,
+									  [[maybe_unused]] Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+									  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const
 	{
 		ANKI_ASSERT(!"Object doesn't support that");
 	}

+ 2 - 2
AnKi/Renderer/RtMaterialFetchDbg.h

@@ -27,8 +27,8 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_rt;
 	}

+ 2 - 2
AnKi/Renderer/RtShadows.h

@@ -33,8 +33,8 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_upscaledRt;
 	}

+ 2 - 2
AnKi/Renderer/ShadowmapsResolve.h

@@ -29,8 +29,8 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		ANKI_ASSERT(rtName == "ResolvedShadows");
 		handles[0] = m_runCtx.m_rt;

+ 2 - 2
AnKi/Renderer/Sky.h

@@ -27,8 +27,8 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_envMapRt;
 	}

+ 3 - 3
AnKi/Renderer/Ssao.h

@@ -39,11 +39,11 @@ public:
 
 	void populateRenderGraph(RenderingContext& ctx);
 
-	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget([[maybe_unused]] CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		handles[0] = m_runCtx.m_finalRt;
-		drawStyles[0] = (rtName == "Ssao") ? DebugRenderTargetDrawStyle::kAlphaOnly : DebugRenderTargetDrawStyle::kPassthrough;
+		drawStyle = (rtName == "Ssao") ? DebugRenderTargetDrawStyle::kAlphaOnly : DebugRenderTargetDrawStyle::kPassthrough;
 	}
 
 	RenderTargetHandle getRt() const

+ 2 - 2
AnKi/Renderer/VrsSriGeneration.h

@@ -69,8 +69,8 @@ public:
 		RenderTargetHandle m_downscaledRt;
 	} m_runCtx;
 
-	void getDebugRenderTarget(CString rtName, Array<RenderTargetHandle, kMaxDebugRenderTargets>& handles,
-							  [[maybe_unused]] Array<DebugRenderTargetDrawStyle, kMaxDebugRenderTargets>& drawStyles) const override
+	void getDebugRenderTarget(CString rtName, Array<RenderTargetHandle, U32(DebugRenderTargetRegister::kCount)>& handles,
+							  [[maybe_unused]] DebugRenderTargetDrawStyle& drawStyle) const override
 	{
 		if(rtName == "VrsSri")
 		{

+ 28 - 0
AnKi/Shaders/Dbg.ankiprog

@@ -377,7 +377,11 @@ StructuredBuffer<U32> g_lodAndRenderableIndices : register(t0);
 StructuredBuffer<GpuSceneRenderable> g_renderables : register(t1);
 StructuredBuffer<GpuSceneMeshLod> g_meshLods : register(t2);
 StructuredBuffer<Mat3x4> g_transforms : register(t3);
+
 Buffer<Vec4> g_unifiedGeom_R16G16B16A16_Unorm : register(t4);
+Buffer<UVec4> g_unifiedGeom_R8G8B8A8_Uint : register(t5);
+Buffer<Vec4> g_unifiedGeom_R8G8B8A8_Snorm : register(t6);
+ByteAddressBuffer g_gpuScene : register(t7);
 
 ANKI_FAST_CONSTANTS(Mat4, g_mvp);
 
@@ -388,6 +392,12 @@ struct VertOut
 };
 
 #	if ANKI_VERTEX_SHADER
+struct Mat3x4_2
+{
+	Mat3x4 m_a;
+	Mat3x4 m_b;
+};
+
 VertOut main(U32 svVertexId : SV_VERTEXID)
 {
 	const U32 packed = SBUFF(g_lodAndRenderableIndices, gl_DrawID);
@@ -402,6 +412,24 @@ VertOut main(U32 svVertexId : SV_VERTEXID)
 	Vec3 position = g_unifiedGeom_R16G16B16A16_Unorm[meshLod.m_vertexOffsets[(U32)VertexStreamId::kPosition] + svVertexId];
 	position = position * meshLod.m_positionScale + meshLod.m_positionTranslation;
 
+	if(renderable.m_boneTransformsOffset)
+	{
+		const UVec4 boneIndices = g_unifiedGeom_R8G8B8A8_Uint[meshLod.m_vertexOffsets[(U32)VertexStreamId::kBoneIds] + svVertexId];
+		const Vec4 boneWeights = g_unifiedGeom_R8G8B8A8_Snorm[meshLod.m_vertexOffsets[(U32)VertexStreamId::kBoneWeights] + svVertexId];
+
+		Mat3x4 skinMat = (Mat3x4)0.0;
+		for(U32 i = 0; i < 4; ++i)
+		{
+			U32 byteOffset = renderable.m_boneTransformsOffset;
+			byteOffset += boneIndices[i] * sizeof(Mat3x4_2);
+
+			const Mat3x4_2 mats = g_gpuScene.Load<Mat3x4_2>(byteOffset);
+			skinMat = skinMat + mats.m_a * boneWeights[i];
+		}
+
+		position = mul(skinMat, Vec4(position, 1.0)).xyz;
+	}
+
 	const Mat3x4 trf = SBUFF(g_transforms, renderable.m_worldTransformsIndex);
 	position = mul(trf, Vec4(position, 1.0));
 

+ 1 - 0
AnKi/Shaders/Include/Common.h

@@ -9,6 +9,7 @@
 #if defined(__cplusplus)
 
 #	include <AnKi/Math.h>
+#	include <AnKi/Util/Enum.h>
 
 #	define ANKI_HLSL 0
 #	define ANKI_GLSL 0

+ 12 - 0
AnKi/Shaders/Include/MiscRendererTypes.h

@@ -271,9 +271,21 @@ enum class DebugRenderTargetDrawStyle
 	kGBufferEmission,
 	kAlphaOnly,
 	kRedOnly,
+	kIntegerTexture,
 
 	kCount,
 	kFirst = 0
 };
 
+enum class DebugRenderTargetRegister
+{
+	kTex1,
+	kTex2,
+	kUintTex,
+
+	kCount,
+	kFirst = 0
+};
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(DebugRenderTargetRegister)
+
 ANKI_END_NAMESPACE

+ 22 - 0
AnKi/Shaders/VisualizeRenderTarget.ankiprog

@@ -13,6 +13,7 @@
 SamplerState g_nearestAnyClampSampler : register(s0);
 Texture2D<Vec4> g_inTex : register(t0);
 Texture2D<Vec4> g_inTex2 : register(t1);
+Texture2D<UVec4> g_integerTex : register(t2);
 
 struct Consts
 {
@@ -24,6 +25,22 @@ struct Consts
 ANKI_FAST_CONSTANTS(Consts, g_consts)
 
 #if ANKI_PIXEL_SHADER
+Vec3 uintToColor(U32 v)
+{
+	// simple integer hash → 0..1
+	const F32 h = frac(sin(v * 12.9898) * 43758.5453);
+
+	const F32 s = 0.6; // moderate saturation
+	const F32 val = 0.9; // bright
+
+	// HSV → RGB
+	const Vec3 k = Vec3(1.0, 2.0 / 3.0, 1.0 / 3.0);
+	const Vec3 p = abs(frac(h + k) * 6.0 - 3.0);
+	const Vec3 rgb = val * lerp(1.0, saturate(p - 1.0), s);
+
+	return rgb; // 0..1
+}
+
 Vec3 main(VertOut input) : SV_TARGET0
 {
 	Vec4 rgba = g_inTex.SampleLevel(g_nearestAnyClampSampler, input.m_uv, 0.0);
@@ -58,6 +75,11 @@ Vec3 main(VertOut input) : SV_TARGET0
 	case DebugRenderTargetDrawStyle::kRedOnly:
 		rgba.xyz = rgba.rrr;
 		break;
+	case DebugRenderTargetDrawStyle::kIntegerTexture:
+	{
+		const UVec4 val = g_integerTex.SampleLevel(g_nearestAnyClampSampler, input.m_uv, 0.0);
+		rgba = Vec4(uintToColor(val.x), 1.0);
+	}
 	default:
 		break;
 	}