diff --git a/README.md b/README.md index ac83ad9..4085cf1 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,29 @@ # ZDRay baking utility for GZDoom -ZDRay is a node and lightmap generator. It is based on zdbsp for the node generation and dlight for the lightmap generation. +ZDRay is a node and lightmap generator for GZDoom. ZDRay is intended as a drop-in replacement for zdbsp, with the additional feature +that it can also bake lights. Once ZDRay has processed the level WAD it is ready to be used by GZDoom. -Special thanks to Randi Heit, Samuel Villarreal, Christoph Oelckers and anyone else involved in creating or maintaining those tools. +ZDRay is based on zdbsp for the node generation and originally used dlight for the lightmap generation. Special thanks to Randi Heit, +Samuel Villarreal, Christoph Oelckers and anyone else involved in creating or maintaining those tools. + +The ray tracing code has been completely rewritten since. It now supports bounces and can do the ray tracing on the GPU. ## ZDRay UDMF properties
+thing // ZDRayInfo (zdray properties for the map) +{ + type = 9890; + suncolor = <int> (color) + sundirx = <float> (X direction for the sun) + sundiry = <float> (Y direction for the sun) + sundirz = <float> (Z direction for the sun) + sampledistance = <int> (default: 8, map units each lightmap texel covers, must be in powers of two) + bounces = <int> (default: 1, how many times light bounces off walls) + gridsize = <float> (default: 32, grid density for the automatic light probes) +} + thing // StaticLight (point or spot light to be baked into the lightmap) { lightcolor = <int> (color) @@ -22,23 +38,14 @@ thing // LightProbe (light sampling point for actors) type = 9875; } -thing // Sunlight (sunlight properties for the map) -{ - type = 9890; - suncolor = <int> (color) - sundirx = <float> (X direction for the sun) - sundiry = <float> (Y direction for the sun) - sundirz = <float> (Z direction for the sun) -} - -linedef // Line surface emitting +linedef // Line emissive surface { lightcolor = <int> (color, default: white) lightintensity = <float> (default: 1) lightdistance = <float> (default: 0, no light) } -sector // Sector planes emitting light +sector // Sector plane emissive surface { lightcolorfloor = <int> (color, default: white) lightintensityfloor = <float> (default: 1) diff --git a/src/level/doomdata.h b/src/level/doomdata.h index e74b41b..734001d 100644 --- a/src/level/doomdata.h +++ b/src/level/doomdata.h @@ -387,8 +387,11 @@ struct FLevel TArraySurfaceLights; TArray ThingLightProbes; - Vec3 defaultSunColor = Vec3(1, 1, 1); - Vec3 defaultSunDirection = Vec3(0.45f, 0.3f, 0.9f); + Vec3 defaultSunColor; + Vec3 defaultSunDirection; + int Samples; + int LightBounce; + float GridSize; void FindMapBounds (); void RemoveExtraLines (); diff --git a/src/level/level.cpp b/src/level/level.cpp index 911a8cd..93ba7c7 100644 --- a/src/level/level.cpp +++ b/src/level/level.cpp @@ -30,7 +30,6 @@ #endif extern int LMDims; -extern int Samples; extern bool CPURaytrace; extern void ShowView (FLevel *level); @@ -693,7 +692,7 @@ void FProcessor::BuildNodes() void FProcessor::BuildLightmaps() { Level.SetupLights(); - LightmapMesh = std::make_unique (Level, Samples, LMDims); + LightmapMesh = std::make_unique (Level, Level.Samples, LMDims); if (CPURaytrace) { diff --git a/src/level/level_light.cpp b/src/level/level_light.cpp index 2192ca2..682566d 100644 --- a/src/level/level_light.cpp +++ b/src/level/level_light.cpp @@ -84,6 +84,13 @@ void FLevel::SetupLights() } } + // GG to whoever memset'ed FLevel + defaultSunColor = Vec3(1, 1, 1); + defaultSunDirection = Vec3(0.45f, 0.3f, 0.9f); + Samples = 8; + LightBounce = 1; + GridSize = 32.0f; + for (int i = 0; i < (int)Things.Size(); ++i) { IntThing* thing = &Things[i]; @@ -91,7 +98,7 @@ void FLevel::SetupLights() { ThingLightProbes.Push(i); } - else if (thing->type == 9890) // Sunlight + else if (thing->type == 9890) // ZDRayInfo { uint32_t lightcolor = 0xffffff; Vec3 sundir(0.0f, 0.0f, 0.0f); @@ -116,6 +123,25 @@ void FLevel::SetupLights() { sundir.z = atof(key.value); } + else if (!stricmp(key.key, "sampledistance")) + { + Samples = atoi(key.value); + if (Samples <= 0) Samples = 1; + if (Samples > 128) Samples = 128; + Samples = Math::RoundPowerOfTwo(Samples); + } + else if (!stricmp(key.key, "bounces")) + { + LightBounce = atoi(key.value); + if (LightBounce < 0) LightBounce = 0; + if (LightBounce > 8) LightBounce = 8; + } + else if (!stricmp(key.key, "gridsize")) + { + GridSize = atof(key.value); + if (GridSize < 0.f) GridSize = 0.f; + if (GridSize > 1024.f) GridSize = 1024.f; + } } if (Vec3::Dot(sundir, sundir) > 0.01f) diff --git a/src/lightmap/cpuraytracer.cpp b/src/lightmap/cpuraytracer.cpp index 4519e51..9bdb108 100644 --- a/src/lightmap/cpuraytracer.cpp +++ b/src/lightmap/cpuraytracer.cpp @@ -12,7 +12,6 @@ #include #include -extern int LightBounce; extern bool VKDebug; CPURaytracer::CPURaytracer() @@ -59,7 +58,7 @@ void CPURaytracer::Raytrace(LevelMesh* level) CreateHemisphereVectors(); CreateLights(); - printf("Ray tracing with %d bounce(s)\n", LightBounce); + printf("Ray tracing with %d bounce(s)\n", mesh->map->LightBounce); Worker::RunJob((int)tasks.size(), [=](int id) { RaytraceTask(tasks[id]); }); @@ -107,7 +106,7 @@ void CPURaytracer::RaytraceTask(const CPUTraceTask& task) state.HemisphereVec = HemisphereVectors[state.SampleIndex]; RunBounceTrace(state); - for (int bounce = 0; bounce < LightBounce && !state.EndTrace; bounce++) + for (int bounce = 0; bounce < mesh->map->LightBounce && !state.EndTrace; bounce++) { state.SampleCount = coverageSampleCount; RunLightTrace(state); diff --git a/src/lightmap/gpuraytracer.cpp b/src/lightmap/gpuraytracer.cpp index c71e3ae..2c1f767 100644 --- a/src/lightmap/gpuraytracer.cpp +++ b/src/lightmap/gpuraytracer.cpp @@ -21,7 +21,6 @@ #include "glsl_rmiss_light.h" #include "glsl_rmiss_sun.h" -extern int LightBounce; extern bool VKDebug; GPURaytracer::GPURaytracer() @@ -86,7 +85,7 @@ void GPURaytracer::Raytrace(LevelMesh* level) HemisphereVectors.push_back(H); } - printf("Ray tracing with %d bounce(s)\n", LightBounce); + printf("Ray tracing with %d bounce(s)\n", mesh->map->LightBounce); size_t maxTasks = (size_t)rayTraceImageSize * rayTraceImageSize; for (size_t startTask = 0; startTask < tasks.size(); startTask += maxTasks) @@ -119,7 +118,7 @@ void GPURaytracer::Raytrace(LevelMesh* level) uniforms.HemisphereVec = HemisphereVectors[uniforms.SampleIndex]; RunTrace(uniforms, rgenBounceRegion); - for (int bounce = 0; bounce < LightBounce; bounce++) + for (int bounce = 0; bounce < mesh->map->LightBounce; bounce++) { uniforms.SampleCount = coverageSampleCount; RunTrace(uniforms, rgenLightRegion); diff --git a/src/lightmap/surfaces.cpp b/src/lightmap/surfaces.cpp index 32fc126..1238a69 100644 --- a/src/lightmap/surfaces.cpp +++ b/src/lightmap/surfaces.cpp @@ -34,8 +34,6 @@ #include "pngwriter.h" #include