Browse Source

Add some cheap diffuse color in acceleration structure instances

Panagiotis Christopoulos Charitos 2 months ago
parent
commit
594bf0d472
100 changed files with 271 additions and 43 deletions
  1. 62 0
      AnKi/Importer/ImageImporter.cpp
  2. 35 19
      AnKi/Math/Functions.h
  3. 1 1
      AnKi/Renderer/RtMaterialFetchDbg.cpp
  4. 6 1
      AnKi/Resource/ImageBinary.h
  5. 4 2
      AnKi/Resource/ImageBinary.xml
  6. 4 2
      AnKi/Resource/ImageLoader.cpp
  7. 9 1
      AnKi/Resource/ImageLoader.h
  8. 2 0
      AnKi/Resource/ImageResource.cpp
  9. 7 0
      AnKi/Resource/ImageResource.h
  10. 5 0
      AnKi/Resource/MaterialResource.h
  11. 53 0
      AnKi/Scene/Components/MaterialComponent.cpp
  12. 11 0
      AnKi/Shaders/Common.hlsl
  13. 1 1
      AnKi/Shaders/GBufferGeneric.ankiprog
  14. 1 1
      AnKi/Shaders/GpuVisibilityAccelerationStructures.ankiprog
  15. 1 1
      AnKi/Shaders/Include/Common.h
  16. 3 0
      AnKi/Shaders/Include/GpuSceneTypes.h
  17. 7 11
      AnKi/Shaders/PackFunctions.hlsl
  18. 58 2
      AnKi/Shaders/RtMaterialFetchDbg.ankiprog
  19. BIN
      Samples/Sponza/Assets/Background_Roughness.ankitex
  20. BIN
      Samples/Sponza/Assets/ChainMail_baseColor.ankitex
  21. BIN
      Samples/Sponza/Assets/ChainMail_metallicRoughness.ankitex
  22. BIN
      Samples/Sponza/Assets/ChainMail_normal.ankitex
  23. BIN
      Samples/Sponza/Assets/Leather_baseColor.ankitex
  24. BIN
      Samples/Sponza/Assets/Leather_metallicRoughness.ankitex
  25. BIN
      Samples/Sponza/Assets/Leather_normal.ankitex
  26. BIN
      Samples/Sponza/Assets/Lion_Roughness.ankitex
  27. BIN
      Samples/Sponza/Assets/Metal_baseColor.ankitex
  28. BIN
      Samples/Sponza/Assets/Metal_metallicRoughness.ankitex
  29. BIN
      Samples/Sponza/Assets/Metal_normal.ankitex
  30. 1 1
      Samples/Sponza/Assets/Scene.lua
  31. BIN
      Samples/Sponza/Assets/Sponza_Ceiling_roughness.ankitex.ankitex
  32. BIN
      Samples/Sponza/Assets/Sponza_Column_b_roughness.ankitex.ankitex
  33. BIN
      Samples/Sponza/Assets/Sponza_Column_c_roughness.ankitex.ankitex
  34. BIN
      Samples/Sponza/Assets/Sponza_Curtain_Red_normal.ankitex
  35. BIN
      Samples/Sponza/Assets/Sponza_Curtain_Red_normal.ankitex.001.ankitex
  36. BIN
      Samples/Sponza/Assets/Sponza_Curtain_roughness.ankitex.001.ankitex
  37. BIN
      Samples/Sponza/Assets/Sponza_Details_metallic-Sponza_Details_roughness.ankitex
  38. BIN
      Samples/Sponza/Assets/Sponza_Details_normal.ankitex
  39. BIN
      Samples/Sponza/Assets/Sponza_Fabric_metallic-Sponza_Curtain_roughness.ankitex
  40. BIN
      Samples/Sponza/Assets/Sponza_FlagPole_normal.ankitex
  41. BIN
      Samples/Sponza/Assets/Sponza_FlagPole_roughness.ankitex
  42. BIN
      Samples/Sponza/Assets/Sponza_Floor_normal.ankitex
  43. BIN
      Samples/Sponza/Assets/Sponza_Floor_roughness.ankitex
  44. BIN
      Samples/Sponza/Assets/Sponza_Roof_normal.ankitex
  45. BIN
      Samples/Sponza/Assets/Sponza_Roof_roughness.ankitex
  46. BIN
      Samples/Sponza/Assets/Sponza_Thorn_roughness.ankitex
  47. BIN
      Samples/Sponza/Assets/Suzanne_e3526e1428c0763c.ankimesh
  48. BIN
      Samples/Sponza/Assets/VaseHanging_normal.ankitex.ankitex
  49. BIN
      Samples/Sponza/Assets/VaseHanging_roughness.ankitex.ankitex
  50. BIN
      Samples/Sponza/Assets/VasePlant_normal.ankitex
  51. BIN
      Samples/Sponza/Assets/VaseRound_normal.ankitex
  52. BIN
      Samples/Sponza/Assets/VaseRound_roughness.ankitex
  53. BIN
      Samples/Sponza/Assets/Vase_roughness.ankitex
  54. BIN
      Samples/Sponza/Assets/background.ankitex
  55. BIN
      Samples/Sponza/Assets/background_ddn.ankitex
  56. BIN
      Samples/Sponza/Assets/candle_3_l.001_9966f5242837df58.ankimesh
  57. BIN
      Samples/Sponza/Assets/chain_texture.ankitex.ankitex
  58. BIN
      Samples/Sponza/Assets/fabric_a_945c29fc221550fb.ankimesh
  59. BIN
      Samples/Sponza/Assets/fabric_b_e8dd2769dc642ab7.ankimesh
  60. BIN
      Samples/Sponza/Assets/leaf_3a245efd17475037.ankimesh
  61. BIN
      Samples/Sponza/Assets/lion.ankitex
  62. BIN
      Samples/Sponza/Assets/lion_ddn.ankitex
  63. BIN
      Samples/Sponza/Assets/material_baseColor.ankitex
  64. BIN
      Samples/Sponza/Assets/material_metallicRoughness.ankitex
  65. BIN
      Samples/Sponza/Assets/skinFace_baseColor.ankitex
  66. BIN
      Samples/Sponza/Assets/skinFace_metallicRoughness.ankitex
  67. BIN
      Samples/Sponza/Assets/skinFace_normal.ankitex
  68. BIN
      Samples/Sponza/Assets/sponza_381_d80b7e06247cf847.ankimesh
  69. BIN
      Samples/Sponza/Assets/sponza_arch_ddn.ankitex
  70. BIN
      Samples/Sponza/Assets/sponza_arch_ddn.ankitex.ankitex
  71. BIN
      Samples/Sponza/Assets/sponza_arch_diff.ankitex
  72. BIN
      Samples/Sponza/Assets/sponza_arch_diff.ankitex.ankitex
  73. BIN
      Samples/Sponza/Assets/sponza_arch_spec.ankitex
  74. BIN
      Samples/Sponza/Assets/sponza_arch_spec.ankitex.ankitex
  75. BIN
      Samples/Sponza/Assets/sponza_bricks_a_ddn.ankitex.ankitex
  76. BIN
      Samples/Sponza/Assets/sponza_bricks_a_diff.ankitex.ankitex
  77. BIN
      Samples/Sponza/Assets/sponza_ceiling_a_diff.ankitex.ankitex
  78. BIN
      Samples/Sponza/Assets/sponza_column_a_ddn.ankitex.ankitex
  79. BIN
      Samples/Sponza/Assets/sponza_column_a_diff.ankitex.ankitex
  80. BIN
      Samples/Sponza/Assets/sponza_column_a_spec.ankitex.ankitex
  81. BIN
      Samples/Sponza/Assets/sponza_column_b_ddn.ankitex.ankitex
  82. BIN
      Samples/Sponza/Assets/sponza_column_b_diff.ankitex.ankitex
  83. BIN
      Samples/Sponza/Assets/sponza_column_c_ddn.ankitex.ankitex
  84. BIN
      Samples/Sponza/Assets/sponza_column_c_diff.ankitex.ankitex
  85. BIN
      Samples/Sponza/Assets/sponza_curtain_green_diff.ankitex.ankitex
  86. BIN
      Samples/Sponza/Assets/sponza_details_diff.ankitex
  87. BIN
      Samples/Sponza/Assets/sponza_fabric_blue_diff.ankitex
  88. BIN
      Samples/Sponza/Assets/sponza_fabric_diff.ankitex
  89. BIN
      Samples/Sponza/Assets/sponza_fabric_green_diff.ankitex
  90. BIN
      Samples/Sponza/Assets/sponza_flagpole_diff.ankitex
  91. BIN
      Samples/Sponza/Assets/sponza_floor_a_diff.ankitex
  92. BIN
      Samples/Sponza/Assets/sponza_roof_diff.ankitex
  93. BIN
      Samples/Sponza/Assets/sponza_thorn_ddn.ankitex
  94. BIN
      Samples/Sponza/Assets/sponza_thorn_diff.ankitex
  95. BIN
      Samples/Sponza/Assets/test.ankitex
  96. BIN
      Samples/Sponza/Assets/vase_ddn.ankitex
  97. BIN
      Samples/Sponza/Assets/vase_dif.ankitex
  98. BIN
      Samples/Sponza/Assets/vase_hanging.ankitex.ankitex
  99. BIN
      Samples/Sponza/Assets/vase_plant.ankitex.ankitex
  100. BIN
      Samples/Sponza/Assets/vase_round.ankitex.ankitex

+ 62 - 0
AnKi/Importer/ImageImporter.cpp

@@ -45,6 +45,7 @@ public:
 	U32 m_channelCount = 0;
 	U32 m_pixelSize = 0; ///< Texel size of an uncompressed image.
 	Bool m_hdr = false;
+	Vec4 m_averageColor = Vec4(0.0f);
 };
 
 class DdsPixelFormat
@@ -356,6 +357,40 @@ static void linearToSRgbBatch(WeakArray<TVec> pixels, TFunc func)
 	}
 }
 
+template<typename TVec>
+static Vec4 computeAverageColor(WeakArray<TVec> pixels)
+{
+	Vec4 average(0.0f);
+	const F32 weight = 1.0f / F32(pixels.getSize());
+
+	for(const TVec& color : pixels)
+	{
+		Vec4 v;
+		if constexpr(TVec::kComponentCount == 3)
+		{
+			v = Vec4(Vec3(color), 0.0f);
+		}
+		else
+		{
+			ANKI_ASSERT(TVec::kComponentCount == 4);
+			v = Vec4(color);
+		}
+
+		if(sizeof(color[0]) == 1)
+		{
+			v /= 255.0f;
+		}
+		else
+		{
+			ANKI_ASSERT(sizeof(color[0]) == 4);
+		}
+
+		average += v * weight;
+	}
+
+	return average;
+}
+
 static void applyScaleAndBias(WeakArray<Vec3> pixels, Vec3 scale, Vec3 bias)
 {
 	for(Vec3& pixel : pixels)
@@ -483,6 +518,32 @@ static Error loadFirstMipmap(const ImageImporterConfig& config, ImageImporterCon
 			memcpy(mip0.m_surfacesOrVolume[i].m_pixels.getBegin(), data, dataSize);
 		}
 
+		Vec4 averageColor(0.0f);
+		if(ctx.m_channelCount == 3)
+		{
+			if(!ctx.m_hdr)
+			{
+				averageColor = computeAverageColor(WeakArray<U8Vec3>(static_cast<U8Vec3*>(data), ctx.m_width * ctx.m_height));
+			}
+			else
+			{
+				averageColor = computeAverageColor(WeakArray<Vec3>(static_cast<Vec3*>(data), ctx.m_width * ctx.m_height));
+			}
+		}
+		else
+		{
+			ANKI_ASSERT(ctx.m_channelCount == 4);
+			if(!ctx.m_hdr)
+			{
+				averageColor = computeAverageColor(WeakArray<U8Vec4>(static_cast<U8Vec4*>(data), ctx.m_width * ctx.m_height));
+			}
+			else
+			{
+				averageColor = computeAverageColor(WeakArray<Vec4>(static_cast<Vec4*>(data), ctx.m_width * ctx.m_height));
+			}
+		}
+		ctx.m_averageColor += averageColor / F32(config.m_inputFilenames.getSize());
+
 		stbi_image_free(data);
 	}
 
@@ -780,6 +841,7 @@ static Error storeAnkiImage(const ImageImporterConfig& config, const ImageImport
 	header.m_mipmapCount = U8(ctx.m_mipmaps.getSize());
 	header.m_astcBlockSizeX = config.m_astcBlockSize.x();
 	header.m_astcBlockSizeY = config.m_astcBlockSize.y();
+	header.m_averageColor = {ctx.m_averageColor.x(), ctx.m_averageColor.y(), ctx.m_averageColor.z(), ctx.m_averageColor.w()};
 	ANKI_CHECK(outFile.write(&header, sizeof(header)));
 
 	// Write RAW

+ 35 - 19
AnKi/Math/Functions.h

@@ -260,25 +260,6 @@ inline U32 packColorToR10G10B10A2SNorm(F32 r, F32 g, F32 b, F32 a)
 	return out.m_packed;
 }
 
-template<typename TVec4>
-inline U32 packSnorm4x8(const TVec4& v)
-{
-	union
-	{
-		I8 in[4];
-		U32 out;
-	} u;
-
-	const TVec4 result = (v.clamp(-1.0f, 1.0f) * 127.0f).round();
-
-	u.in[0] = I8(result[0]);
-	u.in[1] = I8(result[1]);
-	u.in[2] = I8(result[2]);
-	u.in[3] = I8(result[3]);
-
-	return u.out;
-}
-
 /// Compute the abs triangle area.
 template<typename TVec>
 inline F32 computeTriangleArea(const TVec& a, const TVec& b, const TVec& c)
@@ -308,4 +289,39 @@ TVec<T, 3> sphericalToCartesian(T polar, T azimuth)
 	return out;
 }
 
+template<typename T>
+inline [[nodiscard]] U32 packUnorm4x8(TVec<T, 4> value)
+{
+	ANKI_ASSERT((value <= TVec<T, 4>(T(1)) && value >= TVec<T, 4>(T(0))));
+	const TVec<U32, 4> packed(value * T(255));
+	return packed.x() | (packed.y() << 8u) | (packed.z() << 16u) | (packed.w() << 24u);
+}
+
+// Reverse of packUnorm4x8
+template<typename T>
+inline [[nodiscard]] TVec<T, 4> unpackUnorm4x8(const U32 value)
+{
+	const TVec<U32, 4> packed(value & 0xFF, (value >> 8u) & 0xFF, (value >> 16u) & 0xff, value >> 24u);
+	return TVec<T, 4>(packed) / T(255);
+}
+
+template<typename TVec4>
+inline [[nodiscard]] U32 packSnorm4x8(const TVec4& v)
+{
+	union
+	{
+		I8 in[4];
+		U32 out;
+	} u;
+
+	const TVec4 result = (v.clamp(-1.0f, 1.0f) * 127.0f).round();
+
+	u.in[0] = I8(result[0]);
+	u.in[1] = I8(result[1]);
+	u.in[2] = I8(result[2]);
+	u.in[3] = I8(result[3]);
+
+	return u.out;
+}
+
 } // end namespace anki

+ 1 - 1
AnKi/Renderer/RtMaterialFetchDbg.cpp

@@ -97,7 +97,7 @@ void RtMaterialFetchDbg::populateRenderGraph(RenderingContext& ctx)
 			bindRgenSpace2Resources(ctx, rgraphCtx);
 			rgraphCtx.bindUav(0, 2, m_runCtx.m_rt);
 
-			Vec4 dummy;
+			Vec4 dummy[3];
 			cmdb.setFastConstants(&dummy, sizeof(dummy));
 
 			cmdb.dispatchRays(sbtBuffer, m_sbtRecordSize, GpuSceneArrays::RenderableBoundingVolumeRt::getSingleton().getElementCount(), 1,

+ 6 - 1
AnKi/Resource/ImageBinary.h

@@ -66,7 +66,11 @@ public:
 	U32 m_mipmapCount;
 	U32 m_astcBlockSizeX;
 	U32 m_astcBlockSizeY;
-	Array<U8, 80> m_padding;
+
+	/// For U8 formats from 0.0 to 1.0.
+	Array<F32, 4> m_averageColor;
+
+	Array<U8, 64> m_padding;
 
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
@@ -82,6 +86,7 @@ public:
 		s.doValue("m_mipmapCount", offsetof(ImageBinaryHeader, m_mipmapCount), self.m_mipmapCount);
 		s.doValue("m_astcBlockSizeX", offsetof(ImageBinaryHeader, m_astcBlockSizeX), self.m_astcBlockSizeX);
 		s.doValue("m_astcBlockSizeY", offsetof(ImageBinaryHeader, m_astcBlockSizeY), self.m_astcBlockSizeY);
+		s.doArray("m_averageColor", offsetof(ImageBinaryHeader, m_averageColor), &self.m_averageColor[0], self.m_averageColor.getSize());
 		s.doArray("m_padding", offsetof(ImageBinaryHeader, m_padding), &self.m_padding[0], self.m_padding.getSize());
 	}
 

+ 4 - 2
AnKi/Resource/ImageBinary.xml

@@ -5,7 +5,8 @@
 
 	<doxygen_group name="resource"/>
 
-	<prefix_code><![CDATA[
+	<prefix_code>
+		<![CDATA[
 inline constexpr const Char* kImageMagic = "ANKITEX1";
 
 /// Image type.
@@ -58,7 +59,8 @@ ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ImageBinaryDataCompression)
 				<member name="m_mipmapCount" type="U32"/>
 				<member name="m_astcBlockSizeX" type="U32"/>
 				<member name="m_astcBlockSizeY" type="U32"/>
-				<member name="m_padding" type="U8" array_size="80"/>
+				<member name="m_averageColor" type="F32" array_size="4" comment="For U8 formats from 0.0 to 1.0"/>
+				<member name="m_padding" type="U8" array_size="64"/>
 			</members>
 		</class>
 	</classes>

+ 4 - 2
AnKi/Resource/ImageLoader.cpp

@@ -235,7 +235,7 @@ Error ImageLoader::loadAnkiImage(FileInterface& file, U32 maxImageSize, ImageBin
 								 DynamicArray<ImageLoaderSurface, MemoryPoolPtrWrapper<BaseMemoryPool>>& surfaces,
 								 DynamicArray<ImageLoaderVolume, MemoryPoolPtrWrapper<BaseMemoryPool>>& volumes, U32& width, U32& height, U32& depth,
 								 U32& layerCount, U32& mipCount, ImageBinaryType& imageType, ImageBinaryColorFormat& colorFormat,
-								 UVec2& astcBlockSize)
+								 UVec2& astcBlockSize, Vec4& avgColor)
 {
 	//
 	// Read and check the header
@@ -300,6 +300,8 @@ Error ImageLoader::loadAnkiImage(FileInterface& file, U32 maxImageSize, ImageBin
 		return Error::kUserData;
 	}
 
+	avgColor = Vec4(header.m_averageColor);
+
 	// Set a few things
 	colorFormat = header.m_colorFormat;
 	imageType = header.m_type;
@@ -569,7 +571,7 @@ Error ImageLoader::loadInternal(FileInterface& file, const CString& filename, U3
 #endif
 
 		ANKI_CHECK(loadAnkiImage(file, maxImageSize, m_compression, m_surfaces, m_volumes, m_width, m_height, m_depth, m_layerCount, m_mipmapCount,
-								 m_imageType, m_colorFormat, m_astcBlockSize));
+								 m_imageType, m_colorFormat, m_astcBlockSize, m_avgColor));
 	}
 	else if(ext == "png" || ext == "jpg" || ext == "tga")
 	{

+ 9 - 1
AnKi/Resource/ImageLoader.h

@@ -108,6 +108,11 @@ public:
 		return m_astcBlockSize;
 	}
 
+	Vec4 getAverageColor() const
+	{
+		return m_avgColor;
+	}
+
 	const ImageLoaderSurface& getSurface(U32 level, U32 face, U32 layer) const;
 
 	const ImageLoaderVolume& getVolume(U32 level) const;
@@ -129,6 +134,8 @@ private:
 
 	DynamicArray<ImageLoaderVolume, MemoryPoolPtrWrapper<BaseMemoryPool>> m_volumes;
 
+	Vec4 m_avgColor = Vec4(0.0f);
+
 	U32 m_mipmapCount = 0;
 	U32 m_width = 0;
 	U32 m_height = 0;
@@ -147,7 +154,8 @@ private:
 	static Error loadAnkiImage(FileInterface& file, U32 maxImageSize, ImageBinaryDataCompression& preferredCompression,
 							   DynamicArray<ImageLoaderSurface, MemoryPoolPtrWrapper<BaseMemoryPool>>& surfaces,
 							   DynamicArray<ImageLoaderVolume, MemoryPoolPtrWrapper<BaseMemoryPool>>& volumes, U32& width, U32& height, U32& depth,
-							   U32& layerCount, U32& mipCount, ImageBinaryType& imageType, ImageBinaryColorFormat& colorFormat, UVec2& astcBlockSize);
+							   U32& layerCount, U32& mipCount, ImageBinaryType& imageType, ImageBinaryColorFormat& colorFormat, UVec2& astcBlockSize,
+							   Vec4& avgColor);
 
 	Error loadInternal(FileInterface& file, const CString& filename, U32 maxImageSize);
 };

+ 2 - 0
AnKi/Resource/ImageResource.cpp

@@ -68,6 +68,8 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 
 	ANKI_CHECK(loader.load(file, filename, g_cvarRsrcMaxImageSize));
 
+	m_avgColor = loader.getAverageColor();
+
 	// Various sizes
 	init.m_width = loader.getWidth();
 	init.m_height = loader.getHeight();

+ 7 - 0
AnKi/Resource/ImageResource.h

@@ -60,6 +60,11 @@ public:
 		return m_layerCount;
 	}
 
+	Vec4 getAverageColor() const
+	{
+		return m_avgColor;
+	}
+
 private:
 	static constexpr U32 kMaxCopiesBeforeFlush = 4;
 
@@ -70,6 +75,8 @@ private:
 	UVec3 m_size = UVec3(0u);
 	U32 m_layerCount = 0;
 
+	Vec4 m_avgColor = Vec4(0.0f);
+
 	[[nodiscard]] static Error load(LoadingContext& ctx);
 };
 /// @}

+ 5 - 0
AnKi/Resource/MaterialResource.h

@@ -83,6 +83,11 @@ public:
 		return m_offsetInLocalConstants;
 	}
 
+	ImageResource* tryGetImageResource() const
+	{
+		return (m_image) ? m_image.get() : nullptr;
+	}
+
 protected:
 	ResourceString m_name;
 	U32 m_offsetInLocalConstants = kMaxU32;

+ 53 - 0
AnKi/Scene/Components/MaterialComponent.cpp

@@ -148,6 +148,56 @@ void MaterialComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 	const MeshResource& mesh = m_meshComponent->getMeshResource();
 	const U32 submeshIdx = min(mesh.getSubMeshCount() - 1, m_submeshIdx);
 
+	// Extract the diffuse color
+	Vec3 averageDiffuse(0.0f);
+	if(mtlUpdated)
+	{
+		const MaterialVariable* diffuseRelatedMtlVar = nullptr;
+
+		for(const MaterialVariable& mtlVar : mtl.getVariables())
+		{
+			SceneString name = mtlVar.getName();
+			name.toLower();
+
+			if(name.find("diffuse") != String::kNpos || name.find("albedo") != String::kNpos)
+			{
+				if(diffuseRelatedMtlVar)
+				{
+					if(name.find("tex") != String::kNpos)
+					{
+						diffuseRelatedMtlVar = &mtlVar;
+					}
+				}
+				else
+				{
+					diffuseRelatedMtlVar = &mtlVar;
+				}
+			}
+		}
+
+		if(diffuseRelatedMtlVar)
+		{
+			if(diffuseRelatedMtlVar->getDataType() >= ShaderVariableDataType::kTextureFirst
+			   && diffuseRelatedMtlVar->getDataType() <= ShaderVariableDataType::kTextureLast)
+			{
+				averageDiffuse = diffuseRelatedMtlVar->getValue<ImageResourcePtr>()->getAverageColor().xyz();
+			}
+			else if(diffuseRelatedMtlVar->getDataType() == ShaderVariableDataType::kVec3)
+			{
+				averageDiffuse = diffuseRelatedMtlVar->getValue<Vec3>();
+			}
+			else if(diffuseRelatedMtlVar->getDataType() == ShaderVariableDataType::kU32 && diffuseRelatedMtlVar->tryGetImageResource())
+			{
+				// Bindless texture
+				averageDiffuse = diffuseRelatedMtlVar->tryGetImageResource()->getAverageColor().xyz();
+			}
+			else
+			{
+				ANKI_SCENE_LOGW("Couldn't extract a diffuse value for material: %s", mtl.getFilename().cstr());
+			}
+		}
+	}
+
 	// Upload transforms
 	if(moved || movedLastFrame) [[unlikely]]
 	{
@@ -273,6 +323,9 @@ void MaterialComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
 		}
 		gpuRenderable.m_uuid = SceneGraph::getSingleton().getNewUuid();
 
+		const UVec3 u3(averageDiffuse.xyz().clamp(0.0f, 1.0f) * 255.0f);
+		gpuRenderable.m_diffuseColor = ((u3.x() << 16u) | (u3.y() << 8u) | u3.z()) & 0xFFFFFFF;
+
 		m_gpuSceneRenderable.uploadToGpuScene(gpuRenderable);
 	}
 

+ 11 - 0
AnKi/Shaders/Common.hlsl

@@ -237,6 +237,17 @@ CHECK_TEXTURE_3()
 	SpvBuiltInHitTriangleVertexPositionsKHR)]] const static Vec3 gl_HitTriangleVertexPositions[3];
 #endif
 
+#if ANKI_GR_BACKEND_VULKAN
+#	define SpvRayQueryPositionFetchKHR 5391
+#	define SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR 5340
+#	define SpvRayQueryCandidateIntersectionKHR 0
+#	define SpvRayQueryCommittedIntersectionKHR 1
+
+[[vk::ext_capability(SpvRayQueryPositionFetchKHR)]] [[vk::ext_extension("SPV_KHR_ray_tracing_position_fetch")]] [[vk::ext_instruction(
+	SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR)]] float3
+spvRayQueryGetIntersectionTriangleVertexPositionsKHR([[vk::ext_reference]] RayQuery<RAY_FLAG_FORCE_OPAQUE> query, int committed)[3];
+#endif
+
 #if ANKI_GR_BACKEND_VULKAN
 #	define SpvDecorationRelaxedPrecision 0
 #	define ANKI_RELAXED_PRECISION [[vk::ext_decorate(SpvDecorationRelaxedPrecision)]]

+ 1 - 1
AnKi/Shaders/GBufferGeneric.ankiprog

@@ -681,7 +681,7 @@ ANKI_SHADER_RECORD_CONSTANTS(GpuSceneRenderableInstance, g_gpuSceneRenderable)
 // ===========================================================================
 // RT material fetch                                                         =
 // ===========================================================================
-#if ANKI_TECHNIQUE_RtMaterialFetch
+#if NOT_ZERO(ANKI_TECHNIQUE_RtMaterialFetch)
 
 #	define USE_POSITION_FETCH_NORMALS ANKI_GR_BACKEND_VULKAN
 

+ 1 - 1
AnKi/Shaders/GpuVisibilityAccelerationStructures.ankiprog

@@ -109,7 +109,7 @@ ANKI_FAST_CONSTANTS(GpuVisibilityAccelerationStructuresConstants, g_consts)
 				AccelerationStructureInstance instance;
 				instance.m_transform = finalTrf;
 				instance.m_mask = meshLod.m_tlasInstanceMask;
-				instance.m_instanceCustomIndex = instanceIdx & 0x00FFFFFFu;
+				instance.m_instanceCustomIndex = renderable.m_diffuseColor & 0x00FFFFFFu;
 				instance.m_flags = kAccellerationStructureFlagTriangleFrontCounterlockwise;
 				instance.m_instanceShaderBindingTableRecordOffset = instanceIdx & 0x00FFFFFFu;
 				instance.m_accelerationStructureAddress = meshLod.m_blasAddress;

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

@@ -546,7 +546,7 @@ enum AccellerationStructureFlag : U32
 struct AccelerationStructureInstance
 {
 	Mat3x4 m_transform;
-	U32 m_instanceCustomIndex : 24;
+	U32 m_instanceCustomIndex : 24; ///< Custom value that can be accessed in the shaders.
 	U32 m_mask : 8;
 	U32 m_instanceShaderBindingTableRecordOffset : 24;
 	U32 m_flags : 8; ///< It's AccellerationStructureFlag.

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

@@ -27,6 +27,9 @@ struct GpuSceneRenderable
 	U32 m_rtShadowsShaderHandleIndex; ///< The index of the shader handle in the array of library's handles.
 	U32 m_rtMaterialFetchShaderHandleIndex; ///< The index of the shader handle in the array of library's handles.
 	U32 m_uuid;
+
+	U32 m_diffuseColor : 24; ///< The average diffuse color of the renderable. Z is in low bits.
+	U32 m_padding : 8;
 };
 
 /// Almost similar to GpuSceneRenderable but with only what the material shaders need. Needs to fit in a UVec4 vertex attribute.

+ 7 - 11
AnKi/Shaders/PackFunctions.hlsl

@@ -68,22 +68,18 @@ vector<T, 3> signedOctDecode(vector<T, 3> n)
 
 // Vectorized version. Assumes that v is in [0.0, 1.0]
 template<typename T>
-U32 newPackUnorm4x8(const vector<T, 4> v)
+U32 packUnorm4x8(const vector<T, 4> value)
 {
-	const vector<T, 4> a = v * 255.0;
-	const UVec4 b = UVec4(a) << UVec4(0u, 8u, 16u, 24u);
-	const UVec2 c = b.xy | b.zw;
-	return c.x | c.y;
+	const UVec4 packed = UVec4(value * T(255));
+	return packed.x | (packed.y << 8u) | (packed.z << 16u) | (packed.w << 24u);
 }
 
-// Vectorized version
+// Reverse of packUnorm4x8
 template<typename T>
-vector<T, 4> newUnpackUnorm4x8(const U32 u)
+vector<T, 4> unpackUnorm4x8(const U32 value)
 {
-	const UVec4 a = ((UVec4)u) >> UVec4(0u, 8u, 16u, 24u);
-	const UVec4 b = a & ((UVec4)0xFFu);
-	const Vec4 c = Vec4(b);
-	return c * T(1.0 / 255.0);
+	const UVec4 packed = UVec4(value & 0xFF, (value >> 8u) & 0xFF, (value >> 16u) & 0xff, value >> 24u);
+	return vector<T, 4>(packed) / T(255);
 }
 
 template<typename T>

+ 58 - 2
AnKi/Shaders/RtMaterialFetchDbg.ankiprog

@@ -12,6 +12,8 @@
 #include <AnKi/Shaders/RtMaterialFetch.hlsl>
 #include <AnKi/Shaders/Include/GpuSceneTypes.h>
 
+#define CHEAP 1
+
 [shader("raygeneration")] void main()
 {
 	Vec2 outSize;
@@ -25,14 +27,16 @@
 	const Vec3 rayDir = normalize(worldPos - rayOrigin);
 	const F32 tMax = 1000.0;
 	const F32 tMin = 0.1;
-	const F32 texLod = 0.0;
 	constexpr U32 traceFlags = RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES;
+	Vec3 col;
+
+#if !CHEAP
+	const F32 texLod = 0.0;
 	GBufferLight<F16> gbuffer = (GBufferLight<F16>)0;
 	F32 rayT = 0.0;
 	Bool backfacing = false;
 	const Bool hit = materialRayTrace<F16>(rayOrigin, rayDir, tMin, tMax, texLod, gbuffer, rayT, backfacing, traceFlags);
 
-	Vec3 col;
 	if(!hit)
 	{
 		col = Vec3(1.0, 0.0, 1.0);
@@ -46,7 +50,59 @@
 		// col = gbuffer.m_diffuse * 1.0 + (gbuffer.m_worldNormal / 2.0 + 0.5) * 0.0 + rayT * 0.0 + gbuffer.m_emission * 0.0;
 		col = directLighting(gbuffer, rayOrigin + rayDir * rayT, false, true, 100.0, true);
 		col += gbuffer.m_diffuse * 0.3;
+
+		// col = gbuffer.m_worldNormal / 2.0 + 0.5;
+	}
+#else
+	RayQuery<RAY_FLAG_FORCE_OPAQUE> q;
+	const U32 cullMask = 0xFFu;
+	RayDesc ray;
+	ray.Origin = rayOrigin;
+	ray.TMin = tMin;
+	ray.Direction = rayDir;
+	ray.TMax = tMax;
+	q.TraceRayInline(g_tlas, traceFlags, cullMask, ray);
+	q.Proceed();
+	const Bool hit = q.CommittedStatus() == COMMITTED_TRIANGLE_HIT;
+
+	Bool backfacing = false;
+	if(hit)
+	{
+		backfacing = q.CandidateTriangleFrontFace();
+	}
+
+	if(!hit)
+	{
+		col = Vec3(1.0, 0.0, 1.0);
+	}
+	else if(backfacing)
+	{
+		col = Vec3(1.0, 0.0, 1.0);
+	}
+	else
+	{
+		UVec3 coloru = q.CommittedInstanceID();
+		coloru >>= UVec3(16, 8, 0);
+		coloru &= 0xFF;
+		const Vec3 color = Vec3(coloru) / 255.0;
+
+		const Vec3 positions[3] = spvRayQueryGetIntersectionTriangleVertexPositionsKHR(q, SpvRayQueryCommittedIntersectionKHR);
+		const Vec3 vertNormal = normalize(cross(positions[1] - positions[0], positions[2] - positions[1]));
+
+		const Vec3 worldNormal = normalize(mul(q.CandidateObjectToWorld3x4(), Vec4(vertNormal, 0.0)));
+
+		GBufferLight<F16> gbuffer = (GBufferLight<F16>)0;
+		gbuffer.m_diffuse = color;
+		gbuffer.m_worldNormal = worldNormal;
+
+		const F32 rayT = q.CommittedRayT();
+
+		col = directLighting(gbuffer, rayOrigin + rayDir * rayT, false, true, 100.0, true);
+		col += gbuffer.m_diffuse * 0.3;
+
+		// col = worldNormal / 2.0 + 0.5;
 	}
+#endif
 
 	g_colorAndPdfTex[DispatchRaysIndex().xy] = Vec4(col, 0.0);
 }

BIN
Samples/Sponza/Assets/Background_Roughness.ankitex


BIN
Samples/Sponza/Assets/ChainMail_baseColor.ankitex


BIN
Samples/Sponza/Assets/ChainMail_metallicRoughness.ankitex


BIN
Samples/Sponza/Assets/ChainMail_normal.ankitex


BIN
Samples/Sponza/Assets/Leather_baseColor.ankitex


BIN
Samples/Sponza/Assets/Leather_metallicRoughness.ankitex


BIN
Samples/Sponza/Assets/Leather_normal.ankitex


BIN
Samples/Sponza/Assets/Lion_Roughness.ankitex


BIN
Samples/Sponza/Assets/Metal_baseColor.ankitex


BIN
Samples/Sponza/Assets/Metal_metallicRoughness.ankitex


BIN
Samples/Sponza/Assets/Metal_normal.ankitex


+ 1 - 1
Samples/Sponza/Assets/Scene.lua

@@ -1,4 +1,4 @@
--- Generated by: /home/godlike/src/anki/build_rel/Binaries/GltfImporter sponza_crytek_7_pbr_3.0.gltf /home/godlike/src/anki/Samples/Sponza/Assets/ -rpath Assets -texrpath Assets -lod-count 2 -light-scale 0.0001839 -import-textures 0 -j 8 -v
+-- Generated by: C:\src\anki\out\build\x64-Release-VK\Binaries\GltfImporter.exe sponza_crytek_7_pbr_3.0.gltf C:/src/anki/Samples/Sponza/Assets/ -rpath Assets -texrpath Assets -lod-count 2 -light-scale 0.0001839 -import-textures 1 -j 8 -v
 local scene = getSceneGraph()
 local events = getEventManager()
 

BIN
Samples/Sponza/Assets/Sponza_Ceiling_roughness.ankitex.ankitex


BIN
Samples/Sponza/Assets/Sponza_Column_b_roughness.ankitex.ankitex


BIN
Samples/Sponza/Assets/Sponza_Column_c_roughness.ankitex.ankitex


BIN
Samples/Sponza/Assets/Sponza_Curtain_Red_normal.ankitex


BIN
Samples/Sponza/Assets/Sponza_Curtain_Red_normal.ankitex.001.ankitex


BIN
Samples/Sponza/Assets/Sponza_Curtain_roughness.ankitex.001.ankitex


BIN
Samples/Sponza/Assets/Sponza_Details_metallic-Sponza_Details_roughness.ankitex


BIN
Samples/Sponza/Assets/Sponza_Details_normal.ankitex


BIN
Samples/Sponza/Assets/Sponza_Fabric_metallic-Sponza_Curtain_roughness.ankitex


BIN
Samples/Sponza/Assets/Sponza_FlagPole_normal.ankitex


BIN
Samples/Sponza/Assets/Sponza_FlagPole_roughness.ankitex


BIN
Samples/Sponza/Assets/Sponza_Floor_normal.ankitex


BIN
Samples/Sponza/Assets/Sponza_Floor_roughness.ankitex


BIN
Samples/Sponza/Assets/Sponza_Roof_normal.ankitex


BIN
Samples/Sponza/Assets/Sponza_Roof_roughness.ankitex


BIN
Samples/Sponza/Assets/Sponza_Thorn_roughness.ankitex


BIN
Samples/Sponza/Assets/Suzanne_e3526e1428c0763c.ankimesh


BIN
Samples/Sponza/Assets/VaseHanging_normal.ankitex.ankitex


BIN
Samples/Sponza/Assets/VaseHanging_roughness.ankitex.ankitex


BIN
Samples/Sponza/Assets/VasePlant_normal.ankitex


BIN
Samples/Sponza/Assets/VaseRound_normal.ankitex


BIN
Samples/Sponza/Assets/VaseRound_roughness.ankitex


BIN
Samples/Sponza/Assets/Vase_roughness.ankitex


BIN
Samples/Sponza/Assets/background.ankitex


BIN
Samples/Sponza/Assets/background_ddn.ankitex


BIN
Samples/Sponza/Assets/candle_3_l.001_9966f5242837df58.ankimesh


BIN
Samples/Sponza/Assets/chain_texture.ankitex.ankitex


BIN
Samples/Sponza/Assets/fabric_a_945c29fc221550fb.ankimesh


BIN
Samples/Sponza/Assets/fabric_b_e8dd2769dc642ab7.ankimesh


BIN
Samples/Sponza/Assets/leaf_3a245efd17475037.ankimesh


BIN
Samples/Sponza/Assets/lion.ankitex


BIN
Samples/Sponza/Assets/lion_ddn.ankitex


BIN
Samples/Sponza/Assets/material_baseColor.ankitex


BIN
Samples/Sponza/Assets/material_metallicRoughness.ankitex


BIN
Samples/Sponza/Assets/skinFace_baseColor.ankitex


BIN
Samples/Sponza/Assets/skinFace_metallicRoughness.ankitex


BIN
Samples/Sponza/Assets/skinFace_normal.ankitex


BIN
Samples/Sponza/Assets/sponza_381_d80b7e06247cf847.ankimesh


BIN
Samples/Sponza/Assets/sponza_arch_ddn.ankitex


BIN
Samples/Sponza/Assets/sponza_arch_ddn.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_arch_diff.ankitex


BIN
Samples/Sponza/Assets/sponza_arch_diff.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_arch_spec.ankitex


BIN
Samples/Sponza/Assets/sponza_arch_spec.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_bricks_a_ddn.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_bricks_a_diff.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_ceiling_a_diff.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_column_a_ddn.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_column_a_diff.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_column_a_spec.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_column_b_ddn.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_column_b_diff.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_column_c_ddn.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_column_c_diff.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_curtain_green_diff.ankitex.ankitex


BIN
Samples/Sponza/Assets/sponza_details_diff.ankitex


BIN
Samples/Sponza/Assets/sponza_fabric_blue_diff.ankitex


BIN
Samples/Sponza/Assets/sponza_fabric_diff.ankitex


BIN
Samples/Sponza/Assets/sponza_fabric_green_diff.ankitex


BIN
Samples/Sponza/Assets/sponza_flagpole_diff.ankitex


BIN
Samples/Sponza/Assets/sponza_floor_a_diff.ankitex


BIN
Samples/Sponza/Assets/sponza_roof_diff.ankitex


BIN
Samples/Sponza/Assets/sponza_thorn_ddn.ankitex


BIN
Samples/Sponza/Assets/sponza_thorn_diff.ankitex


BIN
Samples/Sponza/Assets/test.ankitex


BIN
Samples/Sponza/Assets/vase_ddn.ankitex


BIN
Samples/Sponza/Assets/vase_dif.ankitex


BIN
Samples/Sponza/Assets/vase_hanging.ankitex.ankitex


BIN
Samples/Sponza/Assets/vase_plant.ankitex.ankitex


BIN
Samples/Sponza/Assets/vase_round.ankitex.ankitex