mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-22 12:01:09 +00:00
Move sample distance, bounces and light probe grid size settings to the zdrayinfo actor as they affect map visuals
This commit is contained in:
parent
cd3563759c
commit
031dc4a4db
8 changed files with 62 additions and 61 deletions
33
README.md
33
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
|
||||
|
||||
<pre>
|
||||
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)
|
||||
|
|
|
@ -387,8 +387,11 @@ struct FLevel
|
|||
TArray<SurfaceLightDef> SurfaceLights;
|
||||
TArray<int> 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 ();
|
||||
|
|
|
@ -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<LevelMesh>(Level, Samples, LMDims);
|
||||
LightmapMesh = std::make_unique<LevelMesh>(Level, Level.Samples, LMDims);
|
||||
|
||||
if (CPURaytrace)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <algorithm>
|
||||
#include <zlib.h>
|
||||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "pngwriter.h"
|
||||
#include <map>
|
||||
|
||||
extern float GridSize;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4267) // warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
|
||||
#pragma warning(disable: 4244) // warning C4244: '=': conversion from '__int64' to 'int', possible loss of data
|
||||
|
@ -392,12 +390,12 @@ void LevelMesh::CreateLightProbes(FLevel& map)
|
|||
float maxX = std::floor(map.MaxX / 65536.0f) + 1.0f;
|
||||
float maxY = std::floor(map.MaxY / 65536.0f) + 1.0f;
|
||||
|
||||
float halfGridSize = GridSize * 0.5f;
|
||||
float doubleGridSize = GridSize * 2.0f;
|
||||
float halfGridSize = map.GridSize * 0.5f;
|
||||
float doubleGridSize = map.GridSize * 2.0f;
|
||||
|
||||
for (float y = minY; y < maxY; y += GridSize)
|
||||
for (float y = minY; y < maxY; y += map.GridSize)
|
||||
{
|
||||
for (float x = minX; x < maxX; x += GridSize)
|
||||
for (float x = minX; x < maxX; x += map.GridSize)
|
||||
{
|
||||
MapSubsectorEx* ssec = map.PointInSubSector((int)x, (int)y);
|
||||
IntSector* sec = ssec ? map.GetSectorFromSubSector(ssec) : nullptr;
|
||||
|
|
32
src/main.cpp
32
src/main.cpp
|
@ -115,11 +115,8 @@ bool HaveSSE1, HaveSSE2;
|
|||
int SSELevel;
|
||||
int NumThreads = 0;
|
||||
int LMDims = 1024;
|
||||
int Samples = 8;
|
||||
bool CPURaytrace = false;
|
||||
bool VKDebug = false;
|
||||
int LightBounce = 1;
|
||||
float GridSize = 32.0f;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
|
@ -155,16 +152,13 @@ static option long_opts[] =
|
|||
{"no-sse2", no_argument, 0, 1003},
|
||||
{"comments", no_argument, 0, 'c'},
|
||||
{"threads", required_argument, 0, 'j'},
|
||||
{"samples", required_argument, 0, 'Q'},
|
||||
{"size", required_argument, 0, 'S'},
|
||||
{"cpu-raytrace", no_argument, 0, 'C'},
|
||||
{"bounce", required_argument, 0, 'B'},
|
||||
{"gridsize", required_argument, 0, 'i'},
|
||||
{"vkdebug", no_argument, 0, 'D'},
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZXx5cj:Q:S:CD";
|
||||
static const char short_opts[] = "wVgGvbNrReEm:o:f:p:s:d:PqtzZXx5cj:S:CD";
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
|
@ -439,12 +433,6 @@ static void ParseArgs(int argc, char **argv)
|
|||
case 'j':
|
||||
NumThreads = atoi(optarg);
|
||||
break;
|
||||
case 'Q':
|
||||
Samples = atoi(optarg);
|
||||
if (Samples <= 0) Samples = 1;
|
||||
if (Samples > 128) Samples = 128;
|
||||
Samples = Math::RoundPowerOfTwo(Samples);
|
||||
break;
|
||||
case 'S':
|
||||
LMDims = atoi(optarg);
|
||||
if (LMDims <= 0) LMDims = 1;
|
||||
|
@ -457,15 +445,6 @@ static void ParseArgs(int argc, char **argv)
|
|||
case 'D':
|
||||
VKDebug = true;
|
||||
break;
|
||||
case 'B':
|
||||
LightBounce = atoi(optarg);
|
||||
if (LightBounce < 0) LightBounce = 0;
|
||||
if (LightBounce > 8) LightBounce = 8;
|
||||
break;
|
||||
case 'i':
|
||||
GridSize = std::stof(optarg);
|
||||
if (GridSize < 0.f) GridSize = 0.f;
|
||||
break;
|
||||
case 1000:
|
||||
ShowUsage();
|
||||
exit(0);
|
||||
|
@ -508,15 +487,9 @@ static void ShowUsage()
|
|||
" -d, --diagonal-cost=NNN Cost for avoiding diagonal splitters (default %d)\n"
|
||||
" -P, --no-polyobjs Do not check for polyobject subsector splits\n"
|
||||
" -j, --threads=NNN Number of threads used for raytracing (default %d)\n"
|
||||
" -Q, --samples=NNN Set texel sampling size (lowest = higher quaility but\n"
|
||||
" slow compile time) must be in powers of two (default %d)\n"
|
||||
" -S, --size=NNN lightmap texture dimensions for width and height\n"
|
||||
" must be in powers of two (1, 2, 4, 8, 16, etc)\n"
|
||||
" -C, --cpu-raytrace Use the CPU for ray tracing\n"
|
||||
" -B, --bounce=NNN Number of indirect light bounces (default %d, max 8)\n"
|
||||
" -i, --gridsize=NNN Automatic light probe grid size, floating point\n"
|
||||
" Lower values increase granularity at the expense of performance\n"
|
||||
" Recommended: 32.0, 64.0, 128.0, etc (default %.1f)\n"
|
||||
" -D, --vkdebug Print messages from the vulkan validation layer\n"
|
||||
" -w, --warn Show warning messages\n"
|
||||
#if HAVE_TIMING
|
||||
|
@ -531,9 +504,6 @@ static void ShowUsage()
|
|||
, SplitCost
|
||||
, AAPreference
|
||||
, (int)std::thread::hardware_concurrency()
|
||||
, Samples
|
||||
, LightBounce
|
||||
, GridSize
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue