fix: video without UI + correct colors
1. No UI in video: end render pass before ImGui, capture, start new render pass with loadOp=LOAD for ImGui, end again. Video captures only the 3D scene. 2. Acid colors fixed: swapchain format changed from B8G8R8A8_SRGB to B8G8R8A8_UNORM. SRGB format stores gamma-compressed values that vkCmdCopyImageToBuffer reads raw — FFmpeg treated them as linear causing acid colors. UNORM stores linear values, copy gives linear data, FFmpeg bgra→yuv420p conversion is correct.
This commit is contained in:
Binary file not shown.
@@ -361,12 +361,12 @@ internal sealed unsafe class VulkanContext : IDisposable
|
|||||||
var formats = stackalloc VkSurfaceFormatKHR[(int)formatCount];
|
var formats = stackalloc VkSurfaceFormatKHR[(int)formatCount];
|
||||||
Vk.vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, formats);
|
Vk.vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, formats);
|
||||||
|
|
||||||
SurfaceFormat = VkFormat.B8G8R8A8Srgb;
|
SurfaceFormat = VkFormat.B8G8R8A8Unorm;
|
||||||
SurfaceColorSpace = VkColorSpaceKHR.SrgbNonlinearKHR;
|
SurfaceColorSpace = VkColorSpaceKHR.SrgbNonlinearKHR;
|
||||||
|
|
||||||
for (uint i = 0; i < formatCount; i++)
|
for (uint i = 0; i < formatCount; i++)
|
||||||
{
|
{
|
||||||
if (formats[(int)i].format == VkFormat.B8G8R8A8Srgb &&
|
if (formats[(int)i].format == VkFormat.B8G8R8A8Unorm &&
|
||||||
formats[(int)i].colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR)
|
formats[(int)i].colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR)
|
||||||
{
|
{
|
||||||
SurfaceFormat = formats[(int)i].format;
|
SurfaceFormat = formats[(int)i].format;
|
||||||
@@ -375,7 +375,7 @@ internal sealed unsafe class VulkanContext : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SurfaceFormat == VkFormat.B8G8R8A8Srgb)
|
if (SurfaceFormat == VkFormat.B8G8R8A8Unorm)
|
||||||
{
|
{
|
||||||
SurfaceFormat = formats[0].format;
|
SurfaceFormat = formats[0].format;
|
||||||
SurfaceColorSpace = formats[0].colorSpace;
|
SurfaceColorSpace = formats[0].colorSpace;
|
||||||
|
|||||||
@@ -521,17 +521,41 @@ public sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreensh
|
|||||||
Vk.vkCmdDrawIndexed(cmd, dc.indexCount, 1, 0, 0, 0);
|
Vk.vkCmdDrawIndexed(cmd, dc.indexCount, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Capture BEFORE ImGui — video without UI
|
||||||
|
if (IsRecording)
|
||||||
|
{
|
||||||
|
// End rendering temporarily to do copy outside render pass
|
||||||
|
Vk.vkCmdEndRendering(cmd);
|
||||||
|
CaptureFrame(cmd, imageIndex);
|
||||||
|
|
||||||
|
// Start new render pass for ImGui
|
||||||
|
var imgClearValue = new VkClearValue
|
||||||
|
{
|
||||||
|
Color = new VkClearColorValue { Float0 = 0, Float1 = 0, Float2 = 0, Float3 = 0 },
|
||||||
|
};
|
||||||
|
var imgLoadAttachment = new VkRenderingAttachmentInfo
|
||||||
|
{
|
||||||
|
sType = VkStructureType.RenderingAttachmentInfo,
|
||||||
|
imageView = _swapchain.ImageViews[imageIndex],
|
||||||
|
imageLayout = VkImageLayout.ColorAttachmentOptimal,
|
||||||
|
loadOp = VkAttachmentLoadOp.Load, // Keep existing content
|
||||||
|
storeOp = VkAttachmentStoreOp.Store,
|
||||||
|
};
|
||||||
|
var imgRenderingInfo = new VkRenderingInfo
|
||||||
|
{
|
||||||
|
sType = VkStructureType.RenderingInfo,
|
||||||
|
renderArea = new VkRect2D { Offset = new VkOffset2D { X = 0, Y = 0 }, Extent = _swapchain.Extent },
|
||||||
|
layerCount = 1,
|
||||||
|
colorAttachmentCount = 1,
|
||||||
|
pColorAttachments = &imgLoadAttachment,
|
||||||
|
};
|
||||||
|
Vk.vkCmdBeginRendering(cmd, &imgRenderingInfo);
|
||||||
|
}
|
||||||
|
|
||||||
_imGui?.Render(cmd, _swapchain.Extent.Width, _swapchain.Extent.Height);
|
_imGui?.Render(cmd, _swapchain.Extent.Width, _swapchain.Extent.Height);
|
||||||
|
|
||||||
Vk.vkCmdEndRendering(cmd);
|
Vk.vkCmdEndRendering(cmd);
|
||||||
|
|
||||||
// Capture frame for video recording — AFTER render pass, BEFORE present
|
|
||||||
// This captures scene + ImGui. To capture without UI, we'd need separate render pass.
|
|
||||||
if (IsRecording)
|
|
||||||
{
|
|
||||||
CaptureFrame(cmd, imageIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
TransitionImageLayout(cmd, _swapchain.Images[imageIndex],
|
TransitionImageLayout(cmd, _swapchain.Images[imageIndex],
|
||||||
VkImageLayout.ColorAttachmentOptimal, VkImageLayout.PresentSrcKHR,
|
VkImageLayout.ColorAttachmentOptimal, VkImageLayout.PresentSrcKHR,
|
||||||
0x400, 0x100,
|
0x400, 0x100,
|
||||||
|
|||||||
Reference in New Issue
Block a user