From 0479d4fce3f66c38a458840e4431117e87b473fb Mon Sep 17 00:00:00 2001 From: RaveYard Date: Wed, 15 Jun 2022 19:02:53 +0200 Subject: [PATCH] Support customizable sampling distance per surface - Fix sampleDistance UDMF - Refactoring code - Handle 3D floors sides via lm_sampledist_mid per each wall in the applied sector --- src/level/doomdata.h | 14 ++++++++++++- src/level/level.cpp | 2 +- src/level/level_light.cpp | 10 ++++----- src/level/level_udmf.cpp | 30 ++++++++++++++++++++++++++ src/lightmap/cpuraytracer.cpp | 5 ++--- src/lightmap/cpuraytracer.h | 1 - src/lightmap/glsl_rchit_ambient.h | 3 ++- src/lightmap/glsl_rchit_bounce.h | 3 ++- src/lightmap/glsl_rchit_light.h | 3 ++- src/lightmap/glsl_rchit_sun.h | 3 ++- src/lightmap/glsl_rgen_ambient.h | 7 ++++--- src/lightmap/glsl_rgen_bounce.h | 7 ++++--- src/lightmap/glsl_rgen_light.h | 11 +++++----- src/lightmap/gpuraytracer.cpp | 3 ++- src/lightmap/gpuraytracer.h | 7 ++++--- src/lightmap/levelmesh.cpp | 35 ++++++++++++++++++++----------- src/lightmap/levelmesh.h | 3 ++- 17 files changed, 104 insertions(+), 43 deletions(-) diff --git a/src/level/doomdata.h b/src/level/doomdata.h index cd619ad..c137fdf 100644 --- a/src/level/doomdata.h +++ b/src/level/doomdata.h @@ -60,6 +60,15 @@ struct IntSideDef IntLineDef *line; + int sampleDistance; + int sampleDistanceTop; + int sampleDistanceMiddle; + int sampleDistanceBottom; + + inline int GetSampleDistanceTop() const { return sampleDistanceTop ? sampleDistanceTop : sampleDistance; } + inline int GetSampleDistanceMiddle() const { return sampleDistanceMiddle ? sampleDistanceMiddle : sampleDistance; } + inline int GetSampleDistanceBottom() const { return sampleDistanceBottom ? sampleDistanceBottom : sampleDistance; } + TArray props; }; @@ -119,6 +128,9 @@ struct IntSector Plane ceilingplane; Plane floorplane; + int sampleDistanceCeiling; + int sampleDistanceFloor; + int floorlightdef; int ceilinglightdef; @@ -396,7 +408,7 @@ struct FLevel vec3 defaultSunColor; vec3 defaultSunDirection; - int Samples; + int DefaultSamples; int LightBounce; float GridSize; diff --git a/src/level/level.cpp b/src/level/level.cpp index 5edf062..d659fd3 100644 --- a/src/level/level.cpp +++ b/src/level/level.cpp @@ -694,7 +694,7 @@ void FProcessor::BuildNodes() void FProcessor::BuildLightmaps() { Level.SetupLights(); - LightmapMesh = std::make_unique(Level, Level.Samples, LMDims); + LightmapMesh = std::make_unique(Level, Level.DefaultSamples, LMDims); std::unique_ptr gpuraytracer; if (!CPURaytrace) diff --git a/src/level/level_light.cpp b/src/level/level_light.cpp index 8d8569a..e1bc076 100644 --- a/src/level/level_light.cpp +++ b/src/level/level_light.cpp @@ -87,7 +87,7 @@ void FLevel::SetupLights() // GG to whoever memset'ed FLevel defaultSunColor = vec3(1, 1, 1); defaultSunDirection = vec3(0.45f, 0.3f, 0.9f); - Samples = 8; + DefaultSamples = 8; LightBounce = 0; GridSize = 32.0f; @@ -128,10 +128,10 @@ void FLevel::SetupLights() } else if (!stricmp(key.key, "lm_sampledistance")) { - Samples = atoi(key.value); - if (Samples < 8) Samples = 8; - if (Samples > 128) Samples = 128; - Samples = Math::RoundPowerOfTwo(Samples); + DefaultSamples = atoi(key.value); + if (DefaultSamples < 8) DefaultSamples = 8; + if (DefaultSamples > 128) DefaultSamples = 128; + DefaultSamples = Math::RoundPowerOfTwo(DefaultSamples); } /* // light bounces temporarily disabled diff --git a/src/level/level_udmf.cpp b/src/level/level_udmf.cpp index 669d4a2..f9ee79a 100644 --- a/src/level/level_udmf.cpp +++ b/src/level/level_udmf.cpp @@ -365,6 +365,10 @@ void FProcessor::ParseSidedef(IntSideDef *sd) sd->midtexture[1] = 0; sd->bottomtexture[0] = '-'; sd->bottomtexture[1] = 0; + sd->sampleDistance = 0; + sd->sampleDistanceTop = 0; + sd->sampleDistanceMiddle = 0; + sd->sampleDistanceBottom = 0; while (!SC_CheckString("}")) { const char *value; @@ -396,6 +400,22 @@ void FProcessor::ParseSidedef(IntSideDef *sd) { sd->rowoffset = CheckInt(key); } + else if (stricmp(key, "lm_sampledist") == 0) + { + sd->sampleDistance = CheckInt(key); + } + else if (stricmp(key, "lm_sampledist_top") == 0) + { + sd->sampleDistanceTop = CheckInt(key); + } + else if (stricmp(key, "lm_sampledist_mid") == 0) + { + sd->sampleDistanceMiddle = CheckInt(key); + } + else if (stricmp(key, "lm_sampledist_bot") == 0) + { + sd->sampleDistanceBottom = CheckInt(key); + } // now store the key in its unprocessed form UDMFKey k = {key, value}; @@ -414,6 +434,8 @@ void FProcessor::ParseSector(IntSector *sec) std::vector moreids; memset(&sec->data, 0, sizeof(sec->data)); sec->data.lightlevel = 160; + sec->sampleDistanceCeiling = 0; + sec->sampleDistanceFloor = 0; int ceilingplane = 0, floorplane = 0; @@ -514,6 +536,14 @@ void FProcessor::ParseSector(IntSector *sec) free(workstring); } } + else if (stricmp(key, "lm_sampledist_floor") == 0) + { + sec->sampleDistanceFloor = CheckInt(key); + } + else if (stricmp(key, "lm_sampledist_ceiling") == 0) + { + sec->sampleDistanceCeiling = CheckInt(key); + } // now store the key in its unprocessed form UDMFKey k = {key, value}; diff --git a/src/lightmap/cpuraytracer.cpp b/src/lightmap/cpuraytracer.cpp index b31a8e3..78cd7aa 100644 --- a/src/lightmap/cpuraytracer.cpp +++ b/src/lightmap/cpuraytracer.cpp @@ -87,7 +87,6 @@ void CPURaytracer::RaytraceTask(const CPUTraceTask& task) state.StartSurface = nullptr; } - state.SampleDistance = (float)mesh->samples; state.LightCount = mesh->map->ThingLights.Size(); state.SunDir = mesh->map->GetSunDirection(); state.SunColor = mesh->map->GetSunColor(); @@ -260,7 +259,7 @@ void CPURaytracer::RunLightTrace(CPUTraceState& state) for (uint32_t i = 0; i < state.SampleCount; i++) { - vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * state.SampleDistance; + vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * float(surface->sampleDimension); vec3 origin2 = origin + e0 * offset.x + e1 * offset.y; vec3 start = origin2; @@ -316,7 +315,7 @@ void CPURaytracer::RunLightTrace(CPUTraceState& state) e0 = cross(normal, e1); for (uint32_t i = 0; i < state.SampleCount; i++) { - vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * state.SampleDistance; + vec2 offset = (Hammersley(i, state.SampleCount) - 0.5f) * float(surface->sampleDimension); vec3 origin2 = origin + e0 * offset.x + e1 * offset.y; LevelTraceHit hit = Trace(origin2, light.Origin); diff --git a/src/lightmap/cpuraytracer.h b/src/lightmap/cpuraytracer.h index 94c86e1..6ee55b4 100644 --- a/src/lightmap/cpuraytracer.h +++ b/src/lightmap/cpuraytracer.h @@ -29,7 +29,6 @@ struct CPUTraceState uint32_t PassType; uint32_t LightCount; vec3 SunDir; - float SampleDistance; vec3 SunColor; float SunIntensity; vec3 HemisphereVec; diff --git a/src/lightmap/glsl_rchit_ambient.h b/src/lightmap/glsl_rchit_ambient.h index 32e4578..2b04b8d 100644 --- a/src/lightmap/glsl_rchit_ambient.h +++ b/src/lightmap/glsl_rchit_ambient.h @@ -17,7 +17,8 @@ struct SurfaceInfo vec3 EmissiveColor; float EmissiveIntensity; float Sky; - float Padding0, Padding1, Padding2; + float SamplingDistance; + float Padding1, Padding2; }; layout(location = 0) rayPayloadInEXT hitPayload payload; diff --git a/src/lightmap/glsl_rchit_bounce.h b/src/lightmap/glsl_rchit_bounce.h index 3ab7cfe..54938bb 100644 --- a/src/lightmap/glsl_rchit_bounce.h +++ b/src/lightmap/glsl_rchit_bounce.h @@ -17,7 +17,8 @@ struct SurfaceInfo vec3 EmissiveColor; float EmissiveIntensity; float Sky; - float Padding0, Padding1, Padding2; + float SamplingDistance; + float Padding1, Padding2; }; layout(location = 0) rayPayloadInEXT hitPayload payload; diff --git a/src/lightmap/glsl_rchit_light.h b/src/lightmap/glsl_rchit_light.h index c8bde0a..488958f 100644 --- a/src/lightmap/glsl_rchit_light.h +++ b/src/lightmap/glsl_rchit_light.h @@ -17,7 +17,8 @@ struct SurfaceInfo vec3 EmissiveColor; float EmissiveIntensity; float Sky; - float Padding0, Padding1, Padding2; + float SamplingDistance; + float Padding1, Padding2; }; layout(location = 0) rayPayloadInEXT hitPayload payload; diff --git a/src/lightmap/glsl_rchit_sun.h b/src/lightmap/glsl_rchit_sun.h index 4f57ba5..82ceef7 100644 --- a/src/lightmap/glsl_rchit_sun.h +++ b/src/lightmap/glsl_rchit_sun.h @@ -17,7 +17,8 @@ struct SurfaceInfo vec3 EmissiveColor; float EmissiveIntensity; float Sky; - float Padding0, Padding1, Padding2; + float SamplingDistance; + float Padding1, Padding2; }; layout(location = 0) rayPayloadInEXT hitPayload payload; diff --git a/src/lightmap/glsl_rgen_ambient.h b/src/lightmap/glsl_rgen_ambient.h index c82c7d2..04002d6 100644 --- a/src/lightmap/glsl_rgen_ambient.h +++ b/src/lightmap/glsl_rgen_ambient.h @@ -24,11 +24,11 @@ layout(set = 0, binding = 4) uniform Uniforms uint PassType; uint Padding0; vec3 SunDir; - float SampleDistance; + float Padding1; vec3 SunColor; float SunIntensity; vec3 HemisphereVec; - float Padding1; + float Padding2; }; struct SurfaceInfo @@ -38,7 +38,8 @@ struct SurfaceInfo vec3 EmissiveColor; float EmissiveIntensity; float Sky; - float Padding0, Padding1, Padding2; + float SamplingDistance; + float Padding1, Padding2; }; layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; }; diff --git a/src/lightmap/glsl_rgen_bounce.h b/src/lightmap/glsl_rgen_bounce.h index 97ae3ac..25de9da 100644 --- a/src/lightmap/glsl_rgen_bounce.h +++ b/src/lightmap/glsl_rgen_bounce.h @@ -24,11 +24,11 @@ layout(set = 0, binding = 4) uniform Uniforms uint PassType; uint Padding0; vec3 SunDir; - float SampleDistance; + float Padding1; vec3 SunColor; float SunIntensity; vec3 HemisphereVec; - float Padding1; + float Padding2; }; struct SurfaceInfo @@ -38,7 +38,8 @@ struct SurfaceInfo vec3 EmissiveColor; float EmissiveIntensity; float Sky; - float Padding0, Padding1, Padding2; + float SamplingDistance; + float Padding1, Padding2; }; layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; }; diff --git a/src/lightmap/glsl_rgen_light.h b/src/lightmap/glsl_rgen_light.h index 29a539b..ccbc53b 100644 --- a/src/lightmap/glsl_rgen_light.h +++ b/src/lightmap/glsl_rgen_light.h @@ -24,11 +24,11 @@ layout(set = 0, binding = 4) uniform Uniforms uint PassType; uint Padding0; vec3 SunDir; - float SampleDistance; + float Padding1; vec3 SunColor; float SunIntensity; vec3 HemisphereVec; - float Padding1; + float Padding2; }; struct SurfaceInfo @@ -38,7 +38,8 @@ struct SurfaceInfo vec3 EmissiveColor; float EmissiveIntensity; float Sky; - float Padding0, Padding1, Padding2; + float SamplingDistance; + float Padding1, Padding2; }; struct LightInfo @@ -100,7 +101,7 @@ void main() for (uint i = 0; i < SampleCount; i++) { - vec2 offset = (Hammersley(i, SampleCount) - 0.5) * SampleDistance; + vec2 offset = (Hammersley(i, SampleCount) - 0.5) * surfaces[surfaceIndex].SamplingDistance; vec3 origin2 = origin + offset.x * e0 + offset.y * e1; traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 2, 0, 2, origin2, minDistance, SunDir, dist, 0); @@ -151,7 +152,7 @@ void main() e0 = cross(normal, e1); for (uint i = 0; i < SampleCount; i++) { - vec2 offset = (Hammersley(i, SampleCount) - 0.5) * SampleDistance; + vec2 offset = (Hammersley(i, SampleCount) - 0.5) * surfaces[surfaceIndex].SamplingDistance; vec3 origin2 = origin + offset.x * e0 + offset.y * e1; float dist2 = distance(light.Origin, origin2); diff --git a/src/lightmap/gpuraytracer.cpp b/src/lightmap/gpuraytracer.cpp index 495f308..0023b18 100644 --- a/src/lightmap/gpuraytracer.cpp +++ b/src/lightmap/gpuraytracer.cpp @@ -103,7 +103,6 @@ void GPURaytracer::Raytrace(LevelMesh* level) BeginTracing(); Uniforms uniforms = {}; - uniforms.SampleDistance = (float)mesh->samples; uniforms.SunDir = mesh->map->GetSunDirection(); uniforms.SunColor = mesh->map->GetSunColor(); uniforms.SunIntensity = 1.0f; @@ -403,6 +402,8 @@ void GPURaytracer::CreateVertexAndIndexBuffers() info.EmissiveIntensity = 0.0f; info.EmissiveColor = vec3(0.0f, 0.0f, 0.0f); } + + info.SamplingDistance = surface->sampleDimension; surfaces.push_back(info); } diff --git a/src/lightmap/gpuraytracer.h b/src/lightmap/gpuraytracer.h index a33a7d5..c71f0b8 100644 --- a/src/lightmap/gpuraytracer.h +++ b/src/lightmap/gpuraytracer.h @@ -13,11 +13,11 @@ struct Uniforms uint32_t PassType; uint32_t Padding0; vec3 SunDir; - float SampleDistance; + float Padding1; vec3 SunColor; float SunIntensity; vec3 HemisphereVec; - float Padding1; + float Padding2; }; struct PushConstants @@ -34,7 +34,8 @@ struct SurfaceInfo vec3 EmissiveColor; float EmissiveIntensity; float Sky; - float Padding0, Padding1, Padding2; + float SamplingDistance; + float Padding1, Padding2; }; struct LightInfo diff --git a/src/lightmap/levelmesh.cpp b/src/lightmap/levelmesh.cpp index f9fcffa..3bb6ca1 100644 --- a/src/lightmap/levelmesh.cpp +++ b/src/lightmap/levelmesh.cpp @@ -42,7 +42,7 @@ LevelMesh::LevelMesh(FLevel &doomMap, int sampleDistance, int textureSize) { map = &doomMap; - samples = sampleDistance; + defaultSamples = sampleDistance; textureWidth = textureSize; textureHeight = textureSize; @@ -132,13 +132,16 @@ void LevelMesh::BuildSurfaceParams(Surface* surface) plane = &surface->plane; bounds = GetBoundsFromSurface(surface); + if (surface->sampleDimension < 0) surface->sampleDimension = 1; + surface->sampleDimension = Math::RoundPowerOfTwo(surface->sampleDimension); + // round off dimentions for (i = 0; i < 3; i++) { - bounds.min[i] = samples * (Math::Floor(bounds.min[i] / samples) - 1); - bounds.max[i] = samples * (Math::Ceil(bounds.max[i] / samples) + 1); + bounds.min[i] = surface->sampleDimension * (Math::Floor(bounds.min[i] / surface->sampleDimension) - 1); + bounds.max[i] = surface->sampleDimension * (Math::Ceil(bounds.max[i] / surface->sampleDimension) + 1); - roundedSize[i] = (bounds.max[i] - bounds.min[i]) / samples; + roundedSize[i] = (bounds.max[i] - bounds.min[i]) / surface->sampleDimension; } tCoords[0] = vec3(0.0f); @@ -151,22 +154,22 @@ void LevelMesh::BuildSurfaceParams(Surface* surface) case Plane::AXIS_YZ: width = (int)roundedSize.y; height = (int)roundedSize.z; - tCoords[0].y = 1.0f / samples; - tCoords[1].z = 1.0f / samples; + tCoords[0].y = 1.0f / surface->sampleDimension; + tCoords[1].z = 1.0f / surface->sampleDimension; break; case Plane::AXIS_XZ: width = (int)roundedSize.x; height = (int)roundedSize.z; - tCoords[0].x = 1.0f / samples; - tCoords[1].z = 1.0f / samples; + tCoords[0].x = 1.0f / surface->sampleDimension; + tCoords[1].z = 1.0f / surface->sampleDimension; break; case Plane::AXIS_XY: width = (int)roundedSize.x; height = (int)roundedSize.y; - tCoords[0].x = 1.0f / samples; - tCoords[1].y = 1.0f / samples; + tCoords[0].x = 1.0f / surface->sampleDimension; + tCoords[1].y = 1.0f / surface->sampleDimension; break; } @@ -231,8 +234,8 @@ void LevelMesh::BuildSurfaceParams(Surface* surface) surface->lightmapDims[0] = width; surface->lightmapDims[1] = height; surface->lightmapOrigin = tOrigin; - surface->lightmapSteps[0] = tCoords[0] * (float)samples; - surface->lightmapSteps[1] = tCoords[1] * (float)samples; + surface->lightmapSteps[0] = tCoords[0] * (float)surface->sampleDimension; + surface->lightmapSteps[1] = tCoords[1] * (float)surface->sampleDimension; surface->samples.resize(width * height); surface->indirect.resize(width * height); @@ -518,11 +521,14 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side) float texWidth = 128.0f; float texHeight = 128.0f; + IntSideDef* otherSide = &doomMap.Sides[side->line->sidenum[0]] == side ? &doomMap.Sides[side->line->sidenum[1]] : &doomMap.Sides[side->line->sidenum[0]]; + auto surf = std::make_unique(); surf->material = "texture"; surf->type = ST_MIDDLESIDE; surf->typeIndex = typeIndex; surf->controlSector = xfloor; + surf->sampleDimension = (surf->sampleDimension = otherSide->GetSampleDistanceMiddle()) ? surf->sampleDimension : defaultSamples; surf->numVerts = 4; surf->verts.resize(4); surf->verts[0].x = surf->verts[2].x = v2.x; @@ -588,6 +594,7 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side) surf->type = ST_LOWERSIDE; surf->typeIndex = typeIndex; surf->controlSector = nullptr; + surf->sampleDimension = (surf->sampleDimension = side->GetSampleDistanceBottom()) ? surf->sampleDimension : defaultSamples; float texZ = surf->verts[0].z; @@ -646,6 +653,7 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side) surf->typeIndex = typeIndex; surf->bSky = bSky; surf->controlSector = nullptr; + surf->sampleDimension = (surf->sampleDimension = side->GetSampleDistanceTop()) ? surf->sampleDimension : defaultSamples; float texZ = surf->verts[0].z; @@ -692,6 +700,7 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side) surf->type = ST_MIDDLESIDE; surf->typeIndex = typeIndex; surf->controlSector = nullptr; + surf->sampleDimension = (surf->sampleDimension = side->GetSampleDistanceMiddle()) ? surf->sampleDimension : defaultSamples; float texZ = surf->verts[0].z; @@ -712,6 +721,7 @@ void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side) void LevelMesh::CreateFloorSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor) { auto surf = std::make_unique(); + surf->sampleDimension = sector->sampleDistanceFloor ? sector->sampleDistanceFloor : defaultSamples; surf->material = sector->data.floorpic; surf->numVerts = sub->numlines; surf->verts.resize(surf->numVerts); @@ -750,6 +760,7 @@ void LevelMesh::CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSe { auto surf = std::make_unique(); surf->material = sector->data.ceilingpic; + surf->sampleDimension = sector->sampleDistanceCeiling ? sector->sampleDistanceCeiling : defaultSamples; surf->numVerts = sub->numlines; surf->verts.resize(surf->numVerts); surf->uvs.resize(surf->numVerts); diff --git a/src/lightmap/levelmesh.h b/src/lightmap/levelmesh.h index e96d0f3..e4a168c 100644 --- a/src/lightmap/levelmesh.h +++ b/src/lightmap/levelmesh.h @@ -74,6 +74,7 @@ struct Surface bool bSky; std::vector uvs; std::string material; + int sampleDimension; }; class LightProbeSample @@ -99,7 +100,7 @@ public: std::vector> textures; - int samples = 16; + int defaultSamples = 16; int textureWidth = 128; int textureHeight = 128;