From 0831e18c2d0adbc911d60eb675a922c9bee65f58 Mon Sep 17 00:00:00 2001 From: Aiden Date: Fri, 8 May 2026 15:52:58 +1000 Subject: [PATCH] Updated shader and fixed PNG output --- .../gl/PngScreenshotWriter.cpp | 18 +++++--- image.png | Bin 48830 -> 0 bytes .../shader.json | 33 +++++++++------ .../shader.slang | 40 ++++++++++++++++-- 4 files changed, 69 insertions(+), 22 deletions(-) delete mode 100644 image.png diff --git a/apps/LoopThroughWithOpenGLCompositing/gl/PngScreenshotWriter.cpp b/apps/LoopThroughWithOpenGLCompositing/gl/PngScreenshotWriter.cpp index 3771acd..b1544ea 100644 --- a/apps/LoopThroughWithOpenGLCompositing/gl/PngScreenshotWriter.cpp +++ b/apps/LoopThroughWithOpenGLCompositing/gl/PngScreenshotWriter.cpp @@ -20,10 +20,10 @@ bool WritePngFile( const std::filesystem::path& outputPath, unsigned width, unsigned height, - const std::vector& rgbaPixels, + const std::vector& bgraPixels, std::string& error) { - if (width == 0 || height == 0 || rgbaPixels.size() < static_cast(width) * height * 4) + if (width == 0 || height == 0 || bgraPixels.size() < static_cast(width) * height * 4) { error = "Invalid screenshot dimensions or pixel buffer."; return false; @@ -83,19 +83,19 @@ bool WritePngFile( if (SUCCEEDED(result)) result = frame->SetSize(width, height); - WICPixelFormatGUID pixelFormat = GUID_WICPixelFormat32bppRGBA; + WICPixelFormatGUID pixelFormat = GUID_WICPixelFormat32bppBGRA; if (SUCCEEDED(result)) result = frame->SetPixelFormat(&pixelFormat); - if (SUCCEEDED(result) && pixelFormat != GUID_WICPixelFormat32bppRGBA) + if (SUCCEEDED(result) && pixelFormat != GUID_WICPixelFormat32bppBGRA) { - error = "PNG encoder did not accept RGBA pixel format."; + error = "PNG encoder did not accept BGRA pixel format."; result = E_FAIL; } const UINT stride = width * 4; const UINT imageSize = stride * height; if (SUCCEEDED(result)) - result = frame->WritePixels(height, stride, imageSize, const_cast(rgbaPixels.data())); + result = frame->WritePixels(height, stride, imageSize, const_cast(bgraPixels.data())); if (SUCCEEDED(result)) result = frame->Commit(); if (SUCCEEDED(result)) @@ -107,6 +107,8 @@ bool WritePngFile( if (FAILED(result)) { error = "Could not write screenshot PNG: " + HResultToString(result); + std::error_code ignored; + std::filesystem::remove(outputPath, ignored); return false; } @@ -123,6 +125,9 @@ void WritePngFileAsync( std::thread( [outputPath, width, height, pixels = std::move(rgbaPixels)]() mutable { + for (std::size_t index = 0; index + 3 < pixels.size(); index += 4) + std::swap(pixels[index], pixels[index + 2]); + std::string error; if (!WritePngFile(outputPath, width, height, pixels, error)) OutputDebugStringA(("Screenshot write failed: " + error + "\n").c_str()); @@ -130,4 +135,3 @@ void WritePngFileAsync( OutputDebugStringA(("Screenshot written: " + outputPath.string() + "\n").c_str()); }).detach(); } - diff --git a/image.png b/image.png deleted file mode 100644 index f8ceba4c09059daa70025f65e845d7eaaa4be5a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48830 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 diff --git a/shaders/fisheye-equirectangular-mirror/shader.json b/shaders/fisheye-equirectangular-mirror/shader.json index 84cd1eb..d4d9fdb 100644 --- a/shaders/fisheye-equirectangular-mirror/shader.json +++ b/shaders/fisheye-equirectangular-mirror/shader.json @@ -1,7 +1,7 @@ { "id": "fisheye-equirectangular-mirror", "name": "Fisheye Equirectangular Mirror", - "description": "Unwraps a single fisheye lens into a 360x180 equirectangular map by mirroring the rear hemisphere into the same fisheye source.", + "description": "Unwraps a single width-filled 16:9 fisheye lens into a 360x180 equirectangular map by mirroring the rear hemisphere into the same fisheye source.", "category": "Projection", "entryPoint": "shadeVideo", "parameters": [ @@ -9,7 +9,7 @@ "id": "lensFovDegrees", "label": "Lens FOV", "type": "float", - "default": 180.0, + "default": 190.0, "min": 1.0, "max": 220.0, "step": 0.1 @@ -27,7 +27,7 @@ "id": "radius", "label": "Fisheye Radius", "type": "vec2", - "default": [0.5, 0.5], + "default": [0.5, 0.8889], "min": [0.001, 0.001], "max": [2.0, 2.0], "step": [0.001, 0.001] @@ -59,15 +59,6 @@ "max": 180.0, "step": 0.1 }, - { - "id": "seamAngleDegrees", - "label": "Seam Angle", - "type": "float", - "default": 0.0, - "min": -180.0, - "max": 180.0, - "step": 0.1 - }, { "id": "fisheyeModel", "label": "Fisheye Model", @@ -80,6 +71,24 @@ { "value": "orthographic", "label": "Orthographic" } ] }, + { + "id": "edgeFill", + "label": "Edge Fill", + "type": "float", + "default": 0.06, + "min": 0.0, + "max": 0.3, + "step": 0.001 + }, + { + "id": "edgeBlur", + "label": "Edge Blur", + "type": "float", + "default": 0.018, + "min": 0.0, + "max": 0.12, + "step": 0.001 + }, { "id": "outsideColor", "label": "Outside Color", diff --git a/shaders/fisheye-equirectangular-mirror/shader.slang b/shaders/fisheye-equirectangular-mirror/shader.slang index f871453..9a6c4ae 100644 --- a/shaders/fisheye-equirectangular-mirror/shader.slang +++ b/shaders/fisheye-equirectangular-mirror/shader.slang @@ -49,7 +49,7 @@ float normalizedFisheyeRadius(float theta, float halfFov) float3 equirectangularRay(float2 uv) { - float longitude = (uv.x - 0.5) * TWO_PI + radiansFromDegrees(seamAngleDegrees); + float longitude = (uv.x - 0.5) * TWO_PI; float latitude = (0.5 - uv.y) * PI; float latitudeCos = cos(latitude); @@ -60,6 +60,39 @@ float3 equirectangularRay(float2 uv) )); } +float sourceUvOutsideDistance(float2 uv) +{ + float2 lower = max(-uv, float2(0.0, 0.0)); + float2 upper = max(uv - 1.0, float2(0.0, 0.0)); + return max(max(lower.x, lower.y), max(upper.x, upper.y)); +} + +float4 sampleEdgeFilledVideo(float2 sourceUv, ShaderContext context) +{ + float outsideDistance = sourceUvOutsideDistance(sourceUv); + if (outsideDistance <= 0.0) + return sampleVideo(sourceUv); + + float fillDistance = max(edgeFill, 0.0); + if (outsideDistance > fillDistance) + return outsideColor; + + float2 clampedUv = saturate(sourceUv); + float2 inward = clampedUv - sourceUv; + float inwardLength = max(length(inward), 0.000001); + inward /= inwardLength; + + float blurDistance = max(edgeBlur, 0.0); + float4 color = sampleVideo(clampedUv) * 0.32; + color += sampleVideo(saturate(clampedUv + inward * blurDistance * 0.35)) * 0.26; + color += sampleVideo(saturate(clampedUv + inward * blurDistance * 0.75)) * 0.20; + color += sampleVideo(saturate(clampedUv + inward * blurDistance * 1.20)) * 0.14; + color += sampleVideo(saturate(clampedUv + inward * blurDistance * 1.75)) * 0.08; + + float edgeFade = smoothstep(fillDistance * 0.78, fillDistance, outsideDistance); + return lerp(color, outsideColor, edgeFade); +} + float4 shadeVideo(ShaderContext context) { float3 ray = equirectangularRay(context.uv); @@ -86,8 +119,9 @@ float4 shadeVideo(ShaderContext context) center.y - sin(phi) * fisheyeRadius * radius.y ); - if (sourceUv.x < 0.0 || sourceUv.x > 1.0 || sourceUv.y < 0.0 || sourceUv.y > 1.0) + float2 guard = 0.5 / max(context.inputResolution, float2(1.0, 1.0)); + if (edgeFill <= 0.0 && (sourceUv.x < -guard.x || sourceUv.x > 1.0 + guard.x || sourceUv.y < -guard.y || sourceUv.y > 1.0 + guard.y)) return outsideColor; - return sampleVideo(sourceUv); + return sampleEdgeFilledVideo(sourceUv, context); }