From 73fb7080386ab6a0eec163ce8251e79e73488d3d Mon Sep 17 00:00:00 2001 From: 3dtours Date: Mon, 5 Oct 2026 20:37:19 +0700 Subject: [PATCH] fix(raw): apply invert3x3 matrix conversion to eliminate red-to-purple shadow artifacts --- docker/frontend/src/engine/rawDevelop.ts | 51 +++++++++++++----------- docker/recipescam-images.tar.gz.sha256 | 2 +- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/docker/frontend/src/engine/rawDevelop.ts b/docker/frontend/src/engine/rawDevelop.ts index 3acefc5..06fde7e 100644 --- a/docker/frontend/src/engine/rawDevelop.ts +++ b/docker/frontend/src/engine/rawDevelop.ts @@ -440,34 +440,39 @@ function invert3x3(m: number[][]): number[][] | null { } function getCamToSrgbMatrix(cd: any): number[][] { - if (cd?.cam_xyz && Array.isArray(cd.cam_xyz) && cd.cam_xyz.length >= 3) { - const cx = cd.cam_xyz; - const scale = (Math.abs(cx[0][0]) > 100) ? 10000.0 : 1.0; - const rX = (cx[0][0] || 0) / scale, rY = (cx[0][1] || 0) / scale, rZ = (cx[0][2] || 0) / scale; - const gX = (cx[1][0] || 0) / scale, gY = (cx[1][1] || 0) / scale, gZ = (cx[1][2] || 0) / scale; - const bX = (cx[2][0] || 0) / scale, bY = (cx[2][1] || 0) / scale, bZ = (cx[2][2] || 0) / scale; - - const m00 = 3.2404542 * rX - 1.5371385 * rY - 0.4985314 * rZ; - const m01 = 3.2404542 * gX - 1.5371385 * gY - 0.4985314 * gZ; - const m02 = 3.2404542 * bX - 1.5371385 * bY - 0.4985314 * bZ; - - const m10 = -0.9692660 * rX + 1.8760108 * rY + 0.0415560 * rZ; - const m11 = -0.9692660 * gX + 1.8760108 * gY + 0.0415560 * gZ; - const m12 = -0.9692660 * bX + 1.8760108 * bY + 0.0415560 * bZ; - - const m20 = 0.0556434 * rX - 0.2040259 * rY + 1.0572252 * rZ; - const m21 = 0.0556434 * gX - 0.2040259 * gY + 1.0572252 * gZ; - const m22 = 0.0556434 * bX - 0.2040259 * bY + 1.0572252 * bZ; - - return [[m00, m01, m02], [m10, m11, m12], [m20, m21, m22]]; - } - if (cd?.rgb_cam && Array.isArray(cd.rgb_cam) && cd.rgb_cam.length >= 3) { - return [ + const m = [ [cd.rgb_cam[0][0] || 0, cd.rgb_cam[0][1] || 0, cd.rgb_cam[0][2] || 0], [cd.rgb_cam[1][0] || 0, cd.rgb_cam[1][1] || 0, cd.rgb_cam[1][2] || 0], [cd.rgb_cam[2][0] || 0, cd.rgb_cam[2][1] || 0, cd.rgb_cam[2][2] || 0], ]; + const inv = invert3x3(m); + if (inv) return inv; + } + + if (cd?.cam_xyz && Array.isArray(cd.cam_xyz) && cd.cam_xyz.length >= 3) { + const cx = [ + [cd.cam_xyz[0][0] || 0, cd.cam_xyz[0][1] || 0, cd.cam_xyz[0][2] || 0], + [cd.cam_xyz[1][0] || 0, cd.cam_xyz[1][1] || 0, cd.cam_xyz[1][2] || 0], + [cd.cam_xyz[2][0] || 0, cd.cam_xyz[2][1] || 0, cd.cam_xyz[2][2] || 0], + ]; + const scale = (Math.abs(cx[0][0]) > 100) ? 10000.0 : 1.0; + for (let r = 0; r < 3; r++) for (let c = 0; c < 3; c++) cx[r][c] /= scale; + const inv = invert3x3(cx); + if (inv) { + const srgbXyz = [ + [3.2404542, -1.5371385, -0.4985314], + [-0.9692660, 1.8760108, 0.0415560], + [0.0556434, -0.2040259, 1.0572252], + ]; + const res = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]; + for (let r = 0; r < 3; r++) { + for (let c = 0; c < 3; c++) { + res[r][c] = srgbXyz[r][0] * inv[0][c] + srgbXyz[r][1] * inv[1][c] + srgbXyz[r][2] * inv[2][c]; + } + } + return res; + } } return [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; diff --git a/docker/recipescam-images.tar.gz.sha256 b/docker/recipescam-images.tar.gz.sha256 index ad8b1c8..6296189 100644 --- a/docker/recipescam-images.tar.gz.sha256 +++ b/docker/recipescam-images.tar.gz.sha256 @@ -1 +1 @@ -d749edf89fe3ff164055a13f1f434c1a362fd39b5939c16a2f3db0986502ef91 recipescam-images.tar.gz +9e207b823f47b6f92913c64c75c5a1bf2b3563898653652032f5f0429d4dbb49 recipescam-images.tar.gz