diff --git a/README.md b/README.md index f8d2342..463736c 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,13 @@ thing // ZDRayInfo (ZDRay properties for the map) thing // Lightmap point light (Light color and distance properties use the same args as dynamic lights) { type = 9876; + lm_sourceradius = <float> (default: 5, radius of the light source in map units; controls the softness) } thing // Lightmap spotlight (Light color, distance and angle properties use the same args as dynamic lights) { type = 9881; + lm_sourceradius = <float> (default: 5, radius of the light source in map units; controls the softness) } linedef diff --git a/src/level/doomdata.h b/src/level/doomdata.h index c5e7559..f1502eb 100644 --- a/src/level/doomdata.h +++ b/src/level/doomdata.h @@ -413,6 +413,7 @@ struct ThingLight float outerAngleCos; float height; float radius; + float sourceRadius; bool bCeiling; IntSector *sector; MapSubsectorEx *ssect; diff --git a/src/level/level_light.cpp b/src/level/level_light.cpp index faedb9e..6fa6bf5 100644 --- a/src/level/level_light.cpp +++ b/src/level/level_light.cpp @@ -247,6 +247,7 @@ void FLevel::CreateLights() float lightDistance = 0.0f; float innerAngleCos = -1.0f; float outerAngleCos = -1.0f; + float sourceradius = 5.0f; // need to process point lights and spot lights differently due to their // inconsistent arg usage... @@ -279,6 +280,14 @@ void FLevel::CreateLights() outerAngleCos = std::cos((float)thing->args[2] * 3.14159265359f / 180.0f); } + for (const auto& prop : thing->props) + { + if (!stricmp(prop.key, "lm_sourceradius")) + { + sourceradius = atof(prop.value); + } + } + // this is known as "intensity" on dynamic lights (and in UDB) lightDistance = thing->args[3]; @@ -304,6 +313,7 @@ void FLevel::CreateLights() thingLight.origin.X = x; thingLight.origin.Y = y; thingLight.sectorGroup = thingLight.sector->group; + thingLight.sourceRadius = sourceradius; ThingLights.Push(thingLight); } diff --git a/src/lightmapper/doom_levelmesh.cpp b/src/lightmapper/doom_levelmesh.cpp index 1e37c15..8a6984b 100644 --- a/src/lightmapper/doom_levelmesh.cpp +++ b/src/lightmapper/doom_levelmesh.cpp @@ -148,6 +148,7 @@ int DoomLevelMesh::GetLightIndex(ThingLight* light, int portalgroup) meshlight.OuterAngleCos = light->outerAngleCos; meshlight.SpotDir = light->SpotDir(); meshlight.Color = light->rgb; + meshlight.SourceRadius = light->sourceRadius; meshlight.SectorGroup = 0; // if (light->sector) diff --git a/src/lightmapper/glsl/binding_lightmapper.glsl.h b/src/lightmapper/glsl/binding_lightmapper.glsl.h index c24cc5a..5716c7f 100644 --- a/src/lightmapper/glsl/binding_lightmapper.glsl.h +++ b/src/lightmapper/glsl/binding_lightmapper.glsl.h @@ -38,7 +38,7 @@ struct LightInfo float InnerAngleCos; float OuterAngleCos; vec3 SpotDir; - float Padding2; + float SourceRadius; vec3 Color; float Padding3; }; diff --git a/src/lightmapper/glsl/trace_light.glsl.h b/src/lightmapper/glsl/trace_light.glsl.h index 840b7f5..3e00665 100644 --- a/src/lightmapper/glsl/trace_light.glsl.h +++ b/src/lightmapper/glsl/trace_light.glsl.h @@ -30,18 +30,25 @@ vec3 TraceLight(vec3 origin, vec3 normal, LightInfo light, float extraDistance) #if defined(USE_SOFTSHADOWS) - vec3 v = (abs(dir.x) > abs(dir.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0); - vec3 xdir = normalize(cross(dir, v)); - vec3 ydir = cross(dir, xdir); - - float lightsize = 10; - int step_count = 10; - for (int i = 0; i < step_count; i++) + if (light.SourceRadius != 0.0) { - vec2 gridoffset = getVogelDiskSample(i, step_count, gl_FragCoord.x + gl_FragCoord.y * 13.37) * lightsize; - vec3 pos = light.Origin + xdir * gridoffset.x + ydir * gridoffset.y; + vec3 v = (abs(dir.x) > abs(dir.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0); + vec3 xdir = normalize(cross(dir, v)); + vec3 ydir = cross(dir, xdir); - incoming += TracePointLightRay(origin, pos, minDistance, rayColor) / float(step_count); + float lightsize = light.SourceRadius; + int step_count = 10; + for (int i = 0; i < step_count; i++) + { + vec2 gridoffset = getVogelDiskSample(i, step_count, gl_FragCoord.x + gl_FragCoord.y * 13.37) * lightsize; + vec3 pos = light.Origin + xdir * gridoffset.x + ydir * gridoffset.y; + + incoming += TracePointLightRay(origin, pos, minDistance, rayColor) / float(step_count); + } + } + else + { + incoming += TracePointLightRay(origin, light.Origin, minDistance, rayColor); } #else diff --git a/src/lightmapper/hw_levelmeshlight.h b/src/lightmapper/hw_levelmeshlight.h index f2ebb6c..82ebf92 100644 --- a/src/lightmapper/hw_levelmeshlight.h +++ b/src/lightmapper/hw_levelmeshlight.h @@ -15,4 +15,5 @@ public: FVector3 SpotDir; FVector3 Color; int SectorGroup; + float SourceRadius; }; diff --git a/src/lightmapper/vk_levelmesh.cpp b/src/lightmapper/vk_levelmesh.cpp index 087b585..e894253 100644 --- a/src/lightmapper/vk_levelmesh.cpp +++ b/src/lightmapper/vk_levelmesh.cpp @@ -670,6 +670,7 @@ void VkLevelMeshUploader::UploadLights() info.OuterAngleCos = light.OuterAngleCos; info.SpotDir = SwapYZ(light.SpotDir); info.Color = light.Color; + info.SourceRadius = light.SourceRadius; *(lights++) = info; } diff --git a/src/lightmapper/vk_levelmesh.h b/src/lightmapper/vk_levelmesh.h index 9630bbf..5a74441 100644 --- a/src/lightmapper/vk_levelmesh.h +++ b/src/lightmapper/vk_levelmesh.h @@ -57,7 +57,7 @@ struct LightInfo float InnerAngleCos; float OuterAngleCos; FVector3 SpotDir; - float Padding2; + float SourceRadius; FVector3 Color; float Padding3; }; diff --git a/src/lightmapper/vk_lightmapper.cpp b/src/lightmapper/vk_lightmapper.cpp index 2f795f6..ba91043 100644 --- a/src/lightmapper/vk_lightmapper.cpp +++ b/src/lightmapper/vk_lightmapper.cpp @@ -37,8 +37,6 @@ VkLightmapper::VkLightmapper(VulkanRenderDevice* fb) : fb(fb) { useRayQuery = fb->IsRayQueryEnabled(); - templightlist.Resize(128); - try { CreateUniformBuffer(); diff --git a/src/lightmapper/vk_lightmapper.h b/src/lightmapper/vk_lightmapper.h index b3c19ca..8f5ba84 100644 --- a/src/lightmapper/vk_lightmapper.h +++ b/src/lightmapper/vk_lightmapper.h @@ -148,7 +148,6 @@ private: TArray selectedTiles; TArray> copylists; - TArray templightlist; struct {