Sfoglia il codice sorgente

More additions to the cornell box test

Panagiotis Christopoulos Charitos 5 anni fa
parent
commit
93bee425eb

+ 1 - 0
src/anki/gr/AccelerationStructure.h

@@ -68,6 +68,7 @@ public:
 	AccelerationStructurePtr m_bottomLevel;
 	Mat3x4 m_transform = Mat3x4::getIdentity();
 	U32 m_sbtRecordIndex = 0; ///< Points to the SBT record.
+	U8 m_mask = 0xFF; ///< A mask that this instance belongs to. Will be tested against what's in traceRayEXT().
 };
 
 /// @memberof AccelerationStructureInitInfo

+ 1 - 1
src/anki/gr/vulkan/AccelerationStructureImpl.cpp

@@ -192,7 +192,7 @@ void AccelerationStructureImpl::initBuildInfo()
 				static_assert(sizeof(outInst.transform) == sizeof(inInst.m_transform), "See file");
 				memcpy(&outInst.transform, &inInst.m_transform, sizeof(inInst.m_transform));
 				outInst.instanceCustomIndex = i & 0xFFFFFF;
-				outInst.mask = 0xFF;
+				outInst.mask = inInst.m_mask;
 				outInst.instanceShaderBindingTableRecordOffset = inInst.m_sbtRecordIndex & 0xFFFFFF;
 				outInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR;
 				outInst.accelerationStructureReference =

+ 218 - 35
tests/gr/Gr.cpp

@@ -2771,12 +2771,25 @@ void main()
 	}
 
 	ShaderProgramPtr rtProg;
+	constexpr U32 rayGenGroupIdx = 0;
+	constexpr U32 missGroupIdx = 1;
+	constexpr U32 shadowMissGroupIdx = 2;
+	constexpr U32 colorChitGroupIdx = 3;
+	constexpr U32 primitiveChitGroupIdx = 4;
+	constexpr U32 shadowAhitGroupIdx = 5;
+	constexpr U32 hitgroupCount = 6;
 	if(useRayTracing)
 	{
 		const CString commonSrc = R"(
 struct PayLoad
 {
 	Vec3 m_color;
+	F32 m_hitT;
+};
+
+struct ShadowPayLoad
+{
+	Bool m_hit;
 };
 
 struct Material
@@ -2796,12 +2809,25 @@ struct Model
 	Mesh m_mesh;
 };
 
-layout(set = 0, binding = 0, scalar) buffer u_00
+struct Light
+{
+	Vec3 m_min;
+	Vec3 m_max;
+	Vec3 m_intensity;
+};
+
+layout(set = 0, binding = 0, scalar) buffer b_00
+{
+	Model u_models[];
+};
+
+layout(set = 0, binding = 1, scalar) buffer b_01
 {
-	Model m_models[];
+	Light u_lights[];
 };
 
 #define PAYLOAD_LOCATION 0
+#define SHADOW_PAYLOAD_LOCATION 1
 )";
 
 		const CString chit0Src = R"(
@@ -2809,7 +2835,8 @@ layout(location = PAYLOAD_LOCATION) rayPayloadInEXT PayLoad s_payLoad;
 
 void main()
 {
-	s_payLoad.m_color = m_models[gl_InstanceID].m_mtl.m_diffuseColor;
+	s_payLoad.m_color = u_models[gl_InstanceID].m_mtl.m_diffuseColor;
+	s_payLoad.m_hitT = gl_HitTEXT;
 }
 )";
 
@@ -2835,6 +2862,7 @@ void main()
 	}
 
 	s_payLoad.m_color = col;
+	s_payLoad.m_hitT = gl_HitTEXT;
 }
 )";
 
@@ -2844,21 +2872,63 @@ layout(location = PAYLOAD_LOCATION) rayPayloadInEXT PayLoad s_payLoad;
 void main()
 {
 	s_payLoad.m_color = Vec3(0.5);
+	s_payLoad.m_hitT = -1.0;
+}
+)";
+
+		const CString shadowAhitSrc = R"(
+layout(location = SHADOW_PAYLOAD_LOCATION) rayPayloadInEXT ShadowPayLoad s_payLoad;
+
+void main()
+{
+	s_payLoad.m_hit = true;
+	terminateRayEXT();
+}
+)";
+
+		const CString shadowMissSrc = R"(
+layout(location = SHADOW_PAYLOAD_LOCATION) rayPayloadInEXT ShadowPayLoad s_payLoad;
+
+void main()
+{
+	s_payLoad.m_hit = false;
 }
 )";
 
 		const CString rayGenSrc = R"(
-layout(set = 0, binding = 1) uniform accelerationStructureEXT u_tlas;
-layout(set = 0, binding = 2, rgba8) uniform image2D u_outImg;
+layout(set = 1, binding = 0) uniform accelerationStructureEXT u_tlas;
+layout(set = 1, binding = 1, rgba8) uniform image2D u_outImg;
 
 layout(push_constant) uniform u_pc
 {
 	Mat4 u_vp;
 	Vec3 u_cameraPos;
-	F32 u_padding0;
+	U32 u_lightCount;
 };
 
 layout(location = PAYLOAD_LOCATION) rayPayloadEXT PayLoad s_payLoad;
+layout(location = SHADOW_PAYLOAD_LOCATION) rayPayloadEXT ShadowPayLoad s_shadowPayLoad;
+
+UVec3 rand3DPCG16(UVec3 v)
+{
+	v = v * 1664525u + 1013904223u;
+
+	v.x += v.y * v.z;
+	v.y += v.z * v.x;
+	v.z += v.x * v.y;
+	v.x += v.y * v.z;
+	v.y += v.z * v.x;
+	v.z += v.x * v.y;
+
+	return v >> 16u;
+}
+
+Vec2 hammersleyRandom16(U32 sampleIdx, U32 sampleCount, UVec2 random)
+{
+	const F32 e1 = fract(F32(sampleIdx) / sampleCount + F32(random.x) * (1.0 / 65536.0));
+	const F32 e2 = F32((bitfieldReverse(sampleIdx) >> 16) ^ random.y) * (1.0 / 65536.0);
+	return Vec2(e1, e2);
+}
 
 void main()
 {
@@ -2868,19 +2938,55 @@ void main()
 	const Vec4 p4 = inverse(u_vp) * Vec4(ndc, 1.0, 1.0);
 	const Vec3 p3 = p4.xyz / p4.w;
 
-	const Vec3 rayDir = normalize(p3 - u_cameraPos);
-	const Vec3 rayOrigin = u_cameraPos;
+	const UVec2 random = rand3DPCG16(UVec3(gl_LaunchSizeEXT.xy, 0)).xy;
+	const Vec2 randomCircle = hammersleyRandom16(0, 0xFFFFu, random);
+
+	Vec3 outColor = Vec3(0.0);
+
+	// Primary ray
+	{
+		const Vec3 rayOrigin = u_cameraPos;
+		const Vec3 rayDir = normalize(p3 - u_cameraPos);
+		const U32 cullMask = 0xFF;
+		const U32 sbtRecordOffset = 0;
+		const U32 sbtRecordStride = 0;
+		const U32 missIndex = 0;
+		const F32 tMin = 0.01;
+		const F32 tMax = 10000.0;
+		traceRayEXT(u_tlas, gl_RayFlagsOpaqueEXT, cullMask, sbtRecordOffset, sbtRecordStride, missIndex, rayOrigin,
+					tMin, rayDir, tMax, PAYLOAD_LOCATION);
+	}
+
+	if(s_payLoad.m_hitT > 0.0)
+	{
+		const Vec3 rayOrigin = u_cameraPos + normalize(p3 - u_cameraPos) * s_payLoad.m_hitT;
+		const Vec3 diffuseColor = s_payLoad.m_color;
 
-	const U32 cullMask = 0xFF;
-	const U32 sbtRecordOffset = 0;
-	const U32 sbtRecordStride = 0;
-	const U32 missIndex = 0;
-	const F32 tMin = 0.01;
-	const F32 tMax = 10000.0;
-	traceRayEXT(u_tlas, gl_RayFlagsOpaqueEXT, cullMask, sbtRecordOffset, sbtRecordStride, missIndex, rayOrigin, tMin,
-				rayDir, tMax, PAYLOAD_LOCATION);
+		for(U32 i = 0; i < u_lightCount; ++i)
+		{
+			s_shadowPayLoad.m_hit = false;
+			const Light light = u_lights[i];
+			const Vec3 randomPointInLight = mix(light.m_min, light.m_max, randomCircle.xyx);
+
+			const Vec3 rayDir = normalize(randomPointInLight - rayOrigin);
+			const U32 cullMask = 0x1;
+			const U32 sbtRecordOffset = 1;
+			const U32 sbtRecordStride = 0;
+			const U32 missIndex = 1;
+			const F32 tMin = 0.01;
+			const F32 tMax = length(randomPointInLight - rayOrigin);
+			traceRayEXT(u_tlas, gl_RayFlagsOpaqueEXT, cullMask, sbtRecordOffset, sbtRecordStride, missIndex, rayOrigin,
+						tMin, rayDir, tMax, SHADOW_PAYLOAD_LOCATION);
+
+			outColor += (s_shadowPayLoad.m_hit) ? diffuseColor * light.m_intensity : Vec3(0.0);
+		}
+	}
+	else
+	{
+		outColor = s_payLoad.m_color;
+	}
 
-	imageStore(u_outImg, IVec2(gl_LaunchIDEXT.xy), Vec4(s_payLoad.m_color, 0.0));
+	imageStore(u_outImg, IVec2(gl_LaunchIDEXT.xy), Vec4(outColor, 0.0));
 }
 		)";
 
@@ -2888,17 +2994,24 @@ void main()
 											 ShaderType::CLOSEST_HIT, *gr);
 		ShaderPtr chit1Shader = createShader(StringAuto(alloc).sprintf("%s\n%s", commonSrc.cstr(), chit1Src.cstr()),
 											 ShaderType::CLOSEST_HIT, *gr);
+
+		ShaderPtr shadowAhitShader = createShader(
+			StringAuto(alloc).sprintf("%s\n%s", commonSrc.cstr(), shadowAhitSrc.cstr()), ShaderType::ANY_HIT, *gr);
 		ShaderPtr missShader =
 			createShader(StringAuto(alloc).sprintf("%s\n%s", commonSrc.cstr(), missSrc.cstr()), ShaderType::MISS, *gr);
 
+		ShaderPtr shadowMissShader = createShader(
+			StringAuto(alloc).sprintf("%s\n%s", commonSrc.cstr(), shadowMissSrc.cstr()), ShaderType::MISS, *gr);
+
 		ShaderPtr rayGenShader = createShader(StringAuto(alloc).sprintf("%s\n%s", commonSrc.cstr(), rayGenSrc.cstr()),
 											  ShaderType::RAY_GEN, *gr);
 
-		Array<RayTracingHitGroup, 2> hitGroups;
+		Array<RayTracingHitGroup, 3> hitGroups;
 		hitGroups[0].m_closestHitShader = chit0Shader;
 		hitGroups[1].m_closestHitShader = chit1Shader;
+		hitGroups[2].m_anyHitShader = shadowAhitShader;
 
-		Array<ShaderPtr, 1> missShaders = {missShader};
+		Array<ShaderPtr, 2> missShaders = {missShader, shadowMissShader};
 
 		ShaderProgramInitInfo inf;
 		inf.m_rayTracingShaders.m_hitGroups = hitGroups;
@@ -2979,17 +3092,17 @@ void main()
 		instances[1].m_bottomLevel = bigBlas;
 		instances[1].m_transform = Mat3x4(Vec3((bigBox.getMin() + bigBox.getMax()).xyz() / 2.0f),
 										  Mat3(Axisang(toRad(15.0f), Vec3(0.0f, 1.0f, 0.0f))));
-		instances[1].m_sbtRecordIndex = 0;
+		instances[1].m_sbtRecordIndex = 1;
 
 		instances[2].m_bottomLevel = lightBlas;
 		instances[2].m_transform =
 			Mat3x4(Vec3((lightBox.getMin() + lightBox.getMax()).xyz() / 2.0f), Mat3::getIdentity());
-		instances[2].m_sbtRecordIndex = 0;
+		instances[2].m_sbtRecordIndex = 2;
 
 		instances[3].m_bottomLevel = roomBlas;
 		instances[3].m_transform =
 			Mat3x4(Vec3((roomBox.getMin() + roomBox.getMax()).xyz() / 2.0f), Mat3::getIdentity());
-		instances[3].m_sbtRecordIndex = 1;
+		instances[3].m_sbtRecordIndex = 3;
 
 		inf.m_type = AccelerationStructureType::TOP_LEVEL;
 		inf.m_topLevel.m_instances = instances;
@@ -3001,26 +3114,65 @@ void main()
 	BufferPtr sbt;
 	if(useRayTracing)
 	{
-		const U32 handleCount = 4;
+		const U32 recordCount = 1 + 2 + 4 * 2;
 
 		BufferInitInfo inf;
 		inf.m_mapAccess = BufferMapAccessBit::WRITE;
 		inf.m_usage = BufferUsageBit::SBT;
-		inf.m_size = gr->getDeviceCapabilities().m_sbtRecordSize * handleCount;
+		inf.m_size = gr->getDeviceCapabilities().m_sbtRecordSize * recordCount;
 
 		sbt = gr->newBuffer(inf);
 		WeakArray<U8, PtrSize> mapped = sbt->map<U8>(0, inf.m_size, BufferMapAccessBit::WRITE);
 		memset(&mapped[0], 0, inf.m_size);
 
 		ConstWeakArray<U8> handles = rtProg->getShaderGroupHandles();
-		ANKI_TEST_EXPECT_EQ(handles.getSize(), gr->getDeviceCapabilities().m_shaderGroupHandleSize * handleCount);
+		ANKI_TEST_EXPECT_EQ(handles.getSize(), gr->getDeviceCapabilities().m_shaderGroupHandleSize * hitgroupCount);
+
+		// Ray gen
+		U32 record = 0;
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * rayGenGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+
+		// 2xMiss
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * missGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowMissGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
 
-		for(U32 handle = 0; handle < handleCount; ++handle)
-		{
-			memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * handle],
-				   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * handle],
-				   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
-		}
+		// Small box
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * colorChitGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowAhitGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+
+		// Big box
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * colorChitGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowAhitGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+
+		// Light
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * colorChitGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowAhitGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+
+		// Room
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * primitiveChitGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
+		memcpy(&mapped[gr->getDeviceCapabilities().m_sbtRecordSize * record++],
+			   &handles[gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowAhitGroupIdx],
+			   gr->getDeviceCapabilities().m_shaderGroupHandleSize);
 
 		sbt->unmap();
 	}
@@ -3064,6 +3216,34 @@ void main()
 		modelBuffer->unmap();
 	}
 
+	// Create lights
+	BufferPtr lightBuffer;
+	constexpr U32 lightCount = 1;
+	if(useRayTracing)
+	{
+		class Light
+		{
+		public:
+			Vec3 m_min;
+			Vec3 m_max;
+			Vec3 m_intensity;
+		};
+
+		BufferInitInfo inf;
+		inf.m_mapAccess = BufferMapAccessBit::WRITE;
+		inf.m_usage = BufferUsageBit::ALL_STORAGE;
+		inf.m_size = sizeof(Light) * lightCount;
+
+		lightBuffer = gr->newBuffer(inf);
+		WeakArray<Light, PtrSize> lights = lightBuffer->map<Light>(0, lightCount, BufferMapAccessBit::WRITE);
+
+		lights[0].m_min = lightBox.getMin().xyz();
+		lights[0].m_max = lightBox.getMax().xyz();
+		lights[0].m_intensity = Vec3(1.0f);
+
+		lightBuffer->unmap();
+	}
+
 	// Draw
 	constexpr U32 ITERATIONS = 200;
 	for(U i = 0; i < ITERATIONS; ++i)
@@ -3126,8 +3306,9 @@ void main()
 								TextureSubresourceInfo());
 
 		cmdb->bindStorageBuffer(0, 0, modelBuffer, 0, MAX_PTR_SIZE);
-		cmdb->bindAccelerationStructure(0, 1, tlas);
-		cmdb->bindImage(0, 2, presentView);
+		cmdb->bindStorageBuffer(0, 1, lightBuffer, 0, MAX_PTR_SIZE);
+		cmdb->bindAccelerationStructure(1, 0, tlas);
+		cmdb->bindImage(1, 1, presentView);
 
 		cmdb->bindShaderProgram(rtProg);
 
@@ -3135,10 +3316,12 @@ void main()
 		{
 		public:
 			Mat4 m_vp;
-			Vec4 m_cameraPos;
+			Vec3 m_cameraPos;
+			U32 m_lightCount;
 		} pc;
 		pc.m_vp = projMat * viewMat;
-		pc.m_cameraPos = Vec4(278.0f, 278.0f, -800.0f, 0.0f);
+		pc.m_cameraPos = Vec3(278.0f, 278.0f, -800.0f);
+		pc.m_lightCount = 1;
 
 		cmdb->setPushConstants(&pc, sizeof(pc));