Browse Source

Irradiance probe indirect lighting mostly functional

BearishSun 8 years ago
parent
commit
e0216b09ff

+ 2 - 1
Data/Raw/Engine/Shaders/IrradianceEvaluate.bsl

@@ -104,7 +104,8 @@ technique IrradianceEvaluate
 				ProbeVolume volume = gProbeVolumes[volumeIdx];
 				
 				float3 P = NDCToWorld(input.screenPos, surfaceData.depth);
-				float3 factors = mul(volume.transform, float4(P, 1.0f));			
+				float3 offset = float3(volume.transform[0][3], volume.transform[1][3], volume.transform[2][3]);
+				float3 factors = mul((float3x3)volume.transform, P - offset);			
 				float4 coords = float4(factors, 1.0f - factors.x - factors.y - factors.z);
 				
 				// Ignore extra points we added to make the volume cover everything

+ 5 - 0
Data/Raw/Engine/Shaders/TetrahedraRender.bsl

@@ -4,6 +4,11 @@ technique TetrahedraRender
 	{
 		cull = cw;
 	};
+	
+	depth
+	{
+		compare = lte;
+	};
 
 	code
 	{

+ 7 - 5
Source/BansheeCore/Include/BsCorePrerequisites.h

@@ -344,8 +344,9 @@ namespace bs
 	class GraphicsPipelineState;
 	class ComputePipelineState;
 	class ReflectionProbe;
-    class CReflectionProbe;
-    class CSkybox;
+	class CReflectionProbe;
+	class CSkybox;
+	class CLightProbeVolume;
 	// Asset import
 	class SpecificImporter;
 	class Importer;
@@ -447,7 +448,7 @@ namespace bs
 		class RenderStateManager;
 		class HardwareBufferManager;
 		class ReflectionProbe;
-        class Skybox;
+		class Skybox;
 	}
 }
 
@@ -652,8 +653,9 @@ namespace bs
 	typedef GameObjectHandle<CFixedJoint> HFixedJoint;
 	typedef GameObjectHandle<CD6Joint> HD6Joint;
 	typedef GameObjectHandle<CCharacterController> HCharacterController;
-    typedef GameObjectHandle<CReflectionProbe> HReflectionProbe;
-    typedef GameObjectHandle<CSkybox> HSkybox;
+	typedef GameObjectHandle<CReflectionProbe> HReflectionProbe;
+	typedef GameObjectHandle<CSkybox> HSkybox;
+	typedef GameObjectHandle<CLightProbeVolume> HLightProbeVolume;
 
 	/** @} */
 }

+ 5 - 1
Source/BansheeCore/Include/BsLightProbeVolume.h

@@ -73,6 +73,10 @@ namespace bs
 	/** Vector representing spherical harmonic coefficients for a light probe. */
 	struct LightProbeSHCoefficients
 	{
+		LightProbeSHCoefficients()
+			:coeffsR(), coeffsG(), coeffsB()
+		{ }
+
 		float coeffsR[9];
 		float coeffsG[9];
 		float coeffsB[9];
@@ -99,7 +103,7 @@ namespace bs
 		{
 			ProbeInfo() {}
 			ProbeInfo(LightProbeFlags flags, const Vector3& position)
-				:flags(flags), position(position) 
+				:flags(flags), position(position)
 			{ }
 
 			LightProbeFlags flags;

+ 37 - 17
Source/BansheeCore/Include/BsPixelData.h

@@ -83,40 +83,60 @@ namespace bs
 		PF_RG8I					BS_SCRIPT_EXPORT(n:RG8I) = 36,
 		/** 8-bit 4-channel pixel format, signed integer. */
 		PF_RGBA8I				BS_SCRIPT_EXPORT(n:RGBA8I) = 37,
+		/** 8-bit 1-channel pixel format, unsigned integer. */
+		PF_R8U					BS_SCRIPT_EXPORT(n:R8U) = 38,
+		/** 8-bit 2-channel pixel format, unsigned integer. */
+		PF_RG8U					BS_SCRIPT_EXPORT(n:RG8U) = 39,
+		/** 8-bit 4-channel pixel format, unsigned integer. */
+		PF_RGBA8U				BS_SCRIPT_EXPORT(n:RGBA8U) = 40,
 		/** 8-bit 1-channel pixel format, signed normalized. */
-		PF_R8S					BS_SCRIPT_EXPORT(n:R8S) = 38,
+		PF_R8S					BS_SCRIPT_EXPORT(n:R8S) = 41,
 		/** 8-bit 2-channel pixel format, signed normalized. */
-		PF_RG8S					BS_SCRIPT_EXPORT(n:RG8S) = 39,
+		PF_RG8S					BS_SCRIPT_EXPORT(n:RG8S) = 42,
 		/** 8-bit 4-channel pixel format, signed normalized. */
-		PF_RGBA8S				BS_SCRIPT_EXPORT(n:RGBA8S) = 40,
+		PF_RGBA8S				BS_SCRIPT_EXPORT(n:RGBA8S) = 43,
 		/** 16-bit 1-channel pixel format, signed integer. */
-		PF_R16I					BS_SCRIPT_EXPORT(n:R16I) = 41,
+		PF_R16I					BS_SCRIPT_EXPORT(n:R16I) = 44,
 		/** 16-bit 2-channel pixel format, signed integer. */
-		PF_RG16I				BS_SCRIPT_EXPORT(n:RG16I) = 42,
+		PF_RG16I				BS_SCRIPT_EXPORT(n:RG16I) = 45,
 		/** 16-bit 4-channel pixel format, signed integer. */
-		PF_RGBA16I				BS_SCRIPT_EXPORT(n:RGBA16I) = 43,
+		PF_RGBA16I				BS_SCRIPT_EXPORT(n:RGBA16I) = 46,
+		/** 16-bit 1-channel pixel format, unsigned integer. */
+		PF_R16U					BS_SCRIPT_EXPORT(n:R16U) = 47,
+		/** 16-bit 2-channel pixel format, unsigned integer. */
+		PF_RG16U				BS_SCRIPT_EXPORT(n:RG16U) = 48,
+		/** 16-bit 4-channel pixel format, unsigned integer. */
+		PF_RGBA16U				BS_SCRIPT_EXPORT(n:RGBA16U) = 49,
 		/** 32-bit 1-channel pixel format, signed integer. */
-		PF_R32I					BS_SCRIPT_EXPORT(n:R32I) = 44,
+		PF_R32I					BS_SCRIPT_EXPORT(n:R32I) = 50,
 		/** 32-bit 2-channel pixel format, signed integer. */
-		PF_RG32I				BS_SCRIPT_EXPORT(n:RG32I) = 45,
+		PF_RG32I				BS_SCRIPT_EXPORT(n:RG32I) = 51,
 		/** 32-bit 3-channel pixel format, signed integer. */
-		PF_RGB32I				BS_SCRIPT_EXPORT(n:RGB32I) = 46,
+		PF_RGB32I				BS_SCRIPT_EXPORT(n:RGB32I) = 52,
 		/** 32-bit 4-channel pixel format, signed integer. */
-		PF_RGBA32I				BS_SCRIPT_EXPORT(n:RGBA32I) = 47,
+		PF_RGBA32I				BS_SCRIPT_EXPORT(n:RGBA32I) = 53,
+		/** 32-bit 1-channel pixel format, unsigned integer. */
+		PF_R32U					BS_SCRIPT_EXPORT(n:R32U) = 54,
+		/** 32-bit 2-channel pixel format, unsigned integer. */
+		PF_RG32U				BS_SCRIPT_EXPORT(n:RG32U) = 55,
+		/** 32-bit 3-channel pixel format, unsigned integer. */
+		PF_RGB32U				BS_SCRIPT_EXPORT(n:RGB32U) = 56,
+		/** 32-bit 4-channel pixel format, unsigned integer. */
+		PF_RGBA32U				BS_SCRIPT_EXPORT(n:RGBA32U) = 57,
 		/** 16-bit 1-channel pixel format, signed normalized. */
-		PF_R16S					BS_SCRIPT_EXPORT(n:R16S) = 48,
+		PF_R16S					BS_SCRIPT_EXPORT(n:R16S) = 58,
 		/** 16-bit 2-channel pixel format, signed normalized. */
-		PF_RG16S				BS_SCRIPT_EXPORT(n:RG16S) = 49,
+		PF_RG16S				BS_SCRIPT_EXPORT(n:RG16S) = 59,
 		/** 16-bit 4-channel pixel format, signed normalized. */
-		PF_RGBA16S				BS_SCRIPT_EXPORT(n:RGBA16S) = 50,
+		PF_RGBA16S				BS_SCRIPT_EXPORT(n:RGBA16S) = 60,
 		/** 16-bit 1-channel pixel format, unsigned normalized. */
-		PF_R16					BS_SCRIPT_EXPORT(n:R16) = 51,
+		PF_R16					BS_SCRIPT_EXPORT(n:R16) = 61,
 		/** 16-bit 2-channel pixel format, unsigned normalized. */
-		PF_RG16					BS_SCRIPT_EXPORT(n:RG16) = 52,
+		PF_RG16					BS_SCRIPT_EXPORT(n:RG16) = 62,
 		/** 16-bit 3-channel pixel format, unsigned normalized. */
-		PF_RGB16				BS_SCRIPT_EXPORT(n:RGB16) = 53,
+		PF_RGB16				BS_SCRIPT_EXPORT(n:RGB16) = 63,
 		/** 16-bit 4-channel pixel format, unsigned normalized. */
-		PF_RGBA16				BS_SCRIPT_EXPORT(n:RGBA16) = 54,
+		PF_RGBA16				BS_SCRIPT_EXPORT(n:RGBA16) = 64,
 		/** Number of pixel formats currently defined. */
 		PF_COUNT				BS_SCRIPT_EXPORT(ex:true)
 	};

+ 8 - 5
Source/BansheeCore/Source/BsLightProbeVolume.cpp

@@ -128,9 +128,9 @@ namespace bs
 			UINT32 z = (idx / slicePitch);
 
 			Vector3 position = mVolume.getMin();
-			position.x += size.x * (x / (float)numProbesX);
-			position.y += size.y * (y / (float)numProbesY);
-			position.z += size.z * (z / (float)numProbesZ);
+			position.x += size.x * (x / (float)(numProbesX - 1));
+			position.y += size.y * (y / (float)(numProbesY - 1));
+			position.z += size.z * (z / (float)(numProbesZ - 1));
 
 			iter->second.position = position;
 			iter->second.flags = LightProbeFlags::Clean;
@@ -378,6 +378,8 @@ namespace bs
 	LightProbeVolume::LightProbeVolume(const UnorderedMap<UINT32, bs::LightProbeVolume::ProbeInfo>& probes)
 	{
 		mInitCoefficients.resize(probes.size());
+		mProbePositions.resize(probes.size());
+		mProbeInfos.resize(probes.size());
 
 		UINT32 probeIdx = 0;
 		for(auto& entry : probes)
@@ -433,8 +435,8 @@ namespace bs
 				TEXTURE_DESC cubemapDesc;
 				cubemapDesc.type = TEX_TYPE_CUBE_MAP;
 				cubemapDesc.format = PF_RGBA16F;
-				cubemapDesc.width = IBLUtility::IRRADIANCE_CUBEMAP_SIZE;
-				cubemapDesc.height = IBLUtility::IRRADIANCE_CUBEMAP_SIZE;
+				cubemapDesc.width = 256; // Note: Test different sizes and their effect on quality
+				cubemapDesc.height = 256;
 				cubemapDesc.usage = TU_STATIC | TU_RENDERTARGET;
 
 				SPtr<Texture> cubemap = Texture::create(cubemapDesc);
@@ -608,6 +610,7 @@ namespace bs
 		desc.elementCount = count;
 		desc.usage = GBU_STATIC;
 		desc.format = BF_UNKNOWN;
+		desc.randomGpuWrite = true;
 
 		SPtr<GpuBuffer> newBuffer = GpuBuffer::create(desc);
 		if (mCoefficients)

+ 146 - 6
Source/BansheeCore/Source/BsPixelUtil.cpp

@@ -760,7 +760,7 @@ namespace bs
 		/* Bytes per element */
 		1,
 		/* Flags */
-		PFF_INTEGER,
+		PFF_INTEGER | PFF_SIGNED,
 		/* Component type and count */
 		PCT_BYTE, 1,
 		/* rbits, gbits, bbits, abits */
@@ -774,7 +774,7 @@ namespace bs
 		/* Bytes per element */
 		2,
 		/* Flags */
-		PFF_INTEGER,
+		PFF_INTEGER | PFF_SIGNED,
 		/* Component type and count */
 		PCT_BYTE, 2,
 		/* rbits, gbits, bbits, abits */
@@ -788,6 +788,48 @@ namespace bs
 		/* Bytes per element */
 		4,
 		/* Flags */
+		PFF_INTEGER | PFF_SIGNED | PFF_HASALPHA,
+		/* Component type and count */
+		PCT_BYTE, 4,
+		/* rbits, gbits, bbits, abits */
+		8, 8, 8, 8,
+		/* Masks and shifts */
+		0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000,
+		0, 8, 16, 24,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_R8U",
+		/* Bytes per element */
+		1,
+		/* Flags */
+		PFF_INTEGER,
+		/* Component type and count */
+		PCT_BYTE, 1,
+		/* rbits, gbits, bbits, abits */
+		8, 0, 0, 0,
+		/* Masks and shifts */
+		0x000000FF, 0, 0, 0, 
+		0, 0, 0, 0,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_RG8U",
+		/* Bytes per element */
+		2,
+		/* Flags */
+		PFF_INTEGER,
+		/* Component type and count */
+		PCT_BYTE, 2,
+		/* rbits, gbits, bbits, abits */
+		8, 8, 0, 0,
+		/* Masks and shifts */
+		0x000000FF, 0x0000FF00, 0, 0, 
+		0, 8, 0, 0,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_RGBA8U",
+		/* Bytes per element */
+		4,
+		/* Flags */
 		PFF_INTEGER | PFF_HASALPHA,
 		/* Component type and count */
 		PCT_BYTE, 4,
@@ -844,7 +886,7 @@ namespace bs
 		/* Bytes per element */
 		2,
 		/* Flags */
-		PFF_INTEGER,
+		PFF_INTEGER | PFF_SIGNED,
 		/* Component type and count */
 		PCT_SHORT, 1,
 		/* rbits, gbits, bbits, abits */
@@ -858,7 +900,7 @@ namespace bs
 		/* Bytes per element */
 		4,
 		/* Flags */
-		PFF_INTEGER,
+		PFF_INTEGER | PFF_SIGNED,
 		/* Component type and count */
 		PCT_SHORT, 2,
 		/* rbits, gbits, bbits, abits */
@@ -872,6 +914,48 @@ namespace bs
 		/* Bytes per element */
 		8,
 		/* Flags */
+		PFF_INTEGER | PFF_SIGNED | PFF_HASALPHA,
+		/* Component type and count */
+		PCT_SHORT, 4,
+		/* rbits, gbits, bbits, abits */
+		16, 16, 16, 16,
+		/* Masks and shifts */
+		0x0000FFFF, 0xFFFF0000, 0x0000FFFF, 0xFFFF0000, 
+		0, 16, 0, 16,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_R16U",
+		/* Bytes per element */
+		2,
+		/* Flags */
+		PFF_INTEGER,
+		/* Component type and count */
+		PCT_SHORT, 1,
+		/* rbits, gbits, bbits, abits */
+		16, 0, 0, 0,
+		/* Masks and shifts */
+		0x0000FFFF, 0, 0, 0, 
+		0, 0, 0, 0,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_RG16U",
+		/* Bytes per element */
+		4,
+		/* Flags */
+		PFF_INTEGER,
+		/* Component type and count */
+		PCT_SHORT, 2,
+		/* rbits, gbits, bbits, abits */
+		16, 16, 0, 0,
+		/* Masks and shifts */
+		0x0000FFFF, 0xFFFF0000, 0, 0, 
+		0, 16, 0, 0,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_RGBA16U",
+		/* Bytes per element */
+		8,
+		/* Flags */
 		PFF_INTEGER | PFF_HASALPHA,
 		/* Component type and count */
 		PCT_SHORT, 4,
@@ -900,7 +984,7 @@ namespace bs
 		/* Bytes per element */
 		8,
 		/* Flags */
-		PFF_INTEGER,
+		PFF_INTEGER | PFF_SIGNED,
 		/* Component type and count */
 		PCT_INT, 2,
 		/* rbits, gbits, bbits, abits */
@@ -914,7 +998,7 @@ namespace bs
 		/* Bytes per element */
 		12,
 		/* Flags */
-		PFF_INTEGER,
+		PFF_INTEGER | PFF_SIGNED,
 		/* Component type and count */
 		PCT_INT, 3,
 		/* rbits, gbits, bbits, abits */
@@ -928,6 +1012,62 @@ namespace bs
 		/* Bytes per element */
 		16,
 		/* Flags */
+		PFF_INTEGER | PFF_SIGNED | PFF_HASALPHA,
+		/* Component type and count */
+		PCT_INT, 4,
+		/* rbits, gbits, bbits, abits */
+		32, 32, 32, 32,
+		/* Masks and shifts */
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 
+		0, 0, 0, 0
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_R32U",
+		/* Bytes per element */
+		4,
+		/* Flags */
+		PFF_INTEGER,
+		/* Component type and count */
+		PCT_INT, 1,
+		/* rbits, gbits, bbits, abits */
+		32, 0, 0, 0,
+		/* Masks and shifts */
+		0xFFFFFFFF, 0, 0, 0,
+		0, 0, 0, 0,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_RG32U",
+		/* Bytes per element */
+		8,
+		/* Flags */
+		PFF_INTEGER,
+		/* Component type and count */
+		PCT_INT, 2,
+		/* rbits, gbits, bbits, abits */
+		32, 32, 0, 0,
+		/* Masks and shifts */
+		0xFFFFFFFF, 0xFFFFFFFF, 0, 0,
+		0, 0, 0, 0,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_RGB32U",
+		/* Bytes per element */
+		12,
+		/* Flags */
+		PFF_INTEGER,
+		/* Component type and count */
+		PCT_INT, 3,
+		/* rbits, gbits, bbits, abits */
+		32, 32, 32, 0,
+		/* Masks and shifts */
+		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0,
+		0, 0, 0, 0,
+		},
+	//-----------------------------------------------------------------------
+		{ "PF_RGBA32U",
+		/* Bytes per element */
+		16,
+		/* Flags */
 		PFF_INTEGER | PFF_HASALPHA,
 		/* Component type and count */
 		PCT_INT, 4,

+ 30 - 12
Source/BansheeD3D11RenderAPI/Source/BsD3D11Mappings.cpp

@@ -415,7 +415,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R32G32B32A32_FLOAT:
 			return PF_RGBA32F;
 		case DXGI_FORMAT_R32G32B32A32_UINT:
-			return PF_UNKNOWN;
+			return PF_RGBA32U;
 		case DXGI_FORMAT_R32G32B32A32_SINT:
 			return PF_RGBA32I;
 		case DXGI_FORMAT_R32G32B32_TYPELESS:
@@ -423,7 +423,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R32G32B32_FLOAT:
 			return PF_RGB32F;
 		case DXGI_FORMAT_R32G32B32_UINT:
-			return PF_UNKNOWN;
+			return PF_RGB32U;
 		case DXGI_FORMAT_R32G32B32_SINT:
 			return PF_RGB32I;
 		case DXGI_FORMAT_R16G16B16A16_TYPELESS:
@@ -433,7 +433,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R16G16B16A16_UNORM:
 			return PF_RGBA16;
 		case DXGI_FORMAT_R16G16B16A16_UINT:
-			return PF_UNKNOWN;
+			return PF_RGBA16U;
 		case DXGI_FORMAT_R16G16B16A16_SNORM:
 			return PF_RGBA16S;
 		case DXGI_FORMAT_R16G16B16A16_SINT:
@@ -443,7 +443,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R32G32_FLOAT:
 			return PF_RG32F;
 		case DXGI_FORMAT_R32G32_UINT:
-			return PF_UNKNOWN;
+			return PF_RG32U;
 		case DXGI_FORMAT_R32G32_SINT:
 			return PF_RG32I;
 		case DXGI_FORMAT_R32G8X24_TYPELESS:
@@ -468,7 +468,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
 			return PF_RGBA8;
 		case DXGI_FORMAT_R8G8B8A8_UINT:
-			return PF_UNKNOWN;
+			return PF_RGBA8U;
 		case DXGI_FORMAT_R8G8B8A8_SNORM:
 			return PF_RGBA8S;
 		case DXGI_FORMAT_R8G8B8A8_SINT:
@@ -480,7 +480,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R16G16_UNORM:
 			return PF_RG16;
 		case DXGI_FORMAT_R16G16_UINT:
-			return PF_UNKNOWN;
+			return PF_RG16U;
 		case DXGI_FORMAT_R16G16_SNORM:
 			return PF_RG16S;
 		case DXGI_FORMAT_R16G16_SINT:
@@ -492,7 +492,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R32_FLOAT:
 			return PF_R32F;
 		case DXGI_FORMAT_R32_UINT:
-			return PF_UNKNOWN;
+			return PF_R32U;
 		case DXGI_FORMAT_R32_SINT:
 			return PF_R32I;
 		case DXGI_FORMAT_R24G8_TYPELESS:
@@ -508,7 +508,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R8G8_UNORM:
 			return PF_RG8;
 		case DXGI_FORMAT_R8G8_UINT:
-			return PF_UNKNOWN;
+			return PF_RG8U;
 		case DXGI_FORMAT_R8G8_SNORM:
 			return PF_RG8S;
 		case DXGI_FORMAT_R8G8_SINT:
@@ -522,7 +522,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R16_UNORM:
 			return PF_R16;
 		case DXGI_FORMAT_R16_UINT:
-			return PF_UNKNOWN;
+			return PF_R16U;
 		case DXGI_FORMAT_R16_SNORM:
 			return PF_R16S;
 		case DXGI_FORMAT_R16_SINT:
@@ -532,7 +532,7 @@ namespace bs { namespace ct
 		case DXGI_FORMAT_R8_UNORM:
 			return PF_R8;
 		case DXGI_FORMAT_R8_UINT:
-			return PF_UNKNOWN;
+			return PF_R8U;
 		case DXGI_FORMAT_R8_SNORM:
 			return PF_R8S;
 		case DXGI_FORMAT_R8_SINT:
@@ -610,12 +610,16 @@ namespace bs { namespace ct
 			return DXGI_FORMAT_R8_SNORM;
 		case PF_R8I:
 			return DXGI_FORMAT_R8_SINT;
+		case PF_R8U:
+			return DXGI_FORMAT_R8_UINT;
 		case PF_RG8:
 			return DXGI_FORMAT_R8G8_UNORM; 
 		case PF_RG8S:
 			return DXGI_FORMAT_R8G8_SNORM; 
 		case PF_RG8I:
 			return DXGI_FORMAT_R8G8_SINT; 
+		case PF_RG8U:
+			return DXGI_FORMAT_R8G8_UINT; 
 		case PF_BGR8:
 			if (gamma)
 				return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
@@ -627,6 +631,8 @@ namespace bs { namespace ct
 			return DXGI_FORMAT_R8G8B8A8_UNORM;
 		case PF_RGBA8I:
 			return DXGI_FORMAT_R8G8B8A8_SINT;
+		case PF_RGBA8U:
+			return DXGI_FORMAT_R8G8B8A8_UINT;
 		case PF_RGBA8S:
 			return DXGI_FORMAT_R8G8B8A8_SNORM;
 		case PF_BGRA8:
@@ -653,14 +659,26 @@ namespace bs { namespace ct
 			return DXGI_FORMAT_R16G16_SINT;
 		case PF_RGBA16I:
 			return DXGI_FORMAT_R16G16B16A16_SINT;
+		case PF_R16U:
+			return DXGI_FORMAT_R16_UINT;
+		case PF_RG16U:
+			return DXGI_FORMAT_R16G16_UINT;
+		case PF_RGBA16U:
+			return DXGI_FORMAT_R16G16B16A16_UINT;
 		case PF_R32I:
 			return DXGI_FORMAT_R32_SINT;
 		case PF_RG32I:
 			return DXGI_FORMAT_R32G32_SINT;
 		case PF_RGB32I:
 			return DXGI_FORMAT_R32G32B32_SINT;
-		case PF_RGBA32I:
-			return DXGI_FORMAT_R32G32B32A32_SINT;
+		case PF_R32U:
+			return DXGI_FORMAT_R32_UINT;
+		case PF_RG32U:
+			return DXGI_FORMAT_R32G32_UINT;
+		case PF_RGB32U:
+			return DXGI_FORMAT_R32G32B32_UINT;
+		case PF_RGBA32U:
+			return DXGI_FORMAT_R32G32B32A32_UINT;
 		case PF_R16S:
 			return DXGI_FORMAT_R16_SNORM;
 		case PF_RG16S:

+ 41 - 0
Source/BansheeGLRenderAPI/Source/BsGLPixelFormat.cpp

@@ -23,10 +23,12 @@ namespace bs { namespace ct
 		{
 		case PF_R8:
 		case PF_R8I:
+		case PF_R8U:
 		case PF_R8S:
 			return GL_RED;
 		case PF_RG8:
 		case PF_RG8I:
+		case PF_RG8U:
 		case PF_RG8S:
 			return GL_RG;
 		case PF_RGB8:
@@ -35,36 +37,44 @@ namespace bs { namespace ct
 			return GL_BGR;
 		case PF_RGBA8:
 		case PF_RGBA8I:
+		case PF_RGBA8U:
 		case PF_RGBA8S:
 			return GL_RGBA;
 		case PF_BGRA8:
 			return GL_BGRA;
 		case PF_R16F:
 		case PF_R16I:
+		case PF_R16U:
 		case PF_R16S:
 		case PF_R16:
 			return GL_RED;
 		case PF_RG16F:
 		case PF_RG16I:
+		case PF_RG16U:
 		case PF_RG16S:
 		case PF_RG16:
 			return GL_RG;
 		case PF_RGBA16F:
 		case PF_RGBA16I:
+		case PF_RGBA16U:
 		case PF_RGBA16S:
 		case PF_RGBA16:
 			return GL_RGBA;
 		case PF_R32F:
 		case PF_R32I:
+		case PF_R32U:
 			return GL_RED;
 		case PF_RG32F:
 		case PF_RG32I:
+		case PF_RG32U:
 			return GL_RG;
 		case PF_RGB32F:
 		case PF_RGB32I:
+		case PF_RGB32U:
 			return GL_RGB;
 		case PF_RGBA32F:
 		case PF_RGBA32I:
+		case PF_RGBA32U:
 			return GL_RGBA;
 		case PF_RG11B10F:
 			return GL_RGB;
@@ -94,6 +104,9 @@ namespace bs { namespace ct
 		case PF_RG8:
 		case PF_RGB8:
 		case PF_BGR8:
+		case PF_R8U:
+		case PF_RG8U:
+		case PF_RGBA8U:
 			return GL_UNSIGNED_BYTE;
 		case PF_BGRA8:
 		case PF_RGBA8:
@@ -115,6 +128,9 @@ namespace bs { namespace ct
 		case PF_R16:
 		case PF_RG16:
 		case PF_RGBA16:
+		case PF_R16U:
+		case PF_RG16U:
+		case PF_RGBA16U:
 			return GL_UNSIGNED_SHORT;
 		case PF_R16F:
 		case PF_RG16F:
@@ -125,6 +141,11 @@ namespace bs { namespace ct
 		case PF_RGB32I:
 		case PF_RGBA32I:
 			return GL_INT;
+		case PF_R32U:
+		case PF_RG32U:
+		case PF_RGB32U:
+		case PF_RGBA32U:
+			return GL_UNSIGNED_INT;
 		case PF_R32F:
 		case PF_RG32F:
 		case PF_RGB32F:
@@ -146,12 +167,16 @@ namespace bs { namespace ct
 			return GL_R8;
 		case PF_R8I:
 			return GL_R8I;
+		case PF_R8U:
+			return GL_R8UI;
 		case PF_R8S:
 			return GL_R8_SNORM;
 		case PF_RG8:
 			return GL_RG8;
 		case PF_RG8I:
 			return GL_RG8I;
+		case PF_RG8U:
+			return GL_RG8UI;
 		case PF_RG8S:
 			return GL_RG8_SNORM;
 		case PF_RGB8:
@@ -168,12 +193,16 @@ namespace bs { namespace ct
 				return GL_RGBA8;
 		case PF_RGBA8I:
 			return GL_RGBA8I;
+		case PF_RGBA8U:
+			return GL_RGBA8UI;
 		case PF_RGBA8S:
 			return GL_RGBA8_SNORM;
 		case PF_R16F:
 			return GL_R16F;
 		case PF_R16I:
 			return GL_R16I;
+		case PF_R16U:
+			return GL_R16UI;
 		case PF_R16S:
 			return GL_R16_SNORM;
 		case PF_R16:
@@ -182,6 +211,8 @@ namespace bs { namespace ct
 			return GL_RG16F;
 		case PF_RG16I:
 			return GL_RG16I;
+		case PF_RG16U:
+			return GL_RG16UI;
 		case PF_RG16S:
 			return GL_RG16_SNORM;
 		case PF_RG16:
@@ -190,6 +221,8 @@ namespace bs { namespace ct
 			return GL_RGBA16F;
 		case PF_RGBA16I:
 			return GL_RGBA16I;
+		case PF_RGBA16U:
+			return GL_RGBA16UI;
 		case PF_RGBA16S:
 			return GL_RGBA16_SNORM;
 		case PF_RGBA16:
@@ -198,18 +231,26 @@ namespace bs { namespace ct
 			return GL_R32F;
 		case PF_R32I:
 			return GL_R32I;
+		case PF_R32U:
+			return GL_R32UI;
 		case PF_RG32F:
 			return GL_RG32F;
 		case PF_RG32I:
 			return GL_RG32I;
+		case PF_RG32U:
+			return GL_RG32UI;
 		case PF_RGB32F:
 			return GL_RGB32F;
 		case PF_RGB32I:
 			return GL_RGB32I;
+		case PF_RGB32U:
+			return GL_RGB32UI;
 		case PF_RGBA32F:
 			return GL_RGBA32F;
 		case PF_RGBA32I:
 			return GL_RGBA32I;
+		case PF_RGBA32U:
+			return GL_RGBA32UI;
 		case PF_BC1a:
 		case PF_BC1:
 			if (hwGamma)

+ 1 - 1
Source/BansheeUtility/Include/BsVectorNI.h

@@ -29,7 +29,7 @@ namespace bs
 
 		VectorNI(std::initializer_list<INT32> list)
 		{
-			assert(list.size() < N);
+			assert(list.size() <= N);
 			std::copy(list.begin(), list.end(), v);
 		}
 

+ 20 - 0
Source/BansheeVulkanRenderAPI/Source/BsVulkanUtility.cpp

@@ -110,6 +110,12 @@ namespace bs { namespace ct
 			return VK_FORMAT_R8G8_SINT;
 		case PF_RGBA8I:
 			return VK_FORMAT_R8G8B8A8_SINT;
+		case PF_R8U:
+			return VK_FORMAT_R8_UINT;
+		case PF_RG8U:
+			return VK_FORMAT_R8G8_UINT;
+		case PF_RGBA8U:
+			return VK_FORMAT_R8G8B8A8_UINT;
 		case PF_R8S:
 			return VK_FORMAT_R8_SNORM;
 		case PF_RG8S:
@@ -136,6 +142,12 @@ namespace bs { namespace ct
 			return VK_FORMAT_R16G16_SINT;
 		case PF_RGBA16I:
 			return VK_FORMAT_R16G16B16A16_SINT;
+		case PF_R16U:
+			return VK_FORMAT_R16_UINT;
+		case PF_RG16U:
+			return VK_FORMAT_R16G16_UINT;
+		case PF_RGBA16U:
+			return VK_FORMAT_R16G16B16A16_UINT;
 		case PF_R32I:
 			return VK_FORMAT_R32_SINT;
 		case PF_RG32I:
@@ -144,6 +156,14 @@ namespace bs { namespace ct
 			return VK_FORMAT_R32G32B32_SINT;
 		case PF_RGBA32I:
 			return VK_FORMAT_R32G32B32A32_SINT;
+		case PF_R32U:
+			return VK_FORMAT_R32_UINT;
+		case PF_RG32U:
+			return VK_FORMAT_R32G32_UINT;
+		case PF_RGB32U:
+			return VK_FORMAT_R32G32B32_UINT;
+		case PF_RGBA32U:
+			return VK_FORMAT_R32G32B32A32_UINT;
 		case PF_R16S:
 			return VK_FORMAT_R16_SNORM;
 		case PF_RG16S:

+ 9 - 2
Source/CMakeLists.txt

@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 3.7.2)
+cmake_minimum_required (VERSION 3.9.0)
 project (Banshee)
 
 # Version
@@ -300,6 +300,13 @@ if(MSVC)
 		include_external_msproject(MBansheeEngine ${PROJECT_SOURCE_DIR}/MBansheeEngine/MBansheeEngine.csproj)
 		include_external_msproject(MBansheeEditor ${PROJECT_SOURCE_DIR}/MBansheeEditor/MBansheeEditor.csproj)
 		
+		set_target_properties(MBansheeEngine PROPERTIES
+		  MAP_IMPORTED_CONFIG_RELEASE OptimizedDebug
+		)
+		set_target_properties(MBansheeEditor PROPERTIES
+		  MAP_IMPORTED_CONFIG_RELEASE OptimizedDebug
+		)
+		
 		set_property(TARGET MBansheeEngine PROPERTY FOLDER Script)
 		set_property(TARGET MBansheeEditor PROPERTY FOLDER Script)
 		
@@ -310,4 +317,4 @@ if(MSVC)
 	endif()
 else()
 # TODO - Use Mono compiler to build the managed code as a pre-build step
-endif()
+endif()

+ 45 - 25
Source/RenderBeast/Source/BsLightProbes.cpp

@@ -91,7 +91,7 @@ namespace bs { namespace ct
 		UINT32 height = viewProps.viewRect.height;
 		UINT32 numSamples = viewProps.numSamples;
 
-		colorDesc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R16I, width, height, TU_RENDERTARGET, numSamples);
+		colorDesc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_R16U, width, height, TU_RENDERTARGET, numSamples);
 		depthDesc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_D16, width, height, TU_DEPTHSTENCIL, numSamples);
 	}
 
@@ -284,21 +284,17 @@ namespace bs { namespace ct
 			resizeCoefficientBuffer(newSize);
 		}
 
-		UINT8* dest = (UINT8*)mProbeCoefficientsGPU->lock(0, mProbeCoefficientsGPU->getSize(), GBL_WRITE_ONLY_DISCARD);
+		UINT32 writePos = 0;
 		for(auto& entry : mVolumes)
 		{
 			UINT32 numProbes = (UINT32)entry.volume->getLightProbePositions().size();
+			UINT32 size = numProbes * sizeof(LightProbeSHCoefficients);
 			SPtr<GpuBuffer> localBuffer = entry.volume->getCoefficientsBuffer();
 			
 			// Note: Some of the coefficients might still be dirty (unrendered). Check for this and write them as black?
-			UINT32 size = numProbes * sizeof(LightProbeSHCoefficients);
-			UINT8* src = (UINT8*)localBuffer->lock(0, size, GBL_READ_ONLY);
-			memcpy(dest, src, size);
-
-			localBuffer->unlock();
-			dest += size;
+			mProbeCoefficientsGPU->copyData(*localBuffer, 0, writePos, size);
+			writePos += size;
 		}
-		mProbeCoefficientsGPU->unlock();
 
 		// Gather all positions
 		UINT32 bufferOffset = 0;
@@ -327,7 +323,7 @@ namespace bs { namespace ct
 		mTetrahedronInfos.clear();
 
 		UINT32 innerVertexCount = (UINT32)mTempTetrahedronPositions.size();
-		generateTetrahedronData(mTempTetrahedronPositions, mTetrahedronInfos, false);
+		generateTetrahedronData(mTempTetrahedronPositions, mTetrahedronInfos, true);
 
 		// Generate a mesh out of all the tetrahedron triangles
 		// Note: Currently the entire volume is rendered as a single large mesh, which will isn't optimal as we can't
@@ -345,6 +341,7 @@ namespace bs { namespace ct
 		SPtr<MeshData> meshData = MeshData::create(numVertices, numIndices, vertexDesc);
 		auto posIter = meshData->getVec3DataIter(VES_POSITION);
 		auto idIter = meshData->getDWORDDataIter(VES_TEXCOORD);
+		UINT32* indices = meshData->getIndices32();
 
 		UINT32 tetIdx = 0;
 		for(auto& entry : mTetrahedronInfos)
@@ -386,6 +383,12 @@ namespace bs { namespace ct
 				idIter.addValue(tetIdx);
 				idIter.addValue(tetIdx);
 				idIter.addValue(tetIdx);
+
+				indices[0] = tetIdx * 4 * 3 + i * 3 + 0;
+				indices[1] = tetIdx * 4 * 3 + i * 3 + 1;
+				indices[2] = tetIdx * 4 * 3 + i * 3 + 2;
+
+				indices += 3;
 			}
 
 			tetIdx++;
@@ -410,7 +413,7 @@ namespace bs { namespace ct
 				if (entry.volume.vertices[i] >= (INT32)innerVertexCount)
 					entry.volume.vertices[i] = -1;
 				else
-					entry.volume.vertices[i] = mTempTetrahedronBufferIndices[i];
+					entry.volume.vertices[i] = mTempTetrahedronBufferIndices[entry.volume.vertices[i]];
 			}
 
 			memcpy(dst->indices, entry.volume.vertices, sizeof(UINT32) * 4);
@@ -602,7 +605,6 @@ namespace bs { namespace ct
 
 				// For each face, generate outer tetrahedrons
 				Vector<Vector3> outerVolumeVerts;
-				FrameVector<TetrahedronVolume> outerTetrahedra;
 				for (UINT32 i = 0; i < numOuterFaces; ++i)
 				{
 					const TetrahedronFace& face = volume.outerFaces[i];
@@ -619,14 +621,10 @@ namespace bs { namespace ct
 					}
 
 					TetrahedronVolume outerVolume = Triangulation::tetrahedralize(outerVolumeVerts);
-
 					UINT32 tetStartIdx = (UINT32)volume.tetrahedra.size();
+
 					for (auto& entry : outerVolume.tetrahedra)
 					{
-						// Remap vertices back to global array
-						for (UINT32 j = 0; j < 4; j++)
-							entry.vertices[j] = originalIndices[entry.vertices[j]];
-
 						// Remap neighbors to global array
 						for (UINT32 j = 0; j < 4; j++)
 						{
@@ -641,6 +639,7 @@ namespace bs { namespace ct
 					// Connect the new volume to the original face
 					for (auto& entry : outerVolume.outerFaces)
 					{
+						// Look for the face sharing all vertices with the original face
 						bool isValid = true;
 						for (UINT32 j = 0; j < 3; j++)
 						{
@@ -675,11 +674,22 @@ namespace bs { namespace ct
 						for(UINT32 j = 0; j < 4; j++)
 						{
 							if (innerTet.neighbors[j] == -1)
-								innerTet.neighbors[j] = entry.tetrahedron;
+							{
+								// Note: Not searching for opposite neighbor here. If tet. has multiple free faces then we
+								// can't just pick the first one
+								innerTet.neighbors[j] = tetStartIdx + entry.tetrahedron;
+								break;
+							}
 						}
 					}
 
-					outerTetrahedra.push_back(outerVolume);
+					for (auto& entry : outerVolume.tetrahedra)
+					{
+						// Remap vertices back to global array
+						for (UINT32 j = 0; j < 4; j++)
+							entry.vertices[j] = originalIndices[entry.vertices[j]];
+					}
+
 					outerVolumeVerts.clear();
 
 					// Add to global tetrahedra array
@@ -731,13 +741,23 @@ namespace bs { namespace ct
 				const Vector3& P3 = positions[volume.tetrahedra[i].vertices[2]];
 				const Vector3& P4 = positions[volume.tetrahedra[i].vertices[3]];
 
-				Matrix4 mat;
-				mat.setColumn(0, Vector4(P1 - P4, 0.0f));
-				mat.setColumn(1, Vector4(P2 - P4, 0.0f));
-				mat.setColumn(2, Vector4(P3 - P4, 0.0f));
-				mat.setColumn(3, Vector4(P4, 1.0f));
+				Vector3 E1 = P1 - P4;
+				Vector3 E2 = P2 - P4;
+				Vector3 E3 = P3 - P4;
+
+				Matrix3 mat;
+				mat.setColumn(0, E1);
+				mat.setColumn(1, E2);
+				mat.setColumn(2, E3);
+
+				// If tetrahedron is co-planar just ignore it, shader will use some other nearby one instead. We can't
+				// handle coplanar tetrahedrons because the matrix is not invertible, and for nearly co-planar ones the
+				// math breaks down because of precision issues.
+				if (fabs(Vector3::dot(Vector3::normalize(Vector3::cross(E1, E2)), E3)) < 0.0001f)
+					continue;
 
-				entry.transform = mat.inverse();
+				entry.transform = Matrix4(mat.inverse());
+				entry.transform.setColumn(3, Vector4(P4, 1.0f));
 
 				output.push_back(entry);
 			}

+ 6 - 2
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -250,8 +250,6 @@ namespace bs { namespace ct
 			mOptionsDirty = false;
 		}
 		
-		// Execute render tasks, after all scene object information has been synced
-		gCoreThread().queueCommand(std::bind(&RenderBeast::processTasks, this, false));
 		gCoreThread().queueCommand(std::bind(&RenderBeast::renderAllCore, this, gTime().getTime(), gTime().getFrameDelta()));
 	}
 
@@ -281,6 +279,9 @@ namespace bs { namespace ct
 		
 		FrameInfo frameInfo(delta, &animData);
 
+		// Make sure any renderer tasks finish first, as rendering might depend on them
+		processTasks(false);
+
 		// Gather all views
 		Vector<RendererView*> views;
 		for (auto& rtInfo : sceneInfo.renderTargets)
@@ -650,5 +651,8 @@ namespace bs { namespace ct
 
 		FrameInfo frameInfo(1.0f/60.0f);
 		renderViews(viewGroup, frameInfo);
+
+		// Make sure the render texture is available for reads
+		RenderAPI::instance().setRenderTarget(nullptr);
 	}
 }}

+ 4 - 0
Source/RenderBeast/Source/BsRenderCompositor.cpp

@@ -683,6 +683,10 @@ namespace bs { namespace ct
 
 			SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
 
+			RenderAPI& rapi = RenderAPI::instance();
+			rapi.setRenderTarget(rt);
+			rapi.clearRenderTarget(FBT_COLOR | FBT_DEPTH);			
+
 			TetrahedraRenderMat* renderTetrahedra = TetrahedraRenderMat::getVariation(viewProps.numSamples > 1);
 			renderTetrahedra->execute(inputs.view, sceneDepthNode->depthTex->texture, volumeMesh, rt);