Remove light probes

Remove emissive surface code
Change default sample count to 16
This commit is contained in:
Magnus Norddahl 2022-08-31 08:48:10 +02:00
parent 8dcd37691c
commit e225118e8e
8 changed files with 9 additions and 205 deletions

View file

@ -7,9 +7,8 @@ that it can also bake lights. Once ZDRay has processed the level WAD it is ready
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 can now do ray tracing on the GPU. GPU ray tracing requires a graphics
card that has support for the Vulkan ray tracing API (for example, nvidia 10 series and higher). ZDRay will automatically fall back
to CPU tracing if no compatible GPU is found.
The ray tracing code has been completely rewritten since. It now does the ray tracing on the GPU. GPU ray tracing requires a graphics
card that has support for the Vulkan ray query API (for example, nvidia 20 series and higher). ZDRay no longer supports CPU tracing.
## ZDRay Usage
@ -38,7 +37,6 @@ Usage: zdray [options] sourcefile.wad
-j, --threads=NNN Number of threads used for raytracing (default 64)
-S, --size=NNN lightmap texture dimensions for width and height must
be in powers of two (1, 2, 4, 8, 16, etc)
-C, --cpu-raytrace Use the CPU for ray tracing
-D, --vkdebug Print messages from the Vulkan validation layer
--dump-mesh Export level mesh and lightmaps for debugging
-w, --warn Show warning messages
@ -54,8 +52,7 @@ thing // ZDRayInfo (ZDRay properties for the map)
{
type = 9890;
lm_suncolor = <string> (default: "FFFFFF", hex color value of the sun)
lm_sampledistance = <int> (default: 8, map units each lightmap texel covers, must be in powers of two)
lm_gridsize = <float> (default: 32, grid density for the automatic light probes)
lm_sampledistance = <int> (default: 16, map units each lightmap texel covers, must be in powers of two)
}
thing // Static point light (Light color and distance properties use the same args as dynamic lights)
@ -68,11 +65,6 @@ thing // Static spotlight (Light color, distance and angle properties use the sa
type = 9881;
}
thing // LightProbe (light sampling point for actors)
{
type = 9875;
}
linedef
{
// Customizable sampling distance per line surface. Will use the value from the ZDRayInfo actor by default.

View file

@ -300,7 +300,6 @@ struct FloatVertex
#define THING_POINTLIGHT_STATIC 9876
#define THING_SPOTLIGHT_STATIC 9881
#define THING_LIGHTPROBE 9875
#define THING_ZDRAYINFO 9890
struct ThingLight
@ -374,13 +373,6 @@ struct ThingLight
}
};
struct SurfaceLightDef
{
float distance;
float intensity;
vec3 rgb;
};
enum mapFlags_t
{
ML_BLOCKING = 1, // Solid, is an obstacle.
@ -425,14 +417,10 @@ struct FLevel
TArray<UDMFKey> props;
TArray<ThingLight> ThingLights;
TArray<SurfaceLightDef> SurfaceLights;
TArray<int> ThingLightProbes;
vec3 defaultSunColor;
vec3 defaultSunDirection;
int DefaultSamples;
int LightBounce;
float GridSize;
void FindMapBounds ();
void RemoveExtraLines ();
@ -456,8 +444,6 @@ struct FLevel
MapSubsectorEx *PointInSubSector(const int x, const int y);
FloatVertex GetSegVertex(int index);
vec3 GetLightProbePosition(int index);
int FindFirstSectorFromTag(int tag);
inline IntSector* PointInSector(const dvec2& pos) { return GetSectorFromSubSector(PointInSubSector(int(pos.x), int(pos.y))); }

View file

@ -43,18 +43,12 @@ void FLevel::SetupLights()
// GG to whoever memset'ed FLevel
defaultSunColor = vec3(1, 1, 1);
defaultSunDirection = vec3(0.45f, 0.3f, 0.9f);
DefaultSamples = 8;
LightBounce = 0;
GridSize = 32.0f;
DefaultSamples = 16;
for (int i = 0; i < (int)Things.Size(); ++i)
{
IntThing* thing = &Things[i];
if (thing->type == THING_LIGHTPROBE)
{
ThingLightProbes.Push(i);
}
else if (thing->type == THING_ZDRAYINFO)
if (thing->type == THING_ZDRAYINFO)
{
uint32_t lightcolor = 0xffffff;
vec3 sundir(0.0f, 0.0f, 0.0f);
@ -86,21 +80,6 @@ void FLevel::SetupLights()
if (DefaultSamples > 128) DefaultSamples = 128;
DefaultSamples = Math::RoundPowerOfTwo(DefaultSamples);
}
/*
// light bounces temporarily disabled
else if (!stricmp(key.key, "lm_bounces"))
{
LightBounce = atoi(key.value);
if (LightBounce < 0) LightBounce = 0;
if (LightBounce > 8) LightBounce = 8;
}
*/
else if (!stricmp(key.key, "lm_gridsize"))
{
GridSize = atof(key.value) ? atof(key.value) : 64.f;
if (GridSize < 1.f) GridSize = 1.f;
if (GridSize > 1024.f) GridSize = 1024.f;
}
}
if (dot(sundir, sundir) > 0.01f)
@ -441,24 +420,3 @@ void FLevel::CreateLights()
//printf("Surface lights: %i\n", (int)SurfaceLights.Size());
}
vec3 FLevel::GetLightProbePosition(int index)
{
int thingIndex = ThingLightProbes[index];
const IntThing& thing = Things[thingIndex];
float x = (float)(thing.x >> FRACBITS);
float y = (float)(thing.y >> FRACBITS);
float z = 0.0f;
MapSubsectorEx* ssect = PointInSubSector(x, y);
if (ssect)
{
IntSector* sector = GetSectorFromSubSector(ssect);
if (sector)
{
z = sector->floorplane.zAt(x, y) + thing.height;
}
}
return vec3(x, y, z);
}

View file

@ -16,12 +16,9 @@ layout(set = 0, binding = 1) uniform Uniforms
struct SurfaceInfo
{
vec3 Normal;
float EmissiveDistance;
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float SamplingDistance;
float Padding1, Padding2;
float Padding1, Padding2, Padding3;
};
struct LightInfo

View file

@ -841,49 +841,9 @@ std::vector<SurfaceInfo> GPURaytracer::CreateSurfaceInfo()
surfaces.reserve(mesh->surfaces.size());
for (const auto& surface : mesh->surfaces)
{
SurfaceLightDef* def = nullptr;
if (surface->type >= ST_MIDDLESIDE && surface->type <= ST_LOWERSIDE)
{
int lightdefidx = mesh->map->Sides[surface->typeIndex].lightdef;
if (lightdefidx != -1)
{
def = &mesh->map->SurfaceLights[lightdefidx];
}
}
else if (surface->type == ST_FLOOR || surface->type == ST_CEILING)
{
MapSubsectorEx* sub = &mesh->map->GLSubsectors[surface->typeIndex];
IntSector* sector = mesh->map->GetSectorFromSubSector(sub);
if (sector && surface->verts.size() > 0)
{
if (sector->floorlightdef != -1 && surface->type == ST_FLOOR)
{
def = &mesh->map->SurfaceLights[sector->floorlightdef];
}
else if (sector->ceilinglightdef != -1 && surface->type == ST_CEILING)
{
def = &mesh->map->SurfaceLights[sector->ceilinglightdef];
}
}
}
SurfaceInfo info;
info.Sky = surface->bSky ? 1.0f : 0.0f;
info.Normal = surface->plane.Normal();
if (def)
{
info.EmissiveDistance = def->distance + def->distance;
info.EmissiveIntensity = def->intensity;
info.EmissiveColor = def->rgb;
}
else
{
info.EmissiveDistance = 0.0f;
info.EmissiveIntensity = 0.0f;
info.EmissiveColor = vec3(0.0f, 0.0f, 0.0f);
}
info.SamplingDistance = float(surface->sampleDimension);
surfaces.push_back(info);
}
@ -912,12 +872,3 @@ void GPURaytracer::PrintVulkanInfo()
printf("Vulkan device type: %s\n", deviceType.c_str());
printf("Vulkan version: %s (api) %s (driver)\n", apiVersion.c_str(), driverVersion.c_str());
}
bool GPURaytracer::IsNegativelyOriented(const vec2& v1, const vec2& v2, const vec2& v3)
{
float A =
v1.x * v2.y - v2.x * v1.y +
v2.x * v3.y - v3.x * v2.y +
v3.x * v1.y - v1.x * v3.y;
return A < 0.0f;
}

View file

@ -31,12 +31,9 @@ struct PushConstants
struct SurfaceInfo
{
vec3 Normal;
float EmissiveDistance;
vec3 EmissiveColor;
float EmissiveIntensity;
float Sky;
float SamplingDistance;
float Padding1, Padding2;
float Padding1, Padding2, Padding3;
};
struct LightInfo
@ -113,7 +110,6 @@ private:
std::vector<SurfaceInfo> CreateSurfaceInfo();
static vec2 ToUV(const vec3& vert, const Surface* targetSurface);
static bool IsNegativelyOriented(const vec2& v1, const vec2& v2, const vec2& v3);
LevelMesh* mesh = nullptr;

View file

@ -106,8 +106,6 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize)
}
}
CreateLightProbes(doomMap);
for (size_t i = 0; i < surfaces.size(); i++)
{
BuildSurfaceParams(surfaces[i].get());
@ -453,59 +451,6 @@ void LevelMesh::FinishSurface(RectPacker& packer, Surface* surface)
}
}
void LevelMesh::CreateLightProbes(FLevel& map)
{
float minX = std::floor(map.MinX / 65536.0f);
float minY = std::floor(map.MinY / 65536.0f);
float maxX = std::floor(map.MaxX / 65536.0f) + 1.0f;
float maxY = std::floor(map.MaxY / 65536.0f) + 1.0f;
float halfGridSize = map.GridSize * 0.5f;
float doubleGridSize = map.GridSize * 2.0f;
for (float y = minY; y < maxY; y += map.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;
if (sec)
{
float z0 = sec->floorplane.zAt(x, y);
float z1 = sec->ceilingplane.zAt(x, y);
float delta = z1 - z0;
if (delta > doubleGridSize)
{
LightProbeSample p[3];
p[0].Position = vec3(x, y, z0 + halfGridSize);
p[1].Position = vec3(x, y, z0 + (z1 - z0) * 0.5f);
p[2].Position = vec3(x, y, z1 - halfGridSize);
for (int i = 0; i < 3; i++)
{
lightProbes.push_back(p[i]);
}
}
else if (delta > 0.0f)
{
LightProbeSample probe;
probe.Position.x = x;
probe.Position.y = y;
probe.Position.z = z0 + (z1 - z0) * 0.5f;
lightProbes.push_back(probe);
}
}
}
}
for (unsigned int i = 0; i < map.ThingLightProbes.Size(); i++)
{
LightProbeSample probe;
probe.Position = map.GetLightProbePosition(i);
lightProbes.push_back(probe);
}
}
void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)
{
IntSector *front;
@ -947,8 +892,7 @@ void LevelMesh::AddLightmapLump(FWadWriter& wadFile)
int surfacesSize = surfaces.size() * 5 * sizeof(uint32_t);
int texCoordsSize = numTexCoords * 2 * sizeof(float);
int texDataSize = textures.size() * textureWidth * textureHeight * 3 * 2;
int lightProbesSize = lightProbes.size() * 6 * sizeof(float);
int lumpSize = headerSize + lightProbesSize + surfacesSize + texCoordsSize + texDataSize;
int lumpSize = headerSize + surfacesSize + texCoordsSize + texDataSize;
// Setup buffer
std::vector<uint8_t> buffer(lumpSize);
@ -961,20 +905,9 @@ void LevelMesh::AddLightmapLump(FWadWriter& wadFile)
lumpFile.Write16(textures.size());
lumpFile.Write32(numSurfaces);
lumpFile.Write32(numTexCoords);
lumpFile.Write32(lightProbes.size());
lumpFile.Write32(0); // old light probes list
lumpFile.Write32(map->NumGLSubsectors);
// Write light probes
for (const LightProbeSample& probe : lightProbes)
{
lumpFile.WriteFloat(probe.Position.x);
lumpFile.WriteFloat(probe.Position.y);
lumpFile.WriteFloat(probe.Position.z);
lumpFile.WriteFloat(probe.Color.x);
lumpFile.WriteFloat(probe.Color.y);
lumpFile.WriteFloat(probe.Color.z);
}
// Write surfaces
int coordOffsets = 0;
for (size_t i = 0; i < surfaces.size(); i++)

View file

@ -107,13 +107,6 @@ struct Surface
int smoothingGroupIndex = -1;
};
class LightProbeSample
{
public:
vec3 Position = vec3(0.0f, 0.0f, 0.0f);
vec3 Color = vec3(0.0f, 0.0f, 0.0f);
};
class LevelMesh
{
public:
@ -126,7 +119,6 @@ public:
FLevel* map = nullptr;
std::vector<std::unique_ptr<Surface>> surfaces;
std::vector<LightProbeSample> lightProbes;
std::vector<std::unique_ptr<LightmapTexture>> textures;
@ -148,7 +140,6 @@ private:
void CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor);
void CreateFloorSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor);
void CreateSideSurfaces(FLevel &doomMap, IntSideDef *side);
void CreateLightProbes(FLevel& doomMap);
void BuildSurfaceParams(Surface* surface);
BBox GetBoundsFromSurface(const Surface* surface);