diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp index de797519d..4e1e2887e 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp @@ -140,6 +140,12 @@ void VkLightmap::RenderBakeImage() cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 0, raytrace.descriptorSet0.get()); cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, raytrace.pipelineLayout.get(), 1, raytrace.descriptorSet1.get()); + VkViewport viewport = {}; + viewport.maxDepth = 1; + viewport.width = (float)bakeImageSize; + viewport.height = (float)bakeImageSize; + fb->GetCommands()->GetTransferCommands()->setViewport(0, 1, &viewport); + for (int i = 0, count = selectedSurfaces.Size(); i < count; i++) { auto& selectedSurface = selectedSurfaces[i]; @@ -151,14 +157,6 @@ void VkLightmap::RenderBakeImage() continue; } - VkViewport viewport = {}; - viewport.maxDepth = 1; - viewport.x = (float)selectedSurface.X - 1; - viewport.y = (float)selectedSurface.Y - 1; - viewport.width = (float)(targetSurface->texWidth + 2); - viewport.height = (float)(targetSurface->texHeight + 2); - fb->GetCommands()->GetTransferCommands()->setViewport(0, 1, &viewport); - bool buffersFull = false; // Paint all surfaces part of the smoothing group into the surface @@ -198,19 +196,20 @@ void VkLightmap::RenderBakeImage() LightmapPushConstants pc; pc.LightStart = firstLight; pc.LightEnd = firstLight + lightCount; - pc.TileX = selectedSurface.X; - pc.TileY = selectedSurface.Y; + pc.TileX = (float)selectedSurface.X; + pc.TileY = (float)selectedSurface.Y; pc.SurfaceIndex = mesh->GetSurfaceIndex(targetSurface); + pc.TextureSize = (float)bakeImageSize; pc.LightmapOrigin = targetSurface->worldOrigin - targetSurface->worldStepX - targetSurface->worldStepY; pc.LightmapStepX = targetSurface->worldStepX * viewport.width; pc.LightmapStepY = targetSurface->worldStepY * viewport.height; - pc.TileWidth = targetSurface->texWidth; - pc.TileHeight = targetSurface->texHeight; + pc.TileWidth = (float)targetSurface->texWidth; + pc.TileHeight = (float)targetSurface->texHeight; pc.WorldToLocal = targetSurface->translateWorldToLocal; pc.ProjLocalToU = targetSurface->projLocalToU; pc.ProjLocalToV = targetSurface->projLocalToV; - fb->GetCommands()->GetTransferCommands()->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapPushConstants), &pc); + fb->GetCommands()->GetTransferCommands()->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapPushConstants), &pc); fb->GetCommands()->GetTransferCommands()->drawIndexed(surface->numElements, 1, surface->startElementIndex, 0, 0); } diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.h b/src/common/rendering/vulkan/accelstructs/vk_lightmap.h index 203e1bd2c..d0ebbcf64 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.h +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.h @@ -24,7 +24,7 @@ struct LightmapPushConstants int32_t SurfaceIndex; int32_t PushPadding1; FVector3 LightmapOrigin; - float PushPadding2; + float TextureSize; FVector3 LightmapStepX; float PushPadding3; FVector3 LightmapStepY; @@ -35,10 +35,10 @@ struct LightmapPushConstants float PushPadding6; FVector3 ProjLocalToV; float PushPadding7; - int32_t TileX; - int32_t TileY; - int32_t TileWidth; - int32_t TileHeight; + float TileX; + float TileY; + float TileWidth; + float TileHeight; }; struct LightmapBakeImage diff --git a/wadsrc/static/shaders/lightmap/frag_raytrace.glsl b/wadsrc/static/shaders/lightmap/frag_raytrace.glsl index ae061f22a..eb743505a 100644 --- a/wadsrc/static/shaders/lightmap/frag_raytrace.glsl +++ b/wadsrc/static/shaders/lightmap/frag_raytrace.glsl @@ -75,7 +75,7 @@ layout(push_constant) uniform PushConstants int SurfaceIndex; int PushPadding1; vec3 LightmapOrigin; - float PushPadding2; + float TextureSize; vec3 LightmapStepX; float PushPadding3; vec3 LightmapStepY; @@ -86,10 +86,10 @@ layout(push_constant) uniform PushConstants float PushPadding6; vec3 ProjLocalToV; float PushPadding7; - int TileX; - int TileY; - int TileWidth; - int TileHeight; + float TileX; + float TileY; + float TileWidth; + float TileHeight; }; layout(location = 0) centroid in vec3 worldpos; diff --git a/wadsrc/static/shaders/lightmap/vert_raytrace.glsl b/wadsrc/static/shaders/lightmap/vert_raytrace.glsl index 2388b5cdb..e59b84029 100644 --- a/wadsrc/static/shaders/lightmap/vert_raytrace.glsl +++ b/wadsrc/static/shaders/lightmap/vert_raytrace.glsl @@ -6,7 +6,7 @@ layout(push_constant) uniform PushConstants int SurfaceIndex; int PushPadding1; vec3 LightmapOrigin; - float PushPadding2; + float TextureSize; vec3 LightmapStepX; float PushPadding3; vec3 LightmapStepY; @@ -17,10 +17,10 @@ layout(push_constant) uniform PushConstants float PushPadding6; vec3 ProjLocalToV; float PushPadding7; - int TileX; - int TileY; - int TileWidth; - int TileHeight; + float TileX; + float TileY; + float TileWidth; + float TileHeight; }; layout(location = 0) in vec3 aPosition; @@ -28,11 +28,19 @@ layout(location = 0) out vec3 worldpos; void main() { - vec3 localPos = aPosition - WorldToLocal; - float u = (1.0f + dot(localPos, ProjLocalToU)) / float(TileWidth + 2); - float v = (1.0f + dot(localPos, ProjLocalToV)) / float(TileHeight + 2); + worldpos = aPosition; - worldpos = LightmapOrigin + LightmapStepX * u + LightmapStepY * v; - gl_Position = vec4(vec2(u, v) * 2.0 - 1.0, 0.0, 1.0); + // Project to position relative to tile + vec3 localPos = aPosition - WorldToLocal; + float x = 1.0 + dot(localPos, ProjLocalToU); + float y = 1.0 + dot(localPos, ProjLocalToV); + + // Find the position in the output texture + gl_Position = vec4(vec2(TileX + x, TileY + y) / TextureSize * 2.0 - 1.0, 0.0, 1.0); + + // Clip all surfaces to the edge of the tile (effectly we are applying a viewport/scissor to the tile) + gl_ClipDistance[0] = x; + gl_ClipDistance[1] = y; + gl_ClipDistance[2] = TileWidth + 2.0 - x; + gl_ClipDistance[3] = TileHeight + 2.0 - y; } - \ No newline at end of file