From 866d02fc4ad9a03b02d2b90bca1454b901c2c5f0 Mon Sep 17 00:00:00 2001 From: RaveYard Date: Mon, 4 Jul 2022 11:52:38 +0200 Subject: [PATCH] Discard GPU trace tasks that are out of surface bounds --- src/lightmap/gpuraytracer.cpp | 79 +++++++++++++++++++++++------------ src/lightmap/gpuraytracer.h | 1 + 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/lightmap/gpuraytracer.cpp b/src/lightmap/gpuraytracer.cpp index c215569..45b8d8d 100644 --- a/src/lightmap/gpuraytracer.cpp +++ b/src/lightmap/gpuraytracer.cpp @@ -7,6 +7,7 @@ #include "framework/templates.h" #include "framework/halffloat.h" #include "vulkanbuilders.h" +#include "surfaceclip.h" #include #include #include @@ -50,32 +51,7 @@ void GPURaytracer::Raytrace(LevelMesh* level) CreateVulkanObjects(); std::vector tasks; - for (size_t i = 0; i < mesh->lightProbes.size(); i++) - { - TraceTask task; - task.id = -(int)(i + 2); - task.x = 0; - task.y = 0; - tasks.push_back(task); - } - - for (size_t i = 0; i < mesh->surfaces.size(); i++) - { - Surface* surface = mesh->surfaces[i].get(); - int sampleWidth = surface->lightmapDims[0]; - int sampleHeight = surface->lightmapDims[1]; - for (int y = 0; y < sampleHeight; y++) - { - for (int x = 0; x < sampleWidth; x++) - { - TraceTask task; - task.id = (int)i; - task.x = x; - task.y = y; - tasks.push_back(task); - } - } - } + CreateTasks(tasks); std::vector HemisphereVectors; HemisphereVectors.reserve(bounceSampleCount); @@ -152,6 +128,57 @@ void GPURaytracer::Raytrace(LevelMesh* level) printf("Ray trace complete\n"); } +void GPURaytracer::CreateTasks(std::vector& tasks) +{ + tasks.resize(mesh->lightProbes.size()); + + for (size_t i = 0; i < mesh->lightProbes.size(); i++) + { + TraceTask task; + task.id = -(int)(i + 2); + task.x = 0; + task.y = 0; + tasks.push_back(task); + } + + size_t fullTaskCount = mesh->lightProbes.size(); + + for (size_t i = 0; i < mesh->surfaces.size(); i++) + { + if (i % 4096 == 0) + printf("\rGathering surface trace tasks: %llu / %llu", i, mesh->surfaces.size()); + + Surface* surface = mesh->surfaces[i].get(); + + if (!surface->bSky) + { + int sampleWidth = surface->lightmapDims[0]; + int sampleHeight = surface->lightmapDims[1]; + + fullTaskCount += size_t(sampleHeight) * size_t(sampleWidth); + + SurfaceClip surfaceClip(surface); + + for (int y = 0; y < sampleHeight; y++) + { + for (int x = 0; x < sampleWidth; x++) + { + if (surfaceClip.SampleIsInBounds(float(x), float(y))) + { + TraceTask task; + task.id = (int)i; + task.x = x; + task.y = y; + tasks.push_back(task); + } + } + } + } + } + printf("\rGathering surface trace tasks: %llu / %llu\n", mesh->surfaces.size(), mesh->surfaces.size()); + printf("\tDiscarded %.3f%% of all tasks\n", (1.0 - double(tasks.size()) / fullTaskCount) * 100.0); +} + void GPURaytracer::CreateVulkanObjects() { cmdpool = std::make_unique(device.get(), device->graphicsFamily); diff --git a/src/lightmap/gpuraytracer.h b/src/lightmap/gpuraytracer.h index c06f9f7..de81a4d 100644 --- a/src/lightmap/gpuraytracer.h +++ b/src/lightmap/gpuraytracer.h @@ -66,6 +66,7 @@ public: void Raytrace(LevelMesh* level); private: + void CreateTasks(std::vector& tasks); void CreateVulkanObjects(); void CreateVertexAndIndexBuffers(); void CreateBottomLevelAccelerationStructure();