Panagiotis Christopoulos Charitos 6 år sedan
förälder
incheckning
cee12d9e52

+ 2 - 2
samples/sponza/assets/scene.lua

@@ -142,9 +142,9 @@ node:getSceneNodeBase():getMoveComponent():setLocalTransform(trf)
 
 node = scene:newGlobalIlluminationProbeNode("giprobe0")
 comp = node:getSceneNodeBase():getGlobalIlluminationProbeComponent()
-comp:setBoundingBox(Vec4.new(-35.1133, -16.4224, -22.1445, 0), Vec4.new(35.1133, 16.4224, 22.1445, 0))
+comp:setBoundingBox(Vec4.new(-24.7947, -12.9703, -11.62, 0), Vec4.new(24.7947, 12.9703, 11.62, 0))
 trf = Transform.new()
-trf:setOrigin(Vec4.new(-0.294456, 13.2902, 0, 0))
+trf:setOrigin(Vec4.new(-1.0849, 12.3116, -0.533418, 0))
 rot = Mat3x4.new()
 rot:setAll(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0)
 trf:setRotation(rot)

BIN
samples/sponza/assets/sponza_379.ankimesh


BIN
samples/sponza/assets/sponza_382.ankimesh


+ 3 - 3
shaders/Functions.glsl

@@ -452,19 +452,19 @@ Vec3 colorPerCubeFace(const U32 dir)
 		color = Vec3(1.0, 0.0, 0.0);
 		break;
 	case 1:
-		color = Vec3(0.5, 0.0, 0.0);
+		color = Vec3(0.25, 0.0, 0.0);
 		break;
 	case 2:
 		color = Vec3(0.0, 1.0, 0.0);
 		break;
 	case 3:
-		color = Vec3(0.0, 0.5, 0.0);
+		color = Vec3(0.0, 0.25, 0.0);
 		break;
 	case 4:
 		color = Vec3(0.0, 0.0, 1.0);
 		break;
 	default:
-		color = Vec3(0.0, 0.0, 0.5);
+		color = Vec3(0.0, 0.0, 0.25);
 	}
 	return color;
 }

+ 1 - 1
shaders/GBufferPost.glslp

@@ -74,7 +74,7 @@ void main()
 			k * (CLUSTER_COUNT_X * CLUSTER_COUNT_Y) + U32(in_clusterIJ.y) * CLUSTER_COUNT_X + U32(in_clusterIJ.x);
 
 		idxOffset = u_clusters[clusterIdx];
-		idxOffset = u_lightIndices[idxOffset - 3u]; // Use the offset metadata
+		idxOffset = u_lightIndices[idxOffset - 2u]; // Use the offset metadata
 	}
 
 	// Process decals

+ 40 - 0
shaders/LightFunctions.glsl

@@ -271,3 +271,43 @@ Vec3 sampleAmbientDice(Vec3 posx, Vec3 negx, Vec3 posy, Vec3 negy, Vec3 posz, Ve
 
 	return col;
 }
+
+// Sample the irradiance term from the clipmap
+Vec3 sampleGlobalIllumination(const Vec3 worldPos,
+	const Vec3 normal,
+	const GlobalIlluminationProbe probe,
+	texture3D textures[MAX_VISIBLE_GLOBAL_ILLUMINATION_PROBES],
+	sampler linearAnyClampSampler)
+{
+	// Find the UVW
+	Vec3 uvw = (worldPos - probe.m_aabbMin) / (probe.m_aabbMax - probe.m_aabbMin);
+
+	// The U contains the 6 directions so divide
+	uvw.x /= 6.0;
+
+	// Calmp it to avoid direction leaking
+	uvw.x = clamp(uvw.x, probe.m_halfTexelSizeU, (1.0 / 6.0) - probe.m_halfTexelSizeU);
+
+	// Read the irradiance
+	Vec3 irradiancePerDir[6u];
+	ANKI_UNROLL for(U32 dir = 0u; dir < 6u; ++dir)
+	{
+		// Point to the correct UV
+		Vec3 shiftedUVw = uvw;
+		shiftedUVw.x += probe.m_volumeSizeUOver6 * F32(dir);
+
+		irradiancePerDir[dir] =
+			textureLod(textures[nonuniformEXT(probe.m_textureIndex)], linearAnyClampSampler, shiftedUVw, 0.0).rgb;
+	}
+
+	// Sample the irradiance
+	const Vec3 irradiance = sampleAmbientDice(irradiancePerDir[0],
+		irradiancePerDir[1],
+		irradiancePerDir[2],
+		irradiancePerDir[3],
+		irradiancePerDir[4],
+		irradiancePerDir[5],
+		normal);
+
+	return irradiance;
+}

+ 27 - 0
shaders/LightShading.glslp

@@ -217,5 +217,32 @@ void main()
 
 		out_color += diffIndirect * gbuffer.m_diffuse + finalRefl * env;
 	}
+
+	// Read GI
+	{
+		Vec3 diffIndirect = Vec3(0.0);
+		F32 totalBlendWeight = EPSILON;
+
+		// Loop probes
+		ANKI_LOOP while((idx = u_lightIndices[idxOffset++]) != MAX_U32)
+		{
+			GlobalIlluminationProbe probe = u_giProbes[idx];
+
+			// Compute blend weight
+			const F32 blendWeight = computeProbeBlendWeight(worldPos, probe.m_aabbMin, probe.m_aabbMax, 0.2);
+			totalBlendWeight += blendWeight;
+
+			// Sample
+			const Vec3 c = sampleGlobalIllumination(
+				worldPos, gbuffer.m_normal, probe, u_globalIlluminationTextures, u_trilinearClampSampler);
+			diffIndirect += c * blendWeight;
+		}
+
+		// Normalize
+		diffIndirect /= totalBlendWeight;
+
+		//out_color += diffIndirect * gbuffer.m_diffuse;
+		out_color = diffIndirect;
+	}
 }
 #pragma anki end

+ 4 - 4
shaders/glsl_cpp_common/ClusteredShading.h

@@ -12,7 +12,7 @@
 ANKI_BEGIN_NAMESPACE
 
 // Consts
-const U32 TYPED_OBJECT_COUNT = 6u; // Point lights, spot lights, refl probes, decals, GI probes and fog volumes
+const U32 TYPED_OBJECT_COUNT = 6u; // Point lights, spot lights, refl probes, GI probes, decals and fog volumes
 const F32 INVALID_TEXTURE_INDEX = -1.0f;
 const F32 LIGHT_FRUSTUM_NEAR_PLANE = 0.1f / 4.0f; // The near plane on the shadow map frustums.
 const U32 MAX_SHADOW_CASCADES = 4u;
@@ -112,10 +112,10 @@ struct GlobalIlluminationProbe
 	U32 m_textureIndex;
 
 	Vec3 m_aabbMax;
-	F32 m_padding0;
+	F32 m_volumeSizeUOver6; // textureSize(texArr[m_textureIndex]).x / 6
 
-	Vec3 m_halfTexelSize; // (1.0 / giVolumeTextureSize) / 2.0
-	F32 m_padding1;
+	Vec3 m_padding0;
+	F32 m_halfTexelSizeU; // (1.0 / textureSize(texArr[m_textureIndex]).x) / 2.0
 };
 const U32 SIZEOF_GLOBAL_ILLUMINATION_PROBE = 3u * SIZEOF_VEC4;
 ANKI_SHADER_STATIC_ASSERT(sizeof(GlobalIlluminationProbe) == SIZEOF_GLOBAL_ILLUMINATION_PROBE)

+ 19 - 18
src/anki/renderer/ClusterBin.cpp

@@ -431,24 +431,23 @@ void ClusterBin::binTile(U32 tileIdx, BinCtx& ctx, TileCtx& tileCtx)
 		}
 	}
 
-	// Decals
+	// GI probes
 	{
-		Obb decalBox;
-		for(U i = 0; i < ctx.m_in->m_renderQueue->m_decals.getSize(); ++i)
+		Aabb probeBox;
+		for(U i = 0; i < ctx.m_in->m_renderQueue->m_giProbes.getSize(); ++i)
 		{
-			const DecalQueueElement& decal = ctx.m_in->m_renderQueue->m_decals[i];
-			decalBox.setCenter(decal.m_obbCenter.xyz0());
-			decalBox.setRotation(Mat3x4(decal.m_obbRotation));
-			decalBox.setExtend(decal.m_obbExtend.xyz0());
+			const GlobalIlluminationProbeQueueElement& probe = ctx.m_in->m_renderQueue->m_giProbes[i];
+			probeBox.setMin(probe.m_aabbMin);
+			probeBox.setMax(probe.m_aabbMax);
 
-			if(!insideClusterFrustum(frustumPlanes, decalBox))
+			if(!insideClusterFrustum(frustumPlanes, probeBox))
 			{
 				continue;
 			}
 
 			for(U clusterZ = 0; clusterZ < m_clusterCounts[2]; ++clusterZ)
 			{
-				if(!testCollision(decalBox, clusterBoxes[clusterZ]))
+				if(!testCollision(probeBox, clusterBoxes[clusterZ]))
 				{
 					continue;
 				}
@@ -458,23 +457,24 @@ void ClusterBin::binTile(U32 tileIdx, BinCtx& ctx, TileCtx& tileCtx)
 		}
 	}
 
-	// GI probes
+	// Decals
 	{
-		Aabb probeBox;
-		for(U i = 0; i < ctx.m_in->m_renderQueue->m_giProbes.getSize(); ++i)
+		Obb decalBox;
+		for(U i = 0; i < ctx.m_in->m_renderQueue->m_decals.getSize(); ++i)
 		{
-			const GlobalIlluminationProbeQueueElement& probe = ctx.m_in->m_renderQueue->m_giProbes[i];
-			probeBox.setMin(probe.m_aabbMin);
-			probeBox.setMax(probe.m_aabbMax);
+			const DecalQueueElement& decal = ctx.m_in->m_renderQueue->m_decals[i];
+			decalBox.setCenter(decal.m_obbCenter.xyz0());
+			decalBox.setRotation(Mat3x4(decal.m_obbRotation));
+			decalBox.setExtend(decal.m_obbExtend.xyz0());
 
-			if(!insideClusterFrustum(frustumPlanes, probeBox))
+			if(!insideClusterFrustum(frustumPlanes, decalBox))
 			{
 				continue;
 			}
 
 			for(U clusterZ = 0; clusterZ < m_clusterCounts[2]; ++clusterZ)
 			{
-				if(!testCollision(probeBox, clusterBoxes[clusterZ]))
+				if(!testCollision(decalBox, clusterBoxes[clusterZ]))
 				{
 					continue;
 				}
@@ -800,7 +800,8 @@ void ClusterBin::writeTypedObjectsToGpuBuffers(BinCtx& ctx) const
 			out.m_aabbMin = in.m_aabbMin;
 			out.m_aabbMax = in.m_aabbMax;
 			out.m_textureIndex = &in - &rqueue.m_giProbes.getFront();
-			out.m_halfTexelSize = 1.0f / Vec3(in.m_cellCounts.x(), in.m_cellCounts.y(), in.m_cellCounts.z()) * 0.5f;
+			out.m_volumeSizeUOver6 = F32(in.m_cellCounts.x()) / 6.0f;
+			out.m_halfTexelSizeU = 1.0f / in.m_cellCounts.x() / 2.0f;
 		}
 	}
 	else