mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-25 21:31:32 +00:00
Limit the number of lights per trace to 50
This commit is contained in:
parent
95232aedf4
commit
583f720007
5 changed files with 60 additions and 21 deletions
|
@ -22,7 +22,7 @@ layout(set = 0, binding = 4) uniform Uniforms
|
||||||
uint SampleIndex;
|
uint SampleIndex;
|
||||||
uint SampleCount;
|
uint SampleCount;
|
||||||
uint PassType;
|
uint PassType;
|
||||||
uint LightCount;
|
uint Padding0;
|
||||||
vec3 SunDir;
|
vec3 SunDir;
|
||||||
float SampleDistance;
|
float SampleDistance;
|
||||||
vec3 SunColor;
|
vec3 SunColor;
|
||||||
|
@ -43,6 +43,13 @@ struct SurfaceInfo
|
||||||
|
|
||||||
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
||||||
|
|
||||||
|
layout(push_constant) uniform PushConstants
|
||||||
|
{
|
||||||
|
uint LightStart;
|
||||||
|
uint LightEnd;
|
||||||
|
ivec2 pushPadding;
|
||||||
|
};
|
||||||
|
|
||||||
vec3 ImportanceSample(vec3 N);
|
vec3 ImportanceSample(vec3 N);
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
|
|
@ -22,7 +22,7 @@ layout(set = 0, binding = 4) uniform Uniforms
|
||||||
uint SampleIndex;
|
uint SampleIndex;
|
||||||
uint SampleCount;
|
uint SampleCount;
|
||||||
uint PassType;
|
uint PassType;
|
||||||
uint LightCount;
|
uint Padding0;
|
||||||
vec3 SunDir;
|
vec3 SunDir;
|
||||||
float SampleDistance;
|
float SampleDistance;
|
||||||
vec3 SunColor;
|
vec3 SunColor;
|
||||||
|
@ -58,6 +58,13 @@ struct LightInfo
|
||||||
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
||||||
layout(set = 0, binding = 7) buffer LightBuffer { LightInfo lights[]; };
|
layout(set = 0, binding = 7) buffer LightBuffer { LightInfo lights[]; };
|
||||||
|
|
||||||
|
layout(push_constant) uniform PushConstants
|
||||||
|
{
|
||||||
|
uint LightStart;
|
||||||
|
uint LightEnd;
|
||||||
|
ivec2 pushPadding;
|
||||||
|
};
|
||||||
|
|
||||||
vec2 Hammersley(uint i, uint N);
|
vec2 Hammersley(uint i, uint N);
|
||||||
float RadicalInverse_VdC(uint bits);
|
float RadicalInverse_VdC(uint bits);
|
||||||
|
|
||||||
|
@ -80,7 +87,7 @@ void main()
|
||||||
|
|
||||||
const float minDistance = 0.01;
|
const float minDistance = 0.01;
|
||||||
|
|
||||||
// Sun light
|
if (LightStart == 0) // Sun light
|
||||||
{
|
{
|
||||||
const float dist = 32768.0;
|
const float dist = 32768.0;
|
||||||
|
|
||||||
|
@ -109,7 +116,7 @@ void main()
|
||||||
incoming.rgb += SunColor * (attenuation * SunIntensity * incoming.w);
|
incoming.rgb += SunColor * (attenuation * SunIntensity * incoming.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint j = 0; j < LightCount; j++)
|
for (uint j = LightStart; j < LightEnd; j++)
|
||||||
{
|
{
|
||||||
LightInfo light = lights[j];
|
LightInfo light = lights[j];
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,6 @@ void GPURaytracer::Raytrace(LevelMesh* level)
|
||||||
|
|
||||||
Uniforms uniforms = {};
|
Uniforms uniforms = {};
|
||||||
uniforms.SampleDistance = (float)mesh->samples;
|
uniforms.SampleDistance = (float)mesh->samples;
|
||||||
uniforms.LightCount = mesh->map->ThingLights.Size();
|
|
||||||
uniforms.SunDir = mesh->map->GetSunDirection();
|
uniforms.SunDir = mesh->map->GetSunDirection();
|
||||||
uniforms.SunColor = mesh->map->GetSunColor();
|
uniforms.SunColor = mesh->map->GetSunColor();
|
||||||
uniforms.SunIntensity = 1.0f;
|
uniforms.SunIntensity = 1.0f;
|
||||||
|
@ -110,7 +109,7 @@ void GPURaytracer::Raytrace(LevelMesh* level)
|
||||||
RunTrace(uniforms, rgenBounceRegion);
|
RunTrace(uniforms, rgenBounceRegion);
|
||||||
|
|
||||||
uniforms.SampleCount = coverageSampleCount;
|
uniforms.SampleCount = coverageSampleCount;
|
||||||
RunTrace(uniforms, rgenLightRegion);
|
RunTrace(uniforms, rgenLightRegion, 0, mesh->map->ThingLights.Size());
|
||||||
|
|
||||||
for (uint32_t i = 0; i < (uint32_t)bounceSampleCount; i++)
|
for (uint32_t i = 0; i < (uint32_t)bounceSampleCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +122,7 @@ void GPURaytracer::Raytrace(LevelMesh* level)
|
||||||
for (int bounce = 0; bounce < mesh->map->LightBounce; bounce++)
|
for (int bounce = 0; bounce < mesh->map->LightBounce; bounce++)
|
||||||
{
|
{
|
||||||
uniforms.SampleCount = coverageSampleCount;
|
uniforms.SampleCount = coverageSampleCount;
|
||||||
RunTrace(uniforms, rgenLightRegion);
|
RunTrace(uniforms, rgenLightRegion, 0, mesh->map->ThingLights.Size());
|
||||||
|
|
||||||
uniforms.PassType = 2;
|
uniforms.PassType = 2;
|
||||||
uniforms.SampleIndex = (i + bounce) % uniforms.SampleCount;
|
uniforms.SampleIndex = (i + bounce) % uniforms.SampleCount;
|
||||||
|
@ -230,7 +229,7 @@ void GPURaytracer::BeginTracing()
|
||||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get());
|
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPURaytracer::RunTrace(const Uniforms& uniforms, const VkStridedDeviceAddressRegionKHR& rgenShader)
|
void GPURaytracer::RunTrace(const Uniforms& uniforms, const VkStridedDeviceAddressRegionKHR& rgenShader, int lightStart, int lightEnd)
|
||||||
{
|
{
|
||||||
if (uniformsIndex == uniformStructs)
|
if (uniformsIndex == uniformStructs)
|
||||||
{
|
{
|
||||||
|
@ -240,25 +239,42 @@ void GPURaytracer::RunTrace(const Uniforms& uniforms, const VkStridedDeviceAddre
|
||||||
|
|
||||||
*reinterpret_cast<Uniforms*>(mappedUniforms + uniformStructStride * uniformsIndex) = uniforms;
|
*reinterpret_cast<Uniforms*>(mappedUniforms + uniformStructStride * uniformsIndex) = uniforms;
|
||||||
|
|
||||||
|
uint32_t offset = (uint32_t)(uniformsIndex * uniformStructStride);
|
||||||
|
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0, descriptorSet.get(), 1, &offset);
|
||||||
|
|
||||||
|
bool needbarrier = true;
|
||||||
if (uniformsIndex == 0)
|
if (uniformsIndex == 0)
|
||||||
{
|
{
|
||||||
PipelineBarrier barrier;
|
PipelineBarrier barrier;
|
||||||
barrier.addBuffer(uniformBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
barrier.addBuffer(uniformBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||||
barrier.addImage(positionsImage.get(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
|
barrier.addImage(positionsImage.get(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
|
||||||
barrier.execute(cmdbuffer.get(), VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
barrier.execute(cmdbuffer.get(), VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||||
|
needbarrier = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
PipelineBarrier barrier;
|
|
||||||
barrier.addImage(positionsImage.get(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
|
|
||||||
barrier.execute(cmdbuffer.get(), VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t offset = (uint32_t)(uniformsIndex * uniformStructStride);
|
|
||||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0, descriptorSet.get(), 1, &offset);
|
|
||||||
cmdbuffer->traceRays(&rgenShader, &missRegion, &hitRegion, &callRegion, rayTraceImageSize, rayTraceImageSize, 1);
|
|
||||||
|
|
||||||
uniformsIndex++;
|
uniformsIndex++;
|
||||||
|
|
||||||
|
const int maxLights = 50;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int count = std::min(lightEnd - lightStart, maxLights);
|
||||||
|
|
||||||
|
if (needbarrier)
|
||||||
|
{
|
||||||
|
PipelineBarrier barrier;
|
||||||
|
barrier.addImage(positionsImage.get(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
|
||||||
|
barrier.execute(cmdbuffer.get(), VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
PushConstants constants = {};
|
||||||
|
constants.LightStart = lightStart;
|
||||||
|
constants.LightEnd = lightStart + count;
|
||||||
|
cmdbuffer->pushConstants(pipelineLayout.get(), VK_SHADER_STAGE_RAYGEN_BIT_KHR, 0, (uint32_t)sizeof(PushConstants), &constants);
|
||||||
|
cmdbuffer->traceRays(&rgenShader, &missRegion, &hitRegion, &callRegion, rayTraceImageSize, rayTraceImageSize, 1);
|
||||||
|
|
||||||
|
needbarrier = true;
|
||||||
|
lightStart += count;
|
||||||
|
} while (lightStart < lightEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPURaytracer::EndTracing()
|
void GPURaytracer::EndTracing()
|
||||||
|
@ -708,6 +724,7 @@ void GPURaytracer::CreatePipeline()
|
||||||
|
|
||||||
PipelineLayoutBuilder layoutbuilder;
|
PipelineLayoutBuilder layoutbuilder;
|
||||||
layoutbuilder.addSetLayout(descriptorSetLayout.get());
|
layoutbuilder.addSetLayout(descriptorSetLayout.get());
|
||||||
|
layoutbuilder.addPushConstantRange(VK_SHADER_STAGE_RAYGEN_BIT_KHR, 0, sizeof(PushConstants));
|
||||||
pipelineLayout = layoutbuilder.create(device.get());
|
pipelineLayout = layoutbuilder.create(device.get());
|
||||||
pipelineLayout->SetDebugName("pipelineLayout");
|
pipelineLayout->SetDebugName("pipelineLayout");
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct Uniforms
|
||||||
uint32_t SampleIndex;
|
uint32_t SampleIndex;
|
||||||
uint32_t SampleCount;
|
uint32_t SampleCount;
|
||||||
uint32_t PassType;
|
uint32_t PassType;
|
||||||
uint32_t LightCount;
|
uint32_t Padding0;
|
||||||
vec3 SunDir;
|
vec3 SunDir;
|
||||||
float SampleDistance;
|
float SampleDistance;
|
||||||
vec3 SunColor;
|
vec3 SunColor;
|
||||||
|
@ -20,6 +20,13 @@ struct Uniforms
|
||||||
float Padding1;
|
float Padding1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PushConstants
|
||||||
|
{
|
||||||
|
uint32_t LightStart;
|
||||||
|
uint32_t LightEnd;
|
||||||
|
ivec2 pushPadding;
|
||||||
|
};
|
||||||
|
|
||||||
struct SurfaceInfo
|
struct SurfaceInfo
|
||||||
{
|
{
|
||||||
vec3 Normal;
|
vec3 Normal;
|
||||||
|
@ -71,7 +78,7 @@ private:
|
||||||
|
|
||||||
void UploadTasks(const TraceTask* tasks, size_t size);
|
void UploadTasks(const TraceTask* tasks, size_t size);
|
||||||
void BeginTracing();
|
void BeginTracing();
|
||||||
void RunTrace(const Uniforms& uniforms, const VkStridedDeviceAddressRegionKHR& rgenShader);
|
void RunTrace(const Uniforms& uniforms, const VkStridedDeviceAddressRegionKHR& rgenShader, int lightStart = 0, int lightEnd = 0);
|
||||||
void EndTracing();
|
void EndTracing();
|
||||||
void DownloadTasks(const TraceTask* tasks, size_t size);
|
void DownloadTasks(const TraceTask* tasks, size_t size);
|
||||||
void SubmitCommands();
|
void SubmitCommands();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include "lightmaptexture.h"
|
#include "lightmaptexture.h"
|
||||||
|
#include "framework/halffloat.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
LightmapTexture::LightmapTexture(int width, int height) : textureWidth(width), textureHeight(height)
|
LightmapTexture::LightmapTexture(int width, int height) : textureWidth(width), textureHeight(height)
|
||||||
|
|
Loading…
Reference in a new issue