diff --git a/apps/web/e2e/avatar-expression-lab.spec.ts b/apps/web/e2e/avatar-expression-lab.spec.ts index 0b7b790..42b7bee 100644 --- a/apps/web/e2e/avatar-expression-lab.spec.ts +++ b/apps/web/e2e/avatar-expression-lab.spec.ts @@ -53,26 +53,35 @@ test.describe("avatar expression lab", () => { ); await expect(panel.locator('[data-expression-card="true"]')).toHaveCount(28); + const cardRenderers = panel.locator( + '.axl__card .vg-avatar [data-avatar-renderer="linocut"]', + ); + await expect(cardRenderers).toHaveCount(28); + await expect + .poll( + async () => + cardRenderers.evaluateAll( + (els) => els.filter((el) => el.getAttribute("data-load-state") === "ready").length, + ), + { timeout: 20_000 }, + ) + .toBe(28); + const sectionMetrics = await panel.evaluate((el) => { const avatars = Array.from(el.querySelectorAll(".axl__card .vg-avatar")); const invalid = avatars .map((avatar) => { - const neck = avatar.querySelector('[data-avatar-neck="true"]'); - const svg = avatar.querySelector("svg"); + const renderer = avatar.querySelector('[data-avatar-renderer="linocut"]'); + const svg = avatar.querySelector(".linocut-avatar"); return { affect: avatar.getAttribute("data-affect"), - primitives: avatar.querySelectorAll("svg path, svg ellipse, svg circle, svg line, svg rect") - .length, - neckBox: neck?.getBoundingClientRect().toJSON(), + loadState: renderer?.getAttribute("data-load-state"), svgBox: svg?.getBoundingClientRect().toJSON(), }; }) .filter((item) => { return ( - item.primitives < 12 || - !item.neckBox || - item.neckBox.width <= 8 || - item.neckBox.height <= 14 || + item.loadState !== "ready" || !item.svgBox || item.svgBox.width <= 0 || item.svgBox.height <= 0 diff --git a/apps/web/e2e/avatar-expression.spec.ts b/apps/web/e2e/avatar-expression.spec.ts index 1262eaa..84b1e17 100644 --- a/apps/web/e2e/avatar-expression.spec.ts +++ b/apps/web/e2e/avatar-expression.spec.ts @@ -197,6 +197,10 @@ test.describe("persona avatar expression rig", () => { await expect(avatar).toBeVisible(); await expect(avatar).toHaveAttribute("data-affect", persona.expectedExpression); + const v3 = avatar.locator('[data-avatar-renderer="linocut"]'); + await expect(v3).toHaveAttribute("data-load-state", "ready", { timeout: 15_000 }); + await expect(v3.locator(".linocut-avatar")).toBeVisible(); + const metrics = await avatar.evaluate((el) => ({ expressionCount: Number(el.getAttribute("data-expression-count")), live2dSchema: el.getAttribute("data-live2d-schema"), @@ -207,10 +211,7 @@ test.describe("persona avatar expression rig", () => { live2dExpressionCount: Number(el.getAttribute("data-live2d-expression-count")), renderMode: el.getAttribute("data-render-mode"), rasterCount: el.querySelectorAll(".vg-raster").length, - primitiveCount: el.querySelectorAll("svg path, svg ellipse, svg circle, svg line, svg rect") - .length, - neckBox: el.querySelector('[data-avatar-neck="true"]')?.getBoundingClientRect().toJSON(), - svgBox: el.querySelector("svg")?.getBoundingClientRect().toJSON(), + v3Box: el.querySelector(".linocut-avatar")?.getBoundingClientRect().toJSON(), })); expect(metrics.expressionCount, `${persona.code} expression count`).toBeGreaterThanOrEqual(20); expect(metrics.live2dSchema, `${persona.code} Live2D schema`).toBe("vignette.live2d.v1"); @@ -225,10 +226,8 @@ test.describe("persona avatar expression rig", () => { expect(metrics.live2dExpressionCount, `${persona.code} Live2D expressions`).toBeGreaterThanOrEqual(20); expect(metrics.renderMode, `${persona.code} render mode`).toBe("svg"); expect(metrics.rasterCount, `${persona.code} raster rig should be disabled`).toBe(0); - expect(metrics.primitiveCount, `${persona.code} SVG primitives`).toBeGreaterThan(10); - expect(metrics.neckBox?.width, `${persona.code} SVG neck`).toBeGreaterThan(0); - expect(metrics.svgBox?.width, `${persona.code} SVG rig`).toBeGreaterThan(0); - expect(metrics.svgBox?.height, `${persona.code} SVG rig`).toBeGreaterThan(0); + expect(metrics.v3Box?.width, `${persona.code} linocut SVG`).toBeGreaterThan(0); + expect(metrics.v3Box?.height, `${persona.code} linocut SVG`).toBeGreaterThan(0); } }); @@ -261,9 +260,10 @@ test.describe("persona avatar expression rig", () => { const activeAvatar = page.locator(".sx-page--active .vg-avatar").first(); await expect(activeAvatar).toBeVisible(); - await expect(activeAvatar).toHaveAttribute("data-render-mode", "svg"); + const activeV3 = activeAvatar.locator('[data-avatar-renderer="linocut"]'); + await expect(activeV3).toHaveAttribute("data-load-state", "ready", { timeout: 15_000 }); + await expect(activeV3.locator(".linocut-avatar")).toBeVisible(); await expect(activeAvatar.locator(".vg-raster")).toHaveCount(0); - await expect(activeAvatar.locator(".vg-avatar__svg")).toBeVisible(); await expect(activeAvatar).toHaveAttribute("data-expression-count", "28"); await expect(activeAvatar).toHaveAttribute("data-live2d-expression-count", "28"); await expect(activeAvatar).toHaveAttribute("data-live2d-model", "vignette-p4-live2d"); @@ -316,9 +316,10 @@ test.describe("persona avatar expression rig", () => { await page.getByRole("button", { name: "회기 시작" }).click(); await expect(page.locator(".sx-page--active")).toBeVisible(); const activeAvatar = page.locator(".sx-page--active .vg-avatar").first(); - await expect(activeAvatar).toHaveAttribute("data-render-mode", "svg"); + const activeV3 = activeAvatar.locator('[data-avatar-renderer="linocut"]'); + await expect(activeV3).toHaveAttribute("data-load-state", "ready", { timeout: 15_000 }); + await expect(activeV3.locator(".linocut-avatar")).toBeVisible(); await expect(activeAvatar.locator(".vg-raster")).toHaveCount(0); - await expect(activeAvatar.locator(".vg-avatar__svg")).toBeVisible(); await expect(activeAvatar).toHaveAttribute("data-live2d-motion", "anxious"); await setLearnerUtterance(page, "조금 안정된 것 같아요."); diff --git a/apps/web/public/avatar/v3/p2/body.webp b/apps/web/public/avatar/v3/p2/body.webp new file mode 100644 index 0000000..391c563 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/body.webp differ diff --git a/apps/web/public/avatar/v3/p2/brow-left.webp b/apps/web/public/avatar/v3/p2/brow-left.webp new file mode 100644 index 0000000..8291391 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/brow-left.webp differ diff --git a/apps/web/public/avatar/v3/p2/brow-right.webp b/apps/web/public/avatar/v3/p2/brow-right.webp new file mode 100644 index 0000000..abb1aaa Binary files /dev/null and b/apps/web/public/avatar/v3/p2/brow-right.webp differ diff --git a/apps/web/public/avatar/v3/p2/face-detail.webp b/apps/web/public/avatar/v3/p2/face-detail.webp new file mode 100644 index 0000000..5383556 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/face-detail.webp differ diff --git a/apps/web/public/avatar/v3/p2/hair-front.webp b/apps/web/public/avatar/v3/p2/hair-front.webp new file mode 100644 index 0000000..6b0dc53 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/hair-front.webp differ diff --git a/apps/web/public/avatar/v3/p2/head.webp b/apps/web/public/avatar/v3/p2/head.webp new file mode 100644 index 0000000..b87cdb7 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/head.webp differ diff --git a/apps/web/public/avatar/v3/p2/jaw-detail.webp b/apps/web/public/avatar/v3/p2/jaw-detail.webp new file mode 100644 index 0000000..4d80292 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/jaw-detail.webp differ diff --git a/apps/web/public/avatar/v3/p2/jaw-head.webp b/apps/web/public/avatar/v3/p2/jaw-head.webp new file mode 100644 index 0000000..d04bde7 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/jaw-head.webp differ diff --git a/apps/web/public/avatar/v3/p2/lip-lower.webp b/apps/web/public/avatar/v3/p2/lip-lower.webp new file mode 100644 index 0000000..5fc702d Binary files /dev/null and b/apps/web/public/avatar/v3/p2/lip-lower.webp differ diff --git a/apps/web/public/avatar/v3/p2/lip-shadow.webp b/apps/web/public/avatar/v3/p2/lip-shadow.webp new file mode 100644 index 0000000..62b17a0 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/lip-shadow.webp differ diff --git a/apps/web/public/avatar/v3/p2/lip-upper.webp b/apps/web/public/avatar/v3/p2/lip-upper.webp new file mode 100644 index 0000000..8199c13 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/lip-upper.webp differ diff --git a/apps/web/public/avatar/v3/p2/paper-grain.webp b/apps/web/public/avatar/v3/p2/paper-grain.webp new file mode 100644 index 0000000..305bb90 Binary files /dev/null and b/apps/web/public/avatar/v3/p2/paper-grain.webp differ diff --git a/apps/web/public/avatar/v3/p3/body.webp b/apps/web/public/avatar/v3/p3/body.webp new file mode 100644 index 0000000..0ce7d30 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/body.webp differ diff --git a/apps/web/public/avatar/v3/p3/brow-left.webp b/apps/web/public/avatar/v3/p3/brow-left.webp new file mode 100644 index 0000000..cda8bf7 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/brow-left.webp differ diff --git a/apps/web/public/avatar/v3/p3/brow-right.webp b/apps/web/public/avatar/v3/p3/brow-right.webp new file mode 100644 index 0000000..a3a3b5e Binary files /dev/null and b/apps/web/public/avatar/v3/p3/brow-right.webp differ diff --git a/apps/web/public/avatar/v3/p3/face-detail.webp b/apps/web/public/avatar/v3/p3/face-detail.webp new file mode 100644 index 0000000..86d4b50 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/face-detail.webp differ diff --git a/apps/web/public/avatar/v3/p3/hair-front.webp b/apps/web/public/avatar/v3/p3/hair-front.webp new file mode 100644 index 0000000..abb1b18 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/hair-front.webp differ diff --git a/apps/web/public/avatar/v3/p3/head.webp b/apps/web/public/avatar/v3/p3/head.webp new file mode 100644 index 0000000..5c64bef Binary files /dev/null and b/apps/web/public/avatar/v3/p3/head.webp differ diff --git a/apps/web/public/avatar/v3/p3/jaw-detail.webp b/apps/web/public/avatar/v3/p3/jaw-detail.webp new file mode 100644 index 0000000..8f701d3 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/jaw-detail.webp differ diff --git a/apps/web/public/avatar/v3/p3/jaw-head.webp b/apps/web/public/avatar/v3/p3/jaw-head.webp new file mode 100644 index 0000000..4b114f7 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/jaw-head.webp differ diff --git a/apps/web/public/avatar/v3/p3/lip-lower.webp b/apps/web/public/avatar/v3/p3/lip-lower.webp new file mode 100644 index 0000000..636486a Binary files /dev/null and b/apps/web/public/avatar/v3/p3/lip-lower.webp differ diff --git a/apps/web/public/avatar/v3/p3/lip-shadow.webp b/apps/web/public/avatar/v3/p3/lip-shadow.webp new file mode 100644 index 0000000..0d1d7d7 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/lip-shadow.webp differ diff --git a/apps/web/public/avatar/v3/p3/lip-upper.webp b/apps/web/public/avatar/v3/p3/lip-upper.webp new file mode 100644 index 0000000..9adec63 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/lip-upper.webp differ diff --git a/apps/web/public/avatar/v3/p3/paper-grain.webp b/apps/web/public/avatar/v3/p3/paper-grain.webp new file mode 100644 index 0000000..c788e40 Binary files /dev/null and b/apps/web/public/avatar/v3/p3/paper-grain.webp differ diff --git a/apps/web/public/avatar/v3/p4/body.webp b/apps/web/public/avatar/v3/p4/body.webp new file mode 100644 index 0000000..5d5fca0 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/body.webp differ diff --git a/apps/web/public/avatar/v3/p4/brow-left.webp b/apps/web/public/avatar/v3/p4/brow-left.webp new file mode 100644 index 0000000..41c6802 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/brow-left.webp differ diff --git a/apps/web/public/avatar/v3/p4/brow-right.webp b/apps/web/public/avatar/v3/p4/brow-right.webp new file mode 100644 index 0000000..2ea8b25 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/brow-right.webp differ diff --git a/apps/web/public/avatar/v3/p4/face-detail.webp b/apps/web/public/avatar/v3/p4/face-detail.webp new file mode 100644 index 0000000..7f549b0 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/face-detail.webp differ diff --git a/apps/web/public/avatar/v3/p4/hair-front.webp b/apps/web/public/avatar/v3/p4/hair-front.webp new file mode 100644 index 0000000..69c27f8 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/hair-front.webp differ diff --git a/apps/web/public/avatar/v3/p4/head.webp b/apps/web/public/avatar/v3/p4/head.webp new file mode 100644 index 0000000..b4cead5 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/head.webp differ diff --git a/apps/web/public/avatar/v3/p4/jaw-detail.webp b/apps/web/public/avatar/v3/p4/jaw-detail.webp new file mode 100644 index 0000000..9d2df37 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/jaw-detail.webp differ diff --git a/apps/web/public/avatar/v3/p4/jaw-head.webp b/apps/web/public/avatar/v3/p4/jaw-head.webp new file mode 100644 index 0000000..78853bf Binary files /dev/null and b/apps/web/public/avatar/v3/p4/jaw-head.webp differ diff --git a/apps/web/public/avatar/v3/p4/lip-lower.webp b/apps/web/public/avatar/v3/p4/lip-lower.webp new file mode 100644 index 0000000..d688a98 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/lip-lower.webp differ diff --git a/apps/web/public/avatar/v3/p4/lip-shadow.webp b/apps/web/public/avatar/v3/p4/lip-shadow.webp new file mode 100644 index 0000000..bd16975 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/lip-shadow.webp differ diff --git a/apps/web/public/avatar/v3/p4/lip-upper.webp b/apps/web/public/avatar/v3/p4/lip-upper.webp new file mode 100644 index 0000000..15e43ff Binary files /dev/null and b/apps/web/public/avatar/v3/p4/lip-upper.webp differ diff --git a/apps/web/public/avatar/v3/p4/paper-grain.webp b/apps/web/public/avatar/v3/p4/paper-grain.webp new file mode 100644 index 0000000..cd0eeb1 Binary files /dev/null and b/apps/web/public/avatar/v3/p4/paper-grain.webp differ diff --git a/apps/web/public/avatar/v3/p5/body.webp b/apps/web/public/avatar/v3/p5/body.webp new file mode 100644 index 0000000..9bc0a21 Binary files /dev/null and b/apps/web/public/avatar/v3/p5/body.webp differ diff --git a/apps/web/public/avatar/v3/p5/brow-left.webp b/apps/web/public/avatar/v3/p5/brow-left.webp new file mode 100644 index 0000000..c87d599 Binary files /dev/null and b/apps/web/public/avatar/v3/p5/brow-left.webp differ diff --git a/apps/web/public/avatar/v3/p5/brow-right.webp b/apps/web/public/avatar/v3/p5/brow-right.webp new file mode 100644 index 0000000..ec8627f Binary files /dev/null and b/apps/web/public/avatar/v3/p5/brow-right.webp differ diff --git a/apps/web/public/avatar/v3/p5/face-detail.webp b/apps/web/public/avatar/v3/p5/face-detail.webp new file mode 100644 index 0000000..7621782 Binary files /dev/null and b/apps/web/public/avatar/v3/p5/face-detail.webp differ diff --git a/apps/web/public/avatar/v3/p5/hair-front.webp b/apps/web/public/avatar/v3/p5/hair-front.webp new file mode 100644 index 0000000..aea0a1c Binary files /dev/null and b/apps/web/public/avatar/v3/p5/hair-front.webp differ diff --git a/apps/web/public/avatar/v3/p5/head.webp b/apps/web/public/avatar/v3/p5/head.webp new file mode 100644 index 0000000..66d6fbc Binary files /dev/null and b/apps/web/public/avatar/v3/p5/head.webp differ diff --git a/apps/web/public/avatar/v3/p5/jaw-detail.webp b/apps/web/public/avatar/v3/p5/jaw-detail.webp new file mode 100644 index 0000000..478dc07 Binary files /dev/null and b/apps/web/public/avatar/v3/p5/jaw-detail.webp differ diff --git a/apps/web/public/avatar/v3/p5/jaw-head.webp b/apps/web/public/avatar/v3/p5/jaw-head.webp new file mode 100644 index 0000000..559d8a3 Binary files /dev/null and b/apps/web/public/avatar/v3/p5/jaw-head.webp differ diff --git a/apps/web/public/avatar/v3/p5/lip-lower.webp b/apps/web/public/avatar/v3/p5/lip-lower.webp new file mode 100644 index 0000000..1ff4eda Binary files /dev/null and b/apps/web/public/avatar/v3/p5/lip-lower.webp differ diff --git a/apps/web/public/avatar/v3/p5/lip-shadow.webp b/apps/web/public/avatar/v3/p5/lip-shadow.webp new file mode 100644 index 0000000..731338f Binary files /dev/null and b/apps/web/public/avatar/v3/p5/lip-shadow.webp differ diff --git a/apps/web/public/avatar/v3/p5/lip-upper.webp b/apps/web/public/avatar/v3/p5/lip-upper.webp new file mode 100644 index 0000000..ba1bc24 Binary files /dev/null and b/apps/web/public/avatar/v3/p5/lip-upper.webp differ diff --git a/apps/web/public/avatar/v3/p5/paper-grain.webp b/apps/web/public/avatar/v3/p5/paper-grain.webp new file mode 100644 index 0000000..d2e49af Binary files /dev/null and b/apps/web/public/avatar/v3/p5/paper-grain.webp differ diff --git a/apps/web/public/avatar/v3/p6/body.webp b/apps/web/public/avatar/v3/p6/body.webp new file mode 100644 index 0000000..3fef69e Binary files /dev/null and b/apps/web/public/avatar/v3/p6/body.webp differ diff --git a/apps/web/public/avatar/v3/p6/brow-left.webp b/apps/web/public/avatar/v3/p6/brow-left.webp new file mode 100644 index 0000000..14d3956 Binary files /dev/null and b/apps/web/public/avatar/v3/p6/brow-left.webp differ diff --git a/apps/web/public/avatar/v3/p6/brow-right.webp b/apps/web/public/avatar/v3/p6/brow-right.webp new file mode 100644 index 0000000..63fb879 Binary files /dev/null and b/apps/web/public/avatar/v3/p6/brow-right.webp differ diff --git a/apps/web/public/avatar/v3/p6/face-detail.webp b/apps/web/public/avatar/v3/p6/face-detail.webp new file mode 100644 index 0000000..7674265 Binary files /dev/null and b/apps/web/public/avatar/v3/p6/face-detail.webp differ diff --git a/apps/web/public/avatar/v3/p6/hair-front.webp b/apps/web/public/avatar/v3/p6/hair-front.webp new file mode 100644 index 0000000..5a0460b Binary files /dev/null and b/apps/web/public/avatar/v3/p6/hair-front.webp differ diff --git a/apps/web/public/avatar/v3/p6/head.webp b/apps/web/public/avatar/v3/p6/head.webp new file mode 100644 index 0000000..bd08906 Binary files /dev/null and b/apps/web/public/avatar/v3/p6/head.webp differ diff --git a/apps/web/public/avatar/v3/p6/jaw-detail.webp b/apps/web/public/avatar/v3/p6/jaw-detail.webp new file mode 100644 index 0000000..f080491 Binary files /dev/null and b/apps/web/public/avatar/v3/p6/jaw-detail.webp differ diff --git a/apps/web/public/avatar/v3/p6/jaw-head.webp b/apps/web/public/avatar/v3/p6/jaw-head.webp new file mode 100644 index 0000000..4d4c3d8 Binary files /dev/null and b/apps/web/public/avatar/v3/p6/jaw-head.webp differ diff --git a/apps/web/public/avatar/v3/p6/lip-lower.webp b/apps/web/public/avatar/v3/p6/lip-lower.webp new file mode 100644 index 0000000..f0250b8 Binary files /dev/null and b/apps/web/public/avatar/v3/p6/lip-lower.webp differ diff --git a/apps/web/public/avatar/v3/p6/lip-shadow.webp b/apps/web/public/avatar/v3/p6/lip-shadow.webp new file mode 100644 index 0000000..1c3dd2d Binary files /dev/null and b/apps/web/public/avatar/v3/p6/lip-shadow.webp differ diff --git a/apps/web/public/avatar/v3/p6/lip-upper.webp b/apps/web/public/avatar/v3/p6/lip-upper.webp new file mode 100644 index 0000000..243b50b Binary files /dev/null and b/apps/web/public/avatar/v3/p6/lip-upper.webp differ diff --git a/apps/web/public/avatar/v3/p6/paper-grain.webp b/apps/web/public/avatar/v3/p6/paper-grain.webp new file mode 100644 index 0000000..4191067 Binary files /dev/null and b/apps/web/public/avatar/v3/p6/paper-grain.webp differ diff --git a/apps/web/public/avatar/v3/p7/body.webp b/apps/web/public/avatar/v3/p7/body.webp new file mode 100644 index 0000000..47cf9d9 Binary files /dev/null and b/apps/web/public/avatar/v3/p7/body.webp differ diff --git a/apps/web/public/avatar/v3/p7/brow-left.webp b/apps/web/public/avatar/v3/p7/brow-left.webp new file mode 100644 index 0000000..5312a76 Binary files /dev/null and b/apps/web/public/avatar/v3/p7/brow-left.webp differ diff --git a/apps/web/public/avatar/v3/p7/brow-right.webp b/apps/web/public/avatar/v3/p7/brow-right.webp new file mode 100644 index 0000000..fec940d Binary files /dev/null and b/apps/web/public/avatar/v3/p7/brow-right.webp differ diff --git a/apps/web/public/avatar/v3/p7/face-detail.webp b/apps/web/public/avatar/v3/p7/face-detail.webp new file mode 100644 index 0000000..4f7abbc Binary files /dev/null and b/apps/web/public/avatar/v3/p7/face-detail.webp differ diff --git a/apps/web/public/avatar/v3/p7/hair-front.webp b/apps/web/public/avatar/v3/p7/hair-front.webp new file mode 100644 index 0000000..7a72966 Binary files /dev/null and b/apps/web/public/avatar/v3/p7/hair-front.webp differ diff --git a/apps/web/public/avatar/v3/p7/head.webp b/apps/web/public/avatar/v3/p7/head.webp new file mode 100644 index 0000000..3c715ca Binary files /dev/null and b/apps/web/public/avatar/v3/p7/head.webp differ diff --git a/apps/web/public/avatar/v3/p7/jaw-detail.webp b/apps/web/public/avatar/v3/p7/jaw-detail.webp new file mode 100644 index 0000000..701e8ac Binary files /dev/null and b/apps/web/public/avatar/v3/p7/jaw-detail.webp differ diff --git a/apps/web/public/avatar/v3/p7/jaw-head.webp b/apps/web/public/avatar/v3/p7/jaw-head.webp new file mode 100644 index 0000000..c90fc74 Binary files /dev/null and b/apps/web/public/avatar/v3/p7/jaw-head.webp differ diff --git a/apps/web/public/avatar/v3/p7/lip-lower.webp b/apps/web/public/avatar/v3/p7/lip-lower.webp new file mode 100644 index 0000000..67b5176 Binary files /dev/null and b/apps/web/public/avatar/v3/p7/lip-lower.webp differ diff --git a/apps/web/public/avatar/v3/p7/lip-shadow.webp b/apps/web/public/avatar/v3/p7/lip-shadow.webp new file mode 100644 index 0000000..eabf657 Binary files /dev/null and b/apps/web/public/avatar/v3/p7/lip-shadow.webp differ diff --git a/apps/web/public/avatar/v3/p7/lip-upper.webp b/apps/web/public/avatar/v3/p7/lip-upper.webp new file mode 100644 index 0000000..14428b0 Binary files /dev/null and b/apps/web/public/avatar/v3/p7/lip-upper.webp differ diff --git a/apps/web/public/avatar/v3/p7/paper-grain.webp b/apps/web/public/avatar/v3/p7/paper-grain.webp new file mode 100644 index 0000000..aeaea47 Binary files /dev/null and b/apps/web/public/avatar/v3/p7/paper-grain.webp differ diff --git a/apps/web/src/components/avatar/engine/demeanorDefaults.ts b/apps/web/src/components/avatar/engine/demeanorDefaults.ts index 658309c..56a30b5 100644 --- a/apps/web/src/components/avatar/engine/demeanorDefaults.ts +++ b/apps/web/src/components/avatar/engine/demeanorDefaults.ts @@ -88,9 +88,11 @@ const P2 = demeanor({ speech: { articulation: 0.85, syllablesPerSec: 6.4, gesture: 0.9, gazeAvertProb: 0.5 }, }); -/* P3 지우 — 28세 미혼모, 역할 부담, 따뜻하지만 지친 톤. */ +/* P3 지우 — 28세 미혼모, 역할 부담, 따뜻하지만 지친 톤. + 눈 감김(eyeOpen)은 −0.15에서 −0.05로 줄였다(2026-10-01): 리노컷 원화가 지친 눈매를 이미 + 그리고 있어 기본 자세로 더 감기면 원화보다 졸린 눈이 된다(결정문 §8.4.1 "중립 = 원화"). */ const P3 = demeanor({ - basePose: { eyeOpen: -0.15, eyeSmile: 0.08, shoulderRaise: -0.15 }, + basePose: { eyeOpen: -0.05, eyeSmile: 0.08, shoulderRaise: -0.15 }, expressivity: 0.9, blinkIntervalMs: [2200, 4600], blinkDurationMs: 140, @@ -143,9 +145,10 @@ const P5 = demeanor({ speech: { articulation: 0.65, syllablesPerSec: 5.8, gesture: 0.6, gazeAvertProb: 0.6 }, }); -/* P6 하린 — 고3, 진로갈등, 똑부러지지만 지친 톤. */ +/* P6 하린 — 고3, 진로갈등, 똑부러지지만 지친 톤. + 눈 감김 기본 자세(−0.08)는 뺐다(2026-10-01, P3과 같은 이유 — 원화의 다크서클이 지침을 맡는다). */ const P6 = demeanor({ - basePose: { eyeOpen: -0.08 }, + basePose: {}, expressivity: 0.9, blinkIntervalMs: [2000, 4200], blinkDurationMs: 120, diff --git a/apps/web/src/components/avatar/v3/rigs/index.ts b/apps/web/src/components/avatar/v3/rigs/index.ts index 998afa5..19bbbca 100644 --- a/apps/web/src/components/avatar/v3/rigs/index.ts +++ b/apps/web/src/components/avatar/v3/rigs/index.ts @@ -1,16 +1,50 @@ /* ===================================================================== 아바타 v3 리그 레지스트리 — 결정문 §8.5 "분기". 페르소나 코드 → 리노컷 - 리그. 지금은 P1만 있고 나머지는 null(기존 SVG로 남는다). 빌드 플래그 - VITE_AVATAR_V3=0 이면 항상 null(기본은 켜짐). + 리그. 세션용(linocutRigFor)은 오케스트레이터가 표정 시트를 판정한 페르소나만 + 켠다 — 2026-10-01 P1~P7 전원(결정문 §8.4.1). 목록에 없으면 null(기존 SVG). + 빌드 플래그 VITE_AVATAR_V3=0 이면 항상 null(기본은 켜짐). ===================================================================== */ import type { LinocutRig } from "../linocutRig"; import { P1_LINOCUT_RIG } from "./p1Rig"; +import { P2_LINOCUT_RIG } from "./p2Rig"; +import { P3_LINOCUT_RIG } from "./p3Rig"; +import { P4_LINOCUT_RIG } from "./p4Rig"; +import { P5_LINOCUT_RIG } from "./p5Rig"; +import { P6_LINOCUT_RIG } from "./p6Rig"; +import { P7_LINOCUT_RIG } from "./p7Rig"; -const LINOCUT_RIGS: Partial> = { P1: P1_LINOCUT_RIG }; +const LINOCUT_RIGS: Partial> = { + P1: P1_LINOCUT_RIG, + P2: P2_LINOCUT_RIG, + P3: P3_LINOCUT_RIG, + P4: P4_LINOCUT_RIG, + P5: P5_LINOCUT_RIG, + P6: P6_LINOCUT_RIG, + P7: P7_LINOCUT_RIG, +}; export function linocutRigFor(code: string | null | undefined): LinocutRig | null { if (import.meta.env.VITE_AVATAR_V3 === "0") return null; if (!code) return null; return LINOCUT_RIGS[code.toUpperCase()] ?? null; } + +/* Lab(AvatarLab.tsx)용 — 공통 파이프라인(scripts/export_rig.py)이 만드는 ./pN Rig.ts를 + 전부 모아 rig.persona로 색인한다. 세션 화면(linocutRigFor)과는 무관하다 — + persona.json이 아직 없는 pNRig.ts가 생기는 즉시 Lab 선택지에 나타나지만, + 세션에는 영향이 없다(세션은 위 LINOCUT_RIGS 목록만 본다). */ +const labRigModules = import.meta.glob("./p*Rig.ts", { eager: true }) as Record>; + +export function labLinocutRigs(): Partial> { + const out: Partial> = {}; + for (const mod of Object.values(labRigModules)) { + for (const exported of Object.values(mod)) { + const rig = exported as Partial | null; + if (rig && typeof rig === "object" && rig.schemaVersion === "vignette.avatar.v3.rig.v1" && typeof rig.persona === "string") { + out[rig.persona.toUpperCase()] = rig as LinocutRig; + } + } + } + return out; +} diff --git a/apps/web/src/components/avatar/v3/rigs/p2Rig.ts b/apps/web/src/components/avatar/v3/rigs/p2Rig.ts new file mode 100644 index 0000000..350609b --- /dev/null +++ b/apps/web/src/components/avatar/v3/rigs/p2Rig.ts @@ -0,0 +1,86 @@ +/* 생성 파일 — docs/avatar-art/linocut-pipeline/scripts/export_rig.py 가 만든다. 손으로 고치지 않는다. */ +import type { LinocutRig } from "../linocutRig"; + +export const P2_LINOCUT_RIG: LinocutRig = { + schemaVersion: "vignette.avatar.v3.rig.v1", + persona: "P2", + canvas: { w: 1005, h: 1566 }, + layers: { + body: { href: "/avatar/v3/p2/body.webp", x: 0, y: 751, w: 1005, h: 815 }, + head: { href: "/avatar/v3/p2/head.webp", x: 164, y: 84, w: 667, h: 877 }, + hairFront: { href: "/avatar/v3/p2/hair-front.webp", x: 240, y: 398, w: 498, h: 460 }, + faceDetail: { href: "/avatar/v3/p2/face-detail.webp", x: 274, y: 405, w: 449, h: 550 }, + }, + grain: { href: "/avatar/v3/p2/paper-grain.webp", size: 256 }, + lipTexture: { + upper: { href: "/avatar/v3/p2/lip-upper.webp", x: 404, y: 772, w: 182, h: 51 }, + lower: { href: "/avatar/v3/p2/lip-lower.webp", x: 404, y: 813, w: 181, h: 48 }, + shadow: { href: "/avatar/v3/p2/lip-shadow.webp", x: 414, y: 817, w: 155, h: 52 }, + }, + jaw: { + head: { href: "/avatar/v3/p2/jaw-head.webp", x: 246, y: 658, w: 506, h: 333 }, + detail: { href: "/avatar/v3/p2/jaw-detail.webp", x: 246, y: 658, w: 506, h: 333 }, + }, + pivots: { + neck: [496.4, 1021.2], + body: [502, 1566], + face: [492, 658.9], + }, + crops: { + portrait: [0, 0, 1005, 1566], + bust: [0, 40, 1005, 1005], + face: [181.6, 364.6, 630.6, 630.6], + }, + faceOval: [[492.2, 398.4], [558, 399.3], [614.2, 407.7], [665.7, 426.4], [699, 456.1], [719.9, 494.6], [731.3, 536], [736, 586.9], [734.6, 635.4], [730.5, 685.8], [721.5, 739], [704.8, 795.1], [682.2, 840.4], [657.5, 873.5], [627.1, 903.3], [601, 924.5], [572.8, 943.3], [539.3, 957.3], [496.4, 961.4], [453.8, 957.3], [421, 943.3], [393.2, 924.7], [367.4, 904.2], [338.1, 874.9], [315, 842], [293.7, 797.6], [277.1, 741.8], [267, 688.9], [261.6, 639.6], [257.9, 591.7], [260.7, 541.3], [270.6, 499.5], [290.1, 460.8], [321.9, 430.6], [371.3, 410.5], [426.6, 401]], + landmarks: { + eyeLeft: { + inner: [436.9, 589.7], + outer: [345.9, 578.6], + upperLidTop: [382.5, 563.5], + lowerLidBottom: [387, 595.5], + iris: { center: [391, 576], radius: 20 }, + lineScale: 2.5, + }, + eyeRight: { + inner: [553.4, 588.3], + outer: [643.7, 575.1], + upperLidTop: [606.6, 560.8], + lowerLidBottom: [603.5, 593], + iris: { center: [598.5, 573.5], radius: 20.5 }, + lineScale: 2.5, + }, + browLeft: { inner: [459.2, 529.9], peak: [359.4, 517.4], outer: [307.8, 526.2], halfWidth: [12.8, 16.5, 2.4], sprite: { href: "/avatar/v3/p2/brow-left.webp", x: 307, y: 500, w: 158, h: 55 } }, + browRight: { inner: [522.2, 526.9], peak: [630.8, 512.7], outer: [686.8, 520.9], halfWidth: [15.3, 12.2, 6.8], sprite: { href: "/avatar/v3/p2/brow-right.webp", x: 515, y: 492, w: 176, h: 57 } }, + noseTip: [494.7, 718.4], + mouthCornerLeft: [417.4, 818.3], + mouthCornerRight: [572.3, 816.9], + upperLipTop: [494.6, 787.6], + lowerLipBottom: [494.1, 843.9], + mouthCenter: [494.6, 812.3], + chinTip: [496.4, 950.7], + }, + palette: { + ink: "#1E1E1D", + sclera: "#D8CEBD", + iris: "#4F3B2C", + irisRing: "#1E1F1F", + lipUpper: "#9D7253", + lipLower: "#A87857", + mouthLine: "#242220", + mouthInner: "#3B201B", + teeth: "#E9E0CF", + blush: "#C0624A", + tear: "#EEE5D3", + pallor: "#9AA3A6", + paper: "#EEE5D3", + motifPetal: "#D0A362", + motifLeaf: "#53626C", + }, + backdrop: { + cognitive: "#ECE3D1", + positive: "#F1DEC2", + negative: "#DCE0E2", + defensive: "#E6DAD3", + energy: "#E2E0D0", + }, +}; diff --git a/apps/web/src/components/avatar/v3/rigs/p3Rig.ts b/apps/web/src/components/avatar/v3/rigs/p3Rig.ts new file mode 100644 index 0000000..b9dffe5 --- /dev/null +++ b/apps/web/src/components/avatar/v3/rigs/p3Rig.ts @@ -0,0 +1,86 @@ +/* 생성 파일 — docs/avatar-art/linocut-pipeline/scripts/export_rig.py 가 만든다. 손으로 고치지 않는다. */ +import type { LinocutRig } from "../linocutRig"; + +export const P3_LINOCUT_RIG: LinocutRig = { + schemaVersion: "vignette.avatar.v3.rig.v1", + persona: "P3", + canvas: { w: 1005, h: 1566 }, + layers: { + body: { href: "/avatar/v3/p3/body.webp", x: 0, y: 848, w: 1005, h: 718 }, + head: { href: "/avatar/v3/p3/head.webp", x: 132, y: 156, w: 742, h: 888 }, + hairFront: { href: "/avatar/v3/p3/hair-front.webp", x: 237, y: 398, w: 540, h: 535 }, + faceDetail: { href: "/avatar/v3/p3/face-detail.webp", x: 279, y: 397, w: 443, h: 542 }, + }, + grain: { href: "/avatar/v3/p3/paper-grain.webp", size: 256 }, + lipTexture: { + upper: { href: "/avatar/v3/p3/lip-upper.webp", x: 424, y: 756, w: 173, h: 51 }, + lower: { href: "/avatar/v3/p3/lip-lower.webp", x: 423, y: 792, w: 171, h: 54 }, + shadow: { href: "/avatar/v3/p3/lip-shadow.webp", x: 433, y: 791, w: 148, h: 63 }, + }, + jaw: { + head: { href: "/avatar/v3/p3/jaw-head.webp", x: 243, y: 644, w: 512, h: 332 }, + detail: { href: "/avatar/v3/p3/jaw-detail.webp", x: 243, y: 644, w: 512, h: 332 }, + }, + pivots: { + neck: [518, 1005], + body: [502, 1566], + face: [492, 652], + }, + crops: { + portrait: [0, 0, 1005, 1566], + bust: [0, 40, 1005, 1005], + face: [185.9, 356.9, 621.9, 621.9], + }, + faceOval: [[475.8, 393.7], [540.7, 390.2], [596.5, 395.8], [649.6, 413.2], [685.4, 442.2], [709.3, 480.3], [724.7, 521.2], [733.9, 571.8], [736.4, 619.7], [736.4, 669.4], [731, 722.5], [718.2, 777.9], [698.5, 822.4], [674.5, 854.4], [643.8, 883.5], [618.4, 904.1], [591.4, 922.9], [559.9, 938.4], [519, 945.4], [477.9, 944.3], [445.2, 933.5], [416.7, 919.2], [389.2, 903.2], [355.4, 879.7], [328.1, 851.8], [302.7, 811.3], [282.3, 758], [269.2, 706.1], [262.4, 657.2], [257.2, 610.1], [258.2, 560], [266.7, 517.2], [283.8, 476], [312.7, 441.9], [359, 416], [411.7, 401.4]], + landmarks: { + eyeLeft: { + inner: [435.1, 593.8], + outer: [346.3, 589.4], + upperLidTop: [382.5, 570.1], + lowerLidBottom: [386.7, 602.2], + iris: { center: [389, 580], radius: 20 }, + lineScale: 1, + }, + eyeRight: { + inner: [552.1, 583.6], + outer: [640.8, 564.7], + upperLidTop: [600.8, 552.1], + lowerLidBottom: [601, 583.9], + iris: { center: [593.5, 558.5], radius: 19.5 }, + lineScale: 1, + }, + browLeft: { inner: [438, 513.2], peak: [354.9, 519.8], outer: [312, 530.8], halfWidth: [7, 8.3, 3.8], sprite: { href: "/avatar/v3/p3/brow-left.webp", x: 314, y: 502, w: 129, h: 38 } }, + browRight: { inner: [521.3, 505.4], peak: [609.3, 496.5], outer: [654.7, 501], halfWidth: [3.9, 7, 2], sprite: { href: "/avatar/v3/p3/brow-right.webp", x: 517, y: 486, w: 142, h: 32 } }, + noseTip: [499.6, 704.4], + mouthCornerLeft: [432.6, 803.4], + mouthCornerRight: [583.6, 792.2], + upperLipTop: [505.2, 769.8], + lowerLipBottom: [509.4, 832.4], + mouthCenter: [507.2, 796.4], + chinTip: [518.3, 935.2], + }, + palette: { + ink: "#242322", + sclera: "#D8CEBD", + iris: "#4F3B2C", + irisRing: "#1E1F1F", + lipUpper: "#B4835D", + lipLower: "#BD8A62", + mouthLine: "#76553F", + mouthInner: "#3B201B", + teeth: "#E9E0CF", + blush: "#C0624A", + tear: "#EEE5D3", + pallor: "#9AA3A6", + paper: "#EEE5D3", + motifPetal: "#D0A362", + motifLeaf: "#53626C", + }, + backdrop: { + cognitive: "#ECE3D1", + positive: "#F1DEC2", + negative: "#DCE0E2", + defensive: "#E6DAD3", + energy: "#E2E0D0", + }, +}; diff --git a/apps/web/src/components/avatar/v3/rigs/p4Rig.ts b/apps/web/src/components/avatar/v3/rigs/p4Rig.ts new file mode 100644 index 0000000..27fd550 --- /dev/null +++ b/apps/web/src/components/avatar/v3/rigs/p4Rig.ts @@ -0,0 +1,86 @@ +/* 생성 파일 — docs/avatar-art/linocut-pipeline/scripts/export_rig.py 가 만든다. 손으로 고치지 않는다. */ +import type { LinocutRig } from "../linocutRig"; + +export const P4_LINOCUT_RIG: LinocutRig = { + schemaVersion: "vignette.avatar.v3.rig.v1", + persona: "P4", + canvas: { w: 1005, h: 1566 }, + layers: { + body: { href: "/avatar/v3/p4/body.webp", x: 0, y: 436, w: 1005, h: 1130 }, + head: { href: "/avatar/v3/p4/head.webp", x: 161, y: 97, w: 661, h: 924 }, + hairFront: { href: "/avatar/v3/p4/hair-front.webp", x: 234, y: 405, w: 534, h: 485 }, + faceDetail: { href: "/avatar/v3/p4/face-detail.webp", x: 266, y: 394, w: 470, h: 551 }, + }, + grain: { href: "/avatar/v3/p4/paper-grain.webp", size: 256 }, + lipTexture: { + upper: { href: "/avatar/v3/p4/lip-upper.webp", x: 410, y: 777, w: 179, h: 46 }, + lower: { href: "/avatar/v3/p4/lip-lower.webp", x: 410, y: 816, w: 178, h: 51 }, + shadow: { href: "/avatar/v3/p4/lip-shadow.webp", x: 420, y: 814, w: 159, h: 61 }, + }, + jaw: { + head: { href: "/avatar/v3/p4/jaw-head.webp", x: 250, y: 668, w: 504, h: 313 }, + detail: { href: "/avatar/v3/p4/jaw-detail.webp", x: 250, y: 668, w: 504, h: 313 }, + }, + pivots: { + neck: [502.7, 1011.1], + body: [502, 1566], + face: [496, 655], + }, + crops: { + portrait: [0, 0, 1005, 1566], + bust: [0, 40, 1005, 1005], + face: [184.9, 354.2, 631.2, 631.2], + }, + faceOval: [[495.7, 388], [569.6, 388.6], [631.4, 396.4], [687.2, 414.1], [721.3, 442.7], [739.9, 479.9], [748.2, 519.6], [748.9, 568.1], [743.7, 615], [735.8, 663.9], [723.6, 715.1], [704.8, 769.9], [681.9, 816.1], [657.7, 851.5], [628.5, 883.7], [603.9, 907.3], [576.9, 929.1], [544.6, 946.1], [502.7, 951.6], [461.8, 946.3], [430.4, 929.7], [403.7, 908.3], [378.7, 885.5], [348.8, 854], [324, 819.1], [300.1, 773.9], [280.7, 719], [267.6, 667.8], [259.3, 619.2], [252.7, 572.5], [252.2, 524.3], [258.8, 484.1], [275.1, 446.8], [306.7, 417.8], [360.2, 398.8], [421.5, 390.1]], + landmarks: { + eyeLeft: { + inner: [430.6, 594.2], + outer: [337.6, 576.7], + upperLidTop: [375.9, 563.9], + lowerLidBottom: [380.9, 598.5], + iris: { center: [385, 576], radius: 20 }, + lineScale: 2.5, + }, + eyeRight: { + inner: [566.4, 593.4], + outer: [659.2, 572.9], + upperLidTop: [621.4, 561.7], + lowerLidBottom: [616.8, 596.6], + iris: { center: [611.5, 574.5], radius: 18.5 }, + lineScale: 2.5, + }, + browLeft: { inner: [449.4, 524.6], peak: [353.2, 508.4], outer: [303.6, 507.6], halfWidth: [6.8, 6.5, 2.5], sprite: { href: "/avatar/v3/p4/brow-left.webp", x: 299, y: 499, w: 156, h: 36 } }, + browRight: { inner: [540.9, 523.7], peak: [642.6, 502.3], outer: [695.1, 500.2], halfWidth: [2.4, 6.7, 1.5], sprite: { href: "/avatar/v3/p4/brow-right.webp", x: 536, y: 491, w: 164, h: 42 } }, + noseTip: [498.6, 728.2], + mouthCornerLeft: [426.2, 819.4], + mouthCornerRight: [571.5, 818.6], + upperLipTop: [497.9, 791.6], + lowerLipBottom: [498.7, 852.3], + mouthCenter: [498.4, 815.7], + chinTip: [502.7, 940.6], + }, + palette: { + ink: "#22211F", + sclera: "#D8CEBD", + iris: "#4F3B2C", + irisRing: "#1E1F1F", + lipUpper: "#B48460", + lipLower: "#C08E69", + mouthLine: "#332B26", + mouthInner: "#3B201B", + teeth: "#E9E0CF", + blush: "#C0624A", + tear: "#EEE5D3", + pallor: "#9AA3A6", + paper: "#EEE5D3", + motifPetal: "#D0A362", + motifLeaf: "#53626C", + }, + backdrop: { + cognitive: "#ECE3D1", + positive: "#F1DEC2", + negative: "#DCE0E2", + defensive: "#E6DAD3", + energy: "#E2E0D0", + }, +}; diff --git a/apps/web/src/components/avatar/v3/rigs/p5Rig.ts b/apps/web/src/components/avatar/v3/rigs/p5Rig.ts new file mode 100644 index 0000000..b5f169e --- /dev/null +++ b/apps/web/src/components/avatar/v3/rigs/p5Rig.ts @@ -0,0 +1,86 @@ +/* 생성 파일 — docs/avatar-art/linocut-pipeline/scripts/export_rig.py 가 만든다. 손으로 고치지 않는다. */ +import type { LinocutRig } from "../linocutRig"; + +export const P5_LINOCUT_RIG: LinocutRig = { + schemaVersion: "vignette.avatar.v3.rig.v1", + persona: "P5", + canvas: { w: 1005, h: 1566 }, + layers: { + body: { href: "/avatar/v3/p5/body.webp", x: 0, y: 696, w: 1005, h: 870 }, + head: { href: "/avatar/v3/p5/head.webp", x: 144, y: 118, w: 688, h: 846 }, + hairFront: { href: "/avatar/v3/p5/hair-front.webp", x: 231, y: 401, w: 513, h: 436 }, + faceDetail: { href: "/avatar/v3/p5/face-detail.webp", x: 262, y: 410, w: 455, h: 523 }, + }, + grain: { href: "/avatar/v3/p5/paper-grain.webp", size: 256 }, + lipTexture: { + upper: { href: "/avatar/v3/p5/lip-upper.webp", x: 423, y: 749, w: 124, h: 54 }, + lower: { href: "/avatar/v3/p5/lip-lower.webp", x: 423, y: 791, w: 136, h: 46 }, + shadow: { href: "/avatar/v3/p5/lip-shadow.webp", x: 433, y: 797, w: 116, h: 48 }, + }, + jaw: { + head: { href: "/avatar/v3/p5/jaw-head.webp", x: 236, y: 633, w: 512, h: 337 }, + detail: { href: "/avatar/v3/p5/jaw-detail.webp", x: 236, y: 633, w: 512, h: 337 }, + }, + pivots: { + neck: [488, 1001], + body: [502, 1566], + face: [490, 659], + }, + crops: { + portrait: [0, 0, 1005, 1566], + bust: [0, 40, 1005, 1005], + face: [191.6, 370.8, 601.3, 601.3], + }, + faceOval: [[496.1, 403], [564, 405], [621.1, 414.5], [672.8, 434.4], [705.1, 464.2], [723.6, 501.7], [732.1, 541], [732.9, 589.2], [728.9, 634.4], [723.7, 681], [714.5, 730.1], [698.1, 782.2], [675.7, 823.6], [650.1, 853], [619, 879.9], [592.9, 900], [565.2, 919.2], [531.9, 934.8], [488.2, 939.9], [444.8, 934.7], [411.7, 918.9], [384.1, 899.3], [358.4, 879], [328.1, 851.8], [303.5, 822.2], [281.3, 781.3], [265.8, 729], [257.4, 680], [253.9, 634], [251.6, 589.2], [255.3, 541.7], [265.7, 502], [286.1, 464.7], [319.6, 435], [371.3, 414.7], [428.2, 405.3]], + landmarks: { + eyeLeft: { + inner: [431.6, 589], + outer: [343.8, 578.5], + upperLidTop: [381.9, 566.8], + lowerLidBottom: [383, 594], + iris: { center: [387.5, 574.5], radius: 18.5 }, + lineScale: 2.5, + }, + eyeRight: { + inner: [553.9, 588.2], + outer: [641.8, 576.3], + upperLidTop: [605.4, 564.5], + lowerLidBottom: [602.9, 593], + iris: { center: [594, 573], radius: 18 }, + lineScale: 2.5, + }, + browLeft: { inner: [454.2, 526.5], peak: [355, 512.3], outer: [303.8, 521.4], halfWidth: [7.1, 13, 3.4], sprite: { href: "/avatar/v3/p5/brow-left.webp", x: 299, y: 495, w: 161, h: 48 } }, + browRight: { inner: [524.9, 526.2], peak: [625.3, 510.7], outer: [677.1, 518.6], halfWidth: [2.1, 13, 1.9], sprite: { href: "/avatar/v3/p5/brow-right.webp", x: 520, y: 495, w: 162, h: 44 } }, + noseTip: [493.1, 693.9], + mouthCornerLeft: [418.9, 801.4], + mouthCornerRight: [557.3, 801.8], + upperLipTop: [490.9, 759.4], + lowerLipBottom: [489.5, 828.3], + mouthCenter: [490.7, 791], + chinTip: [488.3, 929.7], + }, + palette: { + ink: "#222221", + sclera: "#D8CEBD", + iris: "#4F3B2C", + irisRing: "#1E1F1F", + lipUpper: "#B1845F", + lipLower: "#CC926C", + mouthLine: "#A5694F", + mouthInner: "#3B201B", + teeth: "#E9E0CF", + blush: "#C0624A", + tear: "#EEE5D3", + pallor: "#9AA3A6", + paper: "#EEE5D3", + motifPetal: "#D0A362", + motifLeaf: "#53626C", + }, + backdrop: { + cognitive: "#ECE3D1", + positive: "#F1DEC2", + negative: "#DCE0E2", + defensive: "#E6DAD3", + energy: "#E2E0D0", + }, +}; diff --git a/apps/web/src/components/avatar/v3/rigs/p6Rig.ts b/apps/web/src/components/avatar/v3/rigs/p6Rig.ts new file mode 100644 index 0000000..d347217 --- /dev/null +++ b/apps/web/src/components/avatar/v3/rigs/p6Rig.ts @@ -0,0 +1,86 @@ +/* 생성 파일 — docs/avatar-art/linocut-pipeline/scripts/export_rig.py 가 만든다. 손으로 고치지 않는다. */ +import type { LinocutRig } from "../linocutRig"; + +export const P6_LINOCUT_RIG: LinocutRig = { + schemaVersion: "vignette.avatar.v3.rig.v1", + persona: "P6", + canvas: { w: 1005, h: 1566 }, + layers: { + body: { href: "/avatar/v3/p6/body.webp", x: 0, y: 844, w: 1005, h: 722 }, + head: { href: "/avatar/v3/p6/head.webp", x: 37, y: 83, w: 887, h: 1063 }, + hairFront: { href: "/avatar/v3/p6/hair-front.webp", x: 257, y: 399, w: 463, h: 529 }, + faceDetail: { href: "/avatar/v3/p6/face-detail.webp", x: 272, y: 404, w: 439, h: 529 }, + }, + grain: { href: "/avatar/v3/p6/paper-grain.webp", size: 256 }, + lipTexture: { + upper: { href: "/avatar/v3/p6/lip-upper.webp", x: 420, y: 765, w: 158, h: 49 }, + lower: { href: "/avatar/v3/p6/lip-lower.webp", x: 419, y: 804, w: 160, h: 48 }, + shadow: { href: "/avatar/v3/p6/lip-shadow.webp", x: 429, y: 807, w: 140, h: 53 }, + }, + jaw: { + head: { href: "/avatar/v3/p6/jaw-head.webp", x: 251, y: 656, w: 482, h: 315 }, + detail: { href: "/avatar/v3/p6/jaw-detail.webp", x: 251, y: 656, w: 482, h: 315 }, + }, + pivots: { + neck: [506, 1001], + body: [502, 1566], + face: [488, 661], + }, + crops: { + portrait: [0, 0, 1005, 1566], + bust: [0, 40, 1005, 1005], + face: [184.6, 365, 608.6, 608.6], + }, + faceOval: [[480.8, 398.4], [546.8, 397.6], [602, 404.4], [651.9, 421], [683.6, 447.7], [702.8, 483.5], [713.5, 522.5], [717.9, 570.3], [717, 615.8], [714.2, 663.3], [706.6, 713.5], [692.8, 766.8], [673.8, 811.4], [651.7, 845], [623.5, 875.2], [600.1, 897], [575.1, 917.5], [545.4, 934.4], [506.6, 941], [467.6, 937.9], [437.3, 924], [410.8, 905.8], [385.5, 886.6], [354, 859], [328.2, 826.9], [304.3, 783.8], [285.2, 730.7], [272.8, 680.6], [265.7, 633.6], [260, 588.5], [260, 540.9], [267.4, 500.8], [283.6, 463.8], [312.3, 434.4], [359.6, 413.5], [414.2, 402.7]], + landmarks: { + eyeLeft: { + inner: [432.4, 593.7], + outer: [341.4, 583.9], + upperLidTop: [378.1, 566], + lowerLidBottom: [383.4, 600.1], + iris: { center: [386.5, 577.5], radius: 20.5 }, + lineScale: 1, + }, + eyeRight: { + inner: [548.9, 589.6], + outer: [639.8, 570.8], + upperLidTop: [601.4, 555.9], + lowerLidBottom: [598.4, 591.8], + iris: { center: [595, 568], radius: 20 }, + lineScale: 1, + }, + browLeft: { inner: [451.9, 530.3], peak: [367.6, 517.4], outer: [324.1, 521.5], halfWidth: [15.7, 11, 7.9], sprite: { href: "/avatar/v3/p6/brow-left.webp", x: 323, y: 504, w: 134, h: 49 } }, + browRight: { inner: [518.3, 525.4], peak: [607, 510.3], outer: [652.7, 515.6], halfWidth: [5.7, 25.5, 4.9], sprite: { href: "/avatar/v3/p6/brow-right.webp", x: 514, y: 492, w: 137, h: 57 } }, + noseTip: [495.6, 716.5], + mouthCornerLeft: [423.8, 811], + mouthCornerRight: [575.1, 805.1], + upperLipTop: [498.5, 778], + lowerLipBottom: [501.5, 841.2], + mouthCenter: [499.8, 803.5], + chinTip: [506.1, 930.6], + }, + palette: { + ink: "#242322", + sclera: "#D8CEBD", + iris: "#4F3B2C", + irisRing: "#1E1F1F", + lipUpper: "#A27659", + lipLower: "#A47459", + mouthLine: "#2C2625", + mouthInner: "#3B201B", + teeth: "#E9E0CF", + blush: "#C0624A", + tear: "#EEE5D3", + pallor: "#9AA3A6", + paper: "#EEE5D3", + motifPetal: "#D0A362", + motifLeaf: "#53626C", + }, + backdrop: { + cognitive: "#ECE3D1", + positive: "#F1DEC2", + negative: "#DCE0E2", + defensive: "#E6DAD3", + energy: "#E2E0D0", + }, +}; diff --git a/apps/web/src/components/avatar/v3/rigs/p7Rig.ts b/apps/web/src/components/avatar/v3/rigs/p7Rig.ts new file mode 100644 index 0000000..21d5a0b --- /dev/null +++ b/apps/web/src/components/avatar/v3/rigs/p7Rig.ts @@ -0,0 +1,86 @@ +/* 생성 파일 — docs/avatar-art/linocut-pipeline/scripts/export_rig.py 가 만든다. 손으로 고치지 않는다. */ +import type { LinocutRig } from "../linocutRig"; + +export const P7_LINOCUT_RIG: LinocutRig = { + schemaVersion: "vignette.avatar.v3.rig.v1", + persona: "P7", + canvas: { w: 1005, h: 1566 }, + layers: { + body: { href: "/avatar/v3/p7/body.webp", x: 0, y: 725, w: 1005, h: 841 }, + head: { href: "/avatar/v3/p7/head.webp", x: 174, y: 151, w: 648, h: 892 }, + hairFront: { href: "/avatar/v3/p7/hair-front.webp", x: 220, y: 413, w: 535, h: 423 }, + faceDetail: { href: "/avatar/v3/p7/face-detail.webp", x: 276, y: 423, w: 425, h: 513 }, + }, + grain: { href: "/avatar/v3/p7/paper-grain.webp", size: 256 }, + lipTexture: { + upper: { href: "/avatar/v3/p7/lip-upper.webp", x: 406, y: 763, w: 170, h: 50 }, + lower: { href: "/avatar/v3/p7/lip-lower.webp", x: 408, y: 801, w: 164, h: 49 }, + shadow: { href: "/avatar/v3/p7/lip-shadow.webp", x: 428, y: 807, w: 126, h: 51 }, + }, + jaw: { + head: { href: "/avatar/v3/p7/jaw-head.webp", x: 251, y: 652, w: 478, h: 321 }, + detail: { href: "/avatar/v3/p7/jaw-detail.webp", x: 251, y: 652, w: 478, h: 321 }, + }, + pivots: { + neck: [492, 1002], + body: [502, 1566], + face: [489, 660], + }, + crops: { + portrait: [0, 0, 1005, 1566], + bust: [0, 40, 1005, 1005], + face: [193.3, 384.2, 590, 590], + }, + faceOval: [[490.5, 415.8], [555.3, 417.3], [609.5, 425.4], [658.6, 442.5], [688.8, 469], [706, 502.9], [714.3, 539.4], [716.2, 584.5], [712.6, 628.1], [706.8, 673.7], [696.8, 722.2], [681.3, 774.6], [662, 818.1], [641.5, 850.8], [615.8, 880.4], [592.8, 902], [566.9, 921.9], [534.8, 937.4], [491.9, 942.6], [449, 938.5], [416.4, 923.9], [389.5, 904.8], [365.4, 883.9], [338.9, 854.2], [317.7, 821], [298, 777], [282.2, 723.6], [271.5, 674.4], [265.1, 628.9], [260.4, 585.3], [262.1, 540.3], [270.9, 503.5], [289.1, 469.4], [320.3, 442.7], [369.9, 425.3], [425, 417.4]], + landmarks: { + eyeLeft: { + inner: [433.4, 588.7], + outer: [345.6, 578.8], + upperLidTop: [381.3, 566.3], + lowerLidBottom: [387.8, 592.8], + iris: { center: [387.5, 574.5], radius: 16.5 }, + lineScale: 2.5, + }, + eyeRight: { + inner: [550.7, 589.9], + outer: [637.7, 578.5], + upperLidTop: [601.5, 566.1], + lowerLidBottom: [596.3, 593.2], + iris: { center: [593.5, 572.5], radius: 16.5 }, + lineScale: 2.5, + }, + browLeft: { inner: [455.8, 527], peak: [369, 521.2], outer: [324.2, 527.5], halfWidth: [5.4, 8, 3.4], sprite: { href: "/avatar/v3/p7/brow-left.webp", x: 324, y: 509, w: 137, h: 29 } }, + browRight: { inner: [526.5, 526.8], peak: [619.5, 519.8], outer: [667.5, 527], halfWidth: [6.3, 8, 2.9], sprite: { href: "/avatar/v3/p7/brow-right.webp", x: 521, y: 509, w: 150, h: 28 } }, + noseTip: [493.5, 712.5], + mouthCornerLeft: [422.6, 806.5], + mouthCornerRight: [558.9, 808.4], + upperLipTop: [493.8, 774], + lowerLipBottom: [492.3, 835], + mouthCenter: [493.2, 800.3], + chinTip: [491.8, 932.4], + }, + palette: { + ink: "#202122", + sclera: "#D8CEBD", + iris: "#4F3B2C", + irisRing: "#1E1F1F", + lipUpper: "#BA9069", + lipLower: "#C4936D", + mouthLine: "#322F2B", + mouthInner: "#3B201B", + teeth: "#E9E0CF", + blush: "#C0624A", + tear: "#EEE5D3", + pallor: "#9AA3A6", + paper: "#EEE5D3", + motifPetal: "#D0A362", + motifLeaf: "#53626C", + }, + backdrop: { + cognitive: "#ECE3D1", + positive: "#F1DEC2", + negative: "#DCE0E2", + defensive: "#E6DAD3", + energy: "#E2E0D0", + }, +}; diff --git a/apps/web/src/pages/AvatarLab.tsx b/apps/web/src/pages/AvatarLab.tsx index 1cac93c..e056302 100644 --- a/apps/web/src/pages/AvatarLab.tsx +++ b/apps/web/src/pages/AvatarLab.tsx @@ -8,7 +8,7 @@ import { useEffect, useMemo, useRef, useState, type ChangeEvent } from "react"; import DebugFace from "../components/avatar/v3/DebugFace"; import LinocutAvatar from "../components/avatar/v3/LinocutAvatar"; import LinocutMotif from "../components/avatar/v3/LinocutMotif"; -import { P1_LINOCUT_RIG } from "../components/avatar/v3/rigs/p1Rig"; +import { labLinocutRigs } from "../components/avatar/v3/rigs"; import type { LinocutRig } from "../components/avatar/v3/linocutRig"; import { CHANNEL_IDS } from "../components/avatar/engine/channels"; import { createAvatarEngine, type AvatarEngine, type DebugSnapshot } from "../components/avatar/engine/engine"; @@ -30,8 +30,10 @@ const PERSONA_OPTIONS: Array<{ code: string; label: string }> = [ { code: "P7", label: "P7 도현" }, ]; -/** 리노컷 리그가 있는 페르소나만. 없는 페르소나는 debug 렌더러를 강제한다. */ -const LINOCUT_RIGS: Partial> = { P1: P1_LINOCUT_RIG }; +/** 리노컷 리그가 있는 페르소나만. 없는 페르소나는 debug 렌더러를 강제한다. + 공통 파이프라인이 만든 pNRig.ts를 전부 모은 값이라, 새 페르소나가 빌드되는 + 즉시(재빌드 없이) 이 Lab에서 보인다 — v3/rigs/index.ts labLinocutRigs() 참고. */ +const LINOCUT_RIGS: Partial> = labLinocutRigs(); type RendererMode = "linocut" | "debug"; type FeedbackMode = "immersive" | "ambient" | "coached"; @@ -80,11 +82,19 @@ function seedFromQuery(): number { return Number.isFinite(parsed) ? parsed : 1; } +/** ?persona=P3 같은 쿼리로 처음 고를 페르소나를 정한다(캡처 도구용). 모르는 코드거나 + 없으면 기본 P1. */ +function personaFromQuery(): string { + const raw = new URLSearchParams(window.location.search).get("persona"); + const upper = raw?.toUpperCase() ?? ""; + return PERSONA_OPTIONS.some((p) => p.code === upper) ? upper : "P1"; +} + export default function AvatarLab() { const seed = useMemo(seedFromQuery, []); const clock = useRef(createClock()).current; - const [personaCode, setPersonaCode] = useState("P1"); + const [personaCode, setPersonaCode] = useState(personaFromQuery); const [avatarState, setAvatarState] = useState("idle"); const [openness, setOpenness] = useState(0.4); const [reducedMotion, setReducedMotion] = useState(false); diff --git a/docs/avatar-art/p2-linocut/base/base-faceless.png b/docs/avatar-art/p2-linocut/base/base-faceless.png new file mode 100644 index 0000000..a42bbbf Binary files /dev/null and b/docs/avatar-art/p2-linocut/base/base-faceless.png differ diff --git a/docs/avatar-art/p2-linocut/base/base-front.png b/docs/avatar-art/p2-linocut/base/base-front.png new file mode 100644 index 0000000..92a88e5 Binary files /dev/null and b/docs/avatar-art/p2-linocut/base/base-front.png differ diff --git a/docs/avatar-art/p2-linocut/base/edits/aligned-body-1.json b/docs/avatar-art/p2-linocut/base/edits/aligned-body-1.json new file mode 100644 index 0000000..0ad90ba --- /dev/null +++ b/docs/avatar-art/p2-linocut/base/edits/aligned-body-1.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\body-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\aligned-body-1.png", + "refSize": [ + 1004, + 1566 + ], + "editedOriginalSize": [ + 1004, + 1567 + ], + "eccCorrelation": 0.86251, + "transform": { + "scaleSqrtDet": 1.00197, + "rotationDeg": -0.001, + "translateX": -1.76, + "translateY": -2.211, + "matrix": [ + [ + 1.002585, + -0.000235, + -1.760458 + ], + [ + -9e-06, + 1.001356, + -2.210697 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 584670, + "chamferInMask": { + "median": 0.0, + "p90": 3.0, + "nSamples": 110891 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p2-linocut/base/edits/aligned-body-2.json b/docs/avatar-art/p2-linocut/base/edits/aligned-body-2.json new file mode 100644 index 0000000..b9ea9f7 --- /dev/null +++ b/docs/avatar-art/p2-linocut/base/edits/aligned-body-2.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\body-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\aligned-body-2.png", + "refSize": [ + 1004, + 1566 + ], + "editedOriginalSize": [ + 1004, + 1567 + ], + "eccCorrelation": 0.86381, + "transform": { + "scaleSqrtDet": 1.00257, + "rotationDeg": -0.001, + "translateX": -0.653, + "translateY": -5.297, + "matrix": [ + [ + 1.001779, + -0.000341, + -0.652621 + ], + [ + -2.6e-05, + 1.00337, + -5.296521 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 584730, + "chamferInMask": { + "median": 1.0, + "p90": 2.828, + "nSamples": 108723 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p2-linocut/base/edits/aligned-faceless-1.json b/docs/avatar-art/p2-linocut/base/edits/aligned-faceless-1.json new file mode 100644 index 0000000..763589c --- /dev/null +++ b/docs/avatar-art/p2-linocut/base/edits/aligned-faceless-1.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\faceless-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\aligned-faceless-1.png", + "refSize": [ + 1004, + 1566 + ], + "editedOriginalSize": [ + 1004, + 1567 + ], + "eccCorrelation": 0.99442, + "transform": { + "scaleSqrtDet": 1.00043, + "rotationDeg": 0.004, + "translateX": -0.943, + "translateY": -0.245, + "matrix": [ + [ + 1.001139, + -8.8e-05, + -0.942587 + ], + [ + 6.6e-05, + 0.999724, + -0.24468 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 881537, + "chamferInMask": { + "median": 0.0, + "p90": 1.414, + "nSamples": 147663 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 6008 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 318, + 527, + 461, + 611 + ], + "refInkRatio": 0.2271, + "editedInkRatio": 0.0011 + }, + "eyeB": { + "box": [ + 526, + 526, + 669, + 610 + ], + "refInkRatio": 0.2123, + "editedInkRatio": 0.0 + }, + "browA": { + "box": [ + 276, + 463, + 475, + 554 + ], + "refInkRatio": 0.367, + "editedInkRatio": 0.1944 + }, + "browB": { + "box": [ + 510, + 460, + 712, + 550 + ], + "refInkRatio": 0.2291, + "editedInkRatio": 0.0745 + }, + "mouth": { + "box": [ + 393, + 750, + 599, + 862 + ], + "refInkRatio": 0.1096, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 318, + 527, + 461, + 611 + ], + "eyeB": [ + 526, + 526, + 669, + 610 + ], + "browA": [ + 276, + 463, + 475, + 554 + ], + "browB": [ + 510, + 460, + 712, + 550 + ], + "mouth": [ + 393, + 750, + 599, + 862 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p2-linocut/base/edits/aligned-faceless-2.json b/docs/avatar-art/p2-linocut/base/edits/aligned-faceless-2.json new file mode 100644 index 0000000..0f91297 --- /dev/null +++ b/docs/avatar-art/p2-linocut/base/edits/aligned-faceless-2.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\faceless-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\aligned-faceless-2.png", + "refSize": [ + 1004, + 1566 + ], + "editedOriginalSize": [ + 1004, + 1566 + ], + "eccCorrelation": 0.99464, + "transform": { + "scaleSqrtDet": 1.00043, + "rotationDeg": 0.002, + "translateX": -0.804, + "translateY": -0.406, + "matrix": [ + [ + 1.000778, + -2.9e-05, + -0.803723 + ], + [ + 3.8e-05, + 1.000088, + -0.405893 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 881537, + "chamferInMask": { + "median": 0.0, + "p90": 1.414, + "nSamples": 146528 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 5917 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 318, + 527, + 461, + 611 + ], + "refInkRatio": 0.2271, + "editedInkRatio": 0.0001 + }, + "eyeB": { + "box": [ + 526, + 526, + 669, + 610 + ], + "refInkRatio": 0.2123, + "editedInkRatio": 0.0 + }, + "browA": { + "box": [ + 276, + 463, + 475, + 554 + ], + "refInkRatio": 0.367, + "editedInkRatio": 0.1755 + }, + "browB": { + "box": [ + 510, + 460, + 712, + 550 + ], + "refInkRatio": 0.2291, + "editedInkRatio": 0.0665 + }, + "mouth": { + "box": [ + 393, + 750, + 599, + 862 + ], + "refInkRatio": 0.1096, + "editedInkRatio": 0.0001 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 318, + 527, + 461, + 611 + ], + "eyeB": [ + 526, + 526, + 669, + 610 + ], + "browA": [ + 276, + 463, + 475, + 554 + ], + "browB": [ + 510, + 460, + 712, + 550 + ], + "mouth": [ + 393, + 750, + 599, + 862 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p2-linocut/base/edits/sheet.jpg b/docs/avatar-art/p2-linocut/base/edits/sheet.jpg new file mode 100644 index 0000000..761bf74 Binary files /dev/null and b/docs/avatar-art/p2-linocut/base/edits/sheet.jpg differ diff --git a/docs/avatar-art/p2-linocut/base/normalize.json b/docs/avatar-art/p2-linocut/base/normalize.json new file mode 100644 index 0000000..78d35a2 --- /dev/null +++ b/docs/avatar-art/p2-linocut/base/normalize.json @@ -0,0 +1,66 @@ +{ + "canvas": { + "w": 1005, + "h": 1566 + }, + "reference": { + "image": "docs\\avatar-art\\p1-linocut\\base\\base-front.png", + "eyesCenter": [ + 492.69, + 584.33 + ], + "chin": [ + 500.61, + 919.55 + ], + "eyeDistance": 215.427, + "eyeChinDistance": 335.308 + }, + "input": { + "front": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\source-front.png", + "faceless": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\aligned-faceless-2.png", + "body": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\base\\edits\\aligned-body-2.png", + "frontSize": [ + 1004, + 1566 + ], + "eyesCenter": [ + 493.46, + 572.88 + ], + "chin": [ + 498.98, + 945.65 + ], + "eyeDistance": 208.065, + "eyeChinDistance": 372.813 + }, + "transform": { + "sHead": 0.967393, + "sWidth": 1.000996, + "s": 1.000996, + "rotationDeg": 0.0, + "offsetXNatural": -1.268, + "offsetXClampRange": [ + 0.0, + 0.0 + ], + "offsetX": 0.0, + "offsetY": 10.881 + }, + "coveredRange": { + "x": [ + 0.0, + 1005 + ], + "y": [ + 10.9, + 1566 + ] + }, + "inputSha256": { + "front": "5b6026cfcea5ad7337fa4431d485d3cbce647cf00e4016221f695158756f9fa1", + "faceless": "bf844904bbfae18ac3086bb6176a07fcd421671322b4980a077166c003a62b0a", + "body": "91b515db47aeae74c27d0a75753af6ee60df0b00dfbc7fde826aa24e4d0c2a3b" + } +} \ No newline at end of file diff --git a/docs/avatar-art/p2-linocut/manifest.json b/docs/avatar-art/p2-linocut/manifest.json new file mode 100644 index 0000000..e6dec53 --- /dev/null +++ b/docs/avatar-art/p2-linocut/manifest.json @@ -0,0 +1,1698 @@ +{ + "landmarks": { + "coordSystem": "screen (image pixel: x=0 좌측, y=0 상단; left=작은 x, right=큰 x; 인물 해부학적 좌우 아님)", + "eyeLeft": { + "innerCorner": [ + 436.93, + 589.72 + ], + "outerCorner": [ + 345.9, + 578.58 + ], + "upperLidTop": [ + 382.5, + 563.54 + ], + "lowerLidBottom": [ + 387.01, + 595.53 + ], + "iris": { + "center": [ + 390.36, + 578.05 + ], + "radius": 20.26 + } + }, + "eyeRight": { + "innerCorner": [ + 553.44, + 588.28 + ], + "outerCorner": [ + 643.72, + 575.13 + ], + "upperLidTop": [ + 606.63, + 560.81 + ], + "lowerLidBottom": [ + 603.48, + 592.96 + ], + "iris": { + "center": [ + 598.2, + 575.68 + ], + "radius": 20.48 + } + }, + "eyebrowLeft": { + "inner": [ + 459.17, + 529.9 + ], + "peak": [ + 359.35, + 517.35 + ], + "outer": [ + 307.83, + 526.22 + ] + }, + "eyebrowRight": { + "inner": [ + 522.25, + 526.89 + ], + "peak": [ + 630.75, + 512.66 + ], + "outer": [ + 686.75, + 520.91 + ] + }, + "noseTip": [ + 494.67, + 718.39 + ], + "mouthCornerLeft": [ + 417.35, + 818.27 + ], + "mouthCornerRight": [ + 572.28, + 816.91 + ], + "upperLipTopCenter": [ + 494.64, + 787.63 + ], + "lowerLipBottomCenter": [ + 494.14, + 843.92 + ], + "chinTip": [ + 496.44, + 950.72 + ], + "faceWidthAtEyeLevelLeft": [ + 270.67, + 641.28 + ], + "faceWidthAtEyeLevelRight": [ + 725.41, + 637.27 + ] + }, + "landmarkDetector": "mediapipe FaceLandmarker (tasks) 1.0.1, model=face_landmarker(float16, v1)", + "browCenterline": { + "method": "Otsu(front lum in bbox) AND diff(F-front)>=25, morphological closing to merge hatching, single global degree-2 polyfit on column-weighted centroid with one-pass outlier removal", + "diffThresh": 25.0, + "bboxPad": { + "x": 25.0, + "yUp": 42.0, + "yDown": 14.0 + }, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "outlierStdMult": 2.0, + "edgeInsetFrac": 0.03, + "peakWindow": [ + 0.25, + 0.6 + ], + "peakFallbackFrac": 0.35, + "peakFlatHeightPx": 3.0, + "peakFailEdgeFrac": 0.2, + "oldPoints": { + "browLeft": { + "inner": [ + 450.44, + 534.93 + ], + "peak": [ + 352.85, + 500.08 + ], + "outer": [ + 303.22, + 530.63 + ] + }, + "browRight": { + "inner": [ + 537.41, + 533.76 + ], + "peak": [ + 635.0, + 496.78 + ], + "outer": [ + 687.28, + 526.3 + ] + } + }, + "newPoints": { + "browLeft": { + "name": "browLeft", + "bbox": [ + 278, + 458, + 475, + 549 + ], + "otsuThresh": 96.0, + "colRange": [ + 303, + 464 + ], + "width": 161.0, + "nColumns": 162, + "nOutliersRemoved": 7, + "fitCoeffs": [ + 0.00196806, + -1.48522863, + 796.92780822 + ], + "inner": [ + 459.17, + 529.9 + ], + "peak": [ + 359.35, + 517.35 + ], + "outer": [ + 307.83, + 526.22 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.9321, + "checkA_pass": true, + "halfWidthInner": 12.85, + "halfWidthPeak": 16.459, + "halfWidthOuter": 2.411, + "bandX0": 278, + "bandY0": 458, + "colMin": 303, + "colMax": 464 + }, + "browRight": { + "name": "browRight", + "bbox": [ + 512, + 455, + 712, + 548 + ], + "otsuThresh": 109.0, + "colRange": [ + 517, + 692 + ], + "width": 175.0, + "nColumns": 174, + "nOutliersRemoved": 8, + "fitCoeffs": [ + 0.00169369, + -2.08406041, + 1153.34922962 + ], + "inner": [ + 522.25, + 526.89 + ], + "peak": [ + 630.75, + 512.66 + ], + "outer": [ + 686.75, + 520.91 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.9195, + "checkA_pass": true, + "halfWidthInner": 15.261, + "halfWidthPeak": 12.233, + "halfWidthOuter": 6.803, + "bandX0": 512, + "bandY0": 455, + "colMin": 517, + "colMax": 692 + } + }, + "halfWidthLeft": [ + 12.85, + 16.459, + 2.411 + ], + "halfWidthRight": [ + 15.261, + 12.233, + 6.803 + ], + "halfWidthNote": "원화 눈썹 잉크 띠 반두께[inner,peak,outer](px, 중심선 법선 방향). export_rig.py가 persona.json browHalfWidthFromArt!=false(기본)면 RigBrow.halfWidth로 내보낸다.", + "checkB_innerMinusPeakY": { + "browLeft": 12.55, + "browRight": 14.23 + }, + "checkD_symmetry": { + "innerYDiff": 3.01, + "peakYDiff": 4.69 + }, + "evidenceImage": "preview/v2/brow-centerline.jpg" + }, + "schemaVersion": "vignette.avatar.v3.layers.v1", + "persona": "P2", + "canvas": { + "w": 1005, + "h": 1566 + }, + "base": { + "front": "base/base-front.png", + "faceless": "base/base-faceless.png", + "facelessPadded": "base/base-faceless-padded.png", + "facelessSize": [ + 1005, + 1566 + ], + "padNote": "base-faceless.png 마지막 행을 0번 복제해 1005x1566(base-front.png 크기)으로 패딩한 것이 F다." + }, + "segmenter": { + "model": "selfie_multiclass_256x256.tflite (mediapipe ImageSegmenter, storage.googleapis.com)", + "categories": { + "0": "background", + "1": "hair", + "2": "bodySkin", + "3": "faceSkin", + "4": "clothes", + "5": "others" + }, + "categoryPixelCounts": { + "0": 565865, + "1": 185705, + "2": 68467, + "3": 220816, + "4": 532832, + "5": 145 + }, + "hairEdgeRefine": { + "dilatePx": 6, + "lumThreshold": 110, + "addedPixels": 6806 + } + }, + "chinLine": { + "landmarkIndex": 152, + "xy": [ + 496.44, + 950.72 + ], + "marginPx": 8, + "cutY": 958.72 + }, + "faceOval": { + "landmarkLoop": [ + 10, + 338, + 297, + 332, + 284, + 251, + 389, + 356, + 454, + 323, + 361, + 288, + 397, + 365, + 379, + 378, + 400, + 377, + 152, + 148, + 176, + 149, + 150, + 136, + 172, + 58, + 132, + 93, + 234, + 127, + 162, + 21, + 54, + 103, + 67, + 109 + ], + "scale": 1.04, + "sourceImage": "base/base-front.png" + }, + "layers": [ + { + "id": "body", + "file": "layers/body.png", + "source": "base-faceless-masked+regenerated-fill", + "alphaBBox": [ + 0, + 751, + 1005, + 1566 + ], + "opaquePixels": 600798, + "greenResidue": 0, + "fillTargetPixels": 20892, + "fillSourceRaw": "raw/body.png (rejected 재생성이 아니라 수용된 body.png의 크로마키 결과; head/hairFront와 달리 body 재생성은 승인됨)" + }, + { + "id": "head", + "file": "layers/head.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 170, + 95, + 827, + 961 + ], + "opaquePixels": 417526, + "greenResidue": 0 + }, + { + "id": "hairFront", + "file": "layers/hairFront.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 255, + 398, + 738, + 822 + ], + "opaquePixels": 19720, + "greenResidue": 0 + } + ], + "rejectedRawEdits": { + "body": { + "file": "raw/body.png", + "status": "accepted-as-fill-source", + "reason": "정렬 (0,0), 형태 변형 없음 — head_mask 채움 전용 소스로 재사용" + } + }, + "composite": { + "meanAbsDiff": { + "full": 1.461588396883187, + "face": 0.18478636311778845, + "hairOutline": 5.348185720428226 + }, + "target": { + "full": 3.0, + "pass": true + }, + "backgroundNote": "카테고리0(배경)은 종이결 텍스처 노이즈(표준편차 ~29/채널)를 포함해 평탄한 크림(#EEE5D3)과 자체적으로 평균절대차 ~7 차이가 난다." + }, + "layersV2": { + "chinBandFix": { + "targetRegionPixels": 20892, + "sourceBandHeight": 150, + "rowJitterRange": [ + -2.0, + 2.0 + ], + "rngSeed": 20260930 + }, + "hairEdgeFix": { + "bandOuterPx": 40, + "bandInnerPx": 6, + "lumSmoothstep": [ + 205.0, + 150.0 + ], + "minFragmentAreaPx": 60, + "head": { + "bandOuterPixels": 70076, + "bandInnerPixels": 21428, + "componentsBefore": 6, + "removed": 5, + "removedPixels": 16 + }, + "hairFront": { + "bandOuterPixels": 7840, + "bandInnerPixels": 11194, + "componentsBefore": 70, + "removed": 66, + "removedPixels": 427 + } + }, + "hairPaperGapFix": { + "regionDilatePx": 6, + "paperColorDistThreshold": 40.0, + "paperLumThreshold": 195.0, + "paperSatThreshold": 40.0, + "opaqueAlphaThreshold": 0.95, + "regionPixels": 195749, + "head": { + "targetPixels": 794, + "componentsBefore": 1, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + }, + "hairFront": { + "targetPixels": 0, + "componentsBefore": 4, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + } + }, + "jawInkFix": { + "mouthCenterY": 812.28, + "distThresholdPx": 14.0, + "mergePx": 3, + "aspectThreshold": 1.0, + "removedGroups": [], + "keptGroups": [ + { + "pixels": 53, + "bbox": [ + 304, + 813, + 315, + 828 + ], + "width": 11, + "height": 15, + "aspect": 0.733 + }, + { + "pixels": 83, + "bbox": [ + 684, + 813, + 695, + 824 + ], + "width": 11, + "height": 11, + "aspect": 1.0 + }, + { + "pixels": 2, + "bbox": [ + 690, + 844, + 691, + 846 + ], + "width": 1, + "height": 2, + "aspect": 0.5 + }, + { + "pixels": 2, + "bbox": [ + 689, + 853, + 690, + 855 + ], + "width": 1, + "height": 2, + "aspect": 0.5 + } + ], + "removedPixels": 0, + "strayFragmentCleanup": { + "componentsBefore": 4, + "removed": 0, + "removedPixels": 0 + } + }, + "metrics": { + "body": { + "haloPct": 0.044228217602830605 + }, + "head": { + "haloPct": 4.264659767952336, + "bgLeakAlphaMean": 2.8734067319145284e-05, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + }, + "hairFront": { + "haloPct": 0.0, + "bgLeakAlphaMean": 0.0, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + } + }, + "layers": [ + { + "id": "body", + "bbox": [ + 0, + 751, + 1005, + 1566 + ], + "opaque": 599752, + "greenResidue": 0 + }, + { + "id": "head", + "bbox": [ + 164, + 84, + 831, + 961 + ], + "opaque": 420250, + "greenResidue": 0 + }, + { + "id": "hairFront", + "bbox": [ + 240, + 398, + 738, + 858 + ], + "opaque": 24155, + "greenResidue": 0 + } + ], + "faceDetail": { + "browLandmarksSource": "manifest.landmarks.eyebrowLeft/Right", + "region": "face", + "faceInsetPx": 24.0, + "matchFacelessColor": true, + "matchFacelessColorDeltaRgb": { + "eyeLeft": [ + -15.66, + -13.97, + -11.51 + ], + "eyeRight": [ + -8.91, + -8.23, + -7.54 + ], + "browLeft": [ + -4.74, + -3.66, + -3.41 + ], + "browRight": [ + -2.21, + -1.58, + -1.88 + ], + "mouth": [ + -7.06, + -5.11, + -4.14 + ] + }, + "regions": { + "eyeLeft": [ + 315.9, + 507.4, + 461.9, + 665.5 + ], + "eyeRight": [ + 528.4, + 502.7, + 673.7, + 663.0 + ], + "mouth": [ + 372.4, + 743.4, + 617.3, + 935.7 + ], + "moles": [] + }, + "exclusionPixels": { + "eyeLeft": 12408, + "eyeRight": 11446, + "browLeft": 15459, + "browRight": 15182, + "mouth": 19731, + "union": 62281 + }, + "hairMaskPixels": 194350, + "bbox": [ + 274, + 405, + 723, + 955 + ], + "textureCloneStamp": { + "cloneTargetThreshold": 65.0, + "avoidThreshold": 110.0, + "lineOpeningIterations": 3, + "featherPx": 4.0, + "badTexturePixels": 173, + "preservedShadowPixels": 0, + "components": [ + { + "componentId": 1, + "pixels": 1, + "offset": [ + 100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 2, + "pixels": 19, + "offset": [ + 100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 3, + "pixels": 13, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 4, + "pixels": 9, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 5, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 6, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 7, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 8, + "pixels": 8, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 9, + "pixels": 2, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 10, + "pixels": 1, + "offset": [ + -120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 11, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 12, + "pixels": 1, + "offset": [ + -120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 13, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 14, + "pixels": 2, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 15, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 16, + "pixels": 1, + "offset": [ + -40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 17, + "pixels": 2, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 18, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 19, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 20, + "pixels": 6, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 21, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 22, + "pixels": 6, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 23, + "pixels": 1, + "offset": [ + 0, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 24, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 25, + "pixels": 4, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 26, + "pixels": 11, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 27, + "pixels": 2, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 28, + "pixels": 1, + "offset": [ + -40, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 29, + "pixels": 3, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 30, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 31, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 32, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 33, + "pixels": 8, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 34, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 35, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 36, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 37, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 38, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 39, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 40, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 41, + "pixels": 1, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 42, + "pixels": 9, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 43, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 44, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 45, + "pixels": 25, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 46, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 47, + "pixels": 1, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 48, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 49, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 50, + "pixels": 1, + "offset": [ + 0, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 51, + "pixels": 7, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 52, + "pixels": 1, + "offset": [ + 40, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 53, + "pixels": 1, + "offset": [ + -40, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 54, + "pixels": 1, + "offset": [ + 0, + 120 + ], + "method": "clone-stamp" + } + ] + }, + "genericPatches": { + "forehead": [ + 496, + 412, + 544, + 460 + ], + "cheekLeft": [ + 321, + 643, + 369, + 691 + ], + "cheekRight": [ + 514, + 640, + 562, + 688 + ] + }, + "genericPatchBaseline": { + "highFreqEnergy": 9.550611294730496, + "lineEnergy": 3.7758152639145983 + }, + "checkA_meanAbsDiff": 0.5536637943489896, + "checkB_seamLumDiff": 0.9985878703074036, + "checkC_holeDarkResiduePct": 0.1944520925110132, + "checkC_violationPixels": 113, + "checkD_texturePreservation": { + "eyeLeft": { + "insideEnergy": 8.86627100371463, + "baselineEnergy": 9.550611294730496, + "ratio": 0.9283459173557354, + "pass": true + }, + "eyeRight": { + "insideEnergy": 7.971412240626346, + "baselineEnergy": 9.550611294730496, + "ratio": 0.8346494265790646, + "pass": true + }, + "browLeft": { + "insideEnergy": 11.665703959963366, + "baselineEnergy": 9.550611294730496, + "ratio": 1.2214614960196173, + "pass": true + }, + "browRight": { + "insideEnergy": 9.922083278546825, + "baselineEnergy": 9.550611294730496, + "ratio": 1.0388951002561782, + "pass": true + }, + "mouth": { + "insideEnergy": 8.190923228958187, + "baselineEnergy": 9.550611294730496, + "ratio": 0.8576333991812115, + "pass": true + } + }, + "checkD_allPass": true, + "checkE_ghostOutline": { + "eyeLeft": { + "bandLineEnergy": 7.5041240509892235, + "baselineLineEnergy": 3.7758152639145983, + "ratio": 1.9874182200347588, + "pass": false + }, + "eyeRight": { + "bandLineEnergy": 5.421789669498705, + "baselineLineEnergy": 3.7758152639145983, + "ratio": 1.4359255658810048, + "pass": true + }, + "browLeft": { + "bandLineEnergy": 6.336968296699441, + "baselineLineEnergy": 3.7758152639145983, + "ratio": 1.678304645161467, + "pass": false + }, + "browRight": { + "bandLineEnergy": 4.752161517472518, + "baselineLineEnergy": 3.7758152639145983, + "ratio": 1.2585789254280644, + "pass": true + }, + "mouth": { + "bandLineEnergy": 5.409947647889773, + "baselineLineEnergy": 3.7758152639145983, + "ratio": 1.4327892838382612, + "pass": true + } + }, + "checkE_allPass": false, + "checkDarkCircle": { + "eyeLeft": { + "compositeMean": 125.51828571428571, + "frontMean": 125.43542857142857, + "diff": 0.08285714285713652, + "pass": true + }, + "eyeRight": { + "compositeMean": 126.36457142857142, + "frontMean": 126.28990476190475, + "diff": 0.07466666666667265, + "pass": true + } + }, + "checkDarkCircle_allPass": true + }, + "paperGrain": { + "sourceImage": "base/base-front.png", + "sourceOrigin": [ + 739, + 10 + ], + "tileSize": 256, + "personMarginPx": 20, + "cleanFraction": 0.96636962890625, + "contaminatedPixelsFilled": 2204, + "chromaKeep": 0.3, + "targetLumRange": [ + 245.0, + 250.0 + ], + "lumShift": 22.814595540364564, + "finalMeanLum": 247.48806402723034, + "finalLumStd": 2.3873055618421484, + "seamContinuity": { + "leftRightDiff": 0.08759996609734344, + "topBottomDiff": 0.4901310520663742 + } + } + }, + "lipTexture": { + "designVersion": "A5(아랫입술 그늘 띠를 lip-shadow 조각으로 분리)", + "landmarks": { + "mouthCornerLeft": [ + 417.35, + 818.27 + ], + "mouthCornerRight": [ + 572.28, + 816.91 + ], + "upperLipTop": [ + 494.64, + 787.63 + ], + "lowerLipBottom": [ + 494.14, + 843.92 + ], + "mouthCenter": [ + 494.6075988560915, + 812.2768317461014 + ] + }, + "capBBox": [ + 413.81, + 780.77, + 575.82, + 850.77 + ], + "otsuThreshLabA": 135.0, + "diffThresh": 20.0, + "dilatePx": 10.0, + "alphaRampPx": 4.0, + "splitOverlapPx": 2.0, + "shadowBandPx": 18.0, + "shadowTopOverlapPx": 6.0, + "shadowSideRampPx": 6.0, + "shadowTopRampPx": 4.0, + "checks": { + "lip-upper": { + "regionPixelCount": 6559, + "fullOpacityPixelCount": 5652, + "rampPixelCount": 907, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 30, + 31, + 182, + 51 + ] + }, + "lip-lower": { + "regionPixelCount": 6659, + "fullOpacityPixelCount": 5889, + "rampPixelCount": 770, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 30, + 72, + 181, + 48 + ] + }, + "lip-shadow": { + "regionPixelCount": 3720, + "fullOpacityPixelCount": 2004, + "rampPixelCount": 1716, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 40, + 76, + 155, + 52 + ] + }, + "splitOverlapPixelCount": 360, + "splitOverlapBandOk": true, + "splitOverlapAlphaMaxDiff": 0, + "splitOverlapConsistentOk": true, + "splitCoverageMismatchPixelCount": 0, + "splitCheckOk": true, + "shadowLowerOverlapPixelCount": 2770, + "shadowLowerOverlapMaxDiff": 55.057347174163795, + "shadowLowerOverlapDiffGt1PixelCount": 153, + "shadowLowerOverlapOk": false + }, + "check3NeutralComposite": { + "fullOpacityMaxDiff": 0.0, + "rampMeanAbsDiff": 3.432, + "mouthBBoxMeanAbsDiff": 0.841 + }, + "pngFileSizes": { + "lip-upper": 23842, + "lip-lower": 21817, + "lip-shadow": 20971 + }, + "canvasOrigin": { + "upper": [ + 404, + 772 + ], + "lower": [ + 404, + 813 + ], + "shadow": [ + 414, + 817 + ] + }, + "evidenceImage": "preview/v2/lip-texture.jpg", + "check4WebpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jaw": { + "designVersion": "A5(결정문 §8.4 하관 띠 변형 — 턱 조각 원본)", + "noseTip": [ + 494.67, + 718.39 + ], + "chinTip": [ + 496.44, + 950.72 + ], + "yFormula": "noseTip.y - 50 - 10 .. chinTip.y + 40", + "noseToTopPx": 60.0, + "chinToBottomPx": 40.0, + "ovalOutsetPx": 18.0, + "faceOvalSource": "export_rig.detect_face_landmarks + compute_face_oval(base-front.png, 결정적)", + "bboxCanvas": [ + 246, + 658, + 752, + 991 + ], + "naiveXRangeForComparison": [ + 246, + 752 + ], + "checks": { + "head": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 343465 + }, + "detail": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 388506 + } + }, + "evidenceImage": "preview/v2/jaw-pieces.jpg", + "check1VsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.795, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.83, + "maxAbsDiffPremultipliedRgb": 35.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 15864, + "lip-lower": 14532, + "lip-shadow": 14592 + }, + "totalBytes": 44988, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 26526, + "jaw-detail": 27760 + }, + "totalBytes": 54286, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.795, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.83, + "maxAbsDiffPremultipliedRgb": 35.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "pipelineRun": { + "persona": "P2", + "timestamp": "2026-10-01T21:59:56", + "completed": true, + "stages": [ + { + "stage": "brow_sprite", + "ok": true, + "elapsedSec": 3.05 + }, + { + "stage": "paper_grain", + "ok": true, + "elapsedSec": 2.92 + }, + { + "stage": "lip_texture", + "ok": true, + "elapsedSec": 2.2 + }, + { + "stage": "jaw_pieces", + "ok": true, + "elapsedSec": 2.17 + }, + { + "stage": "export_rig", + "ok": true, + "elapsedSec": 17.99 + }, + { + "stage": "final_previews", + "ok": true, + "elapsedSec": 19.72 + } + ] + }, + "browSprite": { + "enabled": true, + "bandExtraHalfHeightPx": 8.0, + "bandEndExtendPx": 6.0, + "diffThresh": 25.0, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "hairSource": "layers/v2/hairFront.png alpha(게시되는 레이어 그 자체, 분할 카테고리 아님)", + "hairAlphaThresh": 128.0, + "hairDilateIterations": 1, + "rampPx": 1.5, + "inkLumMethod": "median(ink-classified pixels in band, region after hair removal)", + "minAlphaForUnmix": 0.05, + "hairMaskPixelCount": 26909, + "left": { + "bboxCanvas": [ + 307, + 500, + 158, + 55 + ], + "halfHeightPx": 24.459, + "otsuThresh": 96.0, + "lSkin": 165.0, + "lInk": 41.333, + "regionPixelCount": 3422, + "hairOverlapPixelCount": 335, + "neutralCompositeMeanAbsDiffAlphaRegion": 3.292, + "pngFileSizeBytes": 11795 + }, + "right": { + "bboxCanvas": [ + 515, + 492, + 176, + 57 + ], + "halfHeightPx": 23.261, + "otsuThresh": 109.0, + "lSkin": 172.0, + "lInk": 54.0, + "regionPixelCount": 4122, + "hairOverlapPixelCount": 47, + "neutralCompositeMeanAbsDiffAlphaRegion": 1.755, + "pngFileSizeBytes": 14396 + }, + "canvasOrigin": { + "left": [ + 307.0, + 500.0 + ], + "right": [ + 515.0, + 492.0 + ] + }, + "evidenceImage": "preview/v2/brow-sprite.jpg", + "checkWebpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "eyeLineScale": { + "enabled": true, + "method": "눈 폭 가운데 60% 열마다 upperLidTop.y-12 ~ 홍채중심y 사이 첫 연속 어두운(lum<80) 구간 길이의 중앙값", + "windowAbovePx": 12.0, + "darkLumThresh": 80.0, + "columnMiddleFrac": 0.6, + "p1BaselinePx": 2.0, + "lineScaleClampRange": [ + 1.0, + 2.5 + ], + "left": { + "measuredPx": 19.0, + "nColumns": 56, + "ratio": 9.5, + "lineScale": 2.5 + }, + "right": { + "measuredPx": 19.0, + "nColumns": 56, + "ratio": 9.5, + "lineScale": 2.5 + } + }, + "iris": { + "method": "가로: 중심 y 부근 상하 각 4행에서 중심 x를 포함하는 연속 어두운(lum<100) 구간의 중앙값으로 반지름·중심x. 세로: 중심 x 부근 좌우 각 4열에서 중심 y를 포함하는 연속 어두운 구간의 아래쪽 끝 중앙값에서 가로 반지름을 빼 중심y(세로축은 윗눈꺼풀 잉크와 홍채가 같은 톤으로 이어져 위쪽 경계를 가를 수 없다).", + "darkLumThresh": 100.0, + "scanBandPx": 4, + "left": { + "measuredCenter": [ + 391.0, + 576.0 + ], + "measuredRadius": 20.0, + "rigCenter": [ + 390.36, + 578.05 + ], + "rigRadius": 20.26, + "nRowsHorizontal": 9, + "nColsVertical": 9 + }, + "right": { + "measuredCenter": [ + 598.5, + 573.5 + ], + "measuredRadius": 20.5, + "rigCenter": [ + 598.2, + 575.68 + ], + "rigRadius": 20.48, + "nRowsHorizontal": 9, + "nColsVertical": 9 + } + }, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 8120, + "brow-right": 10126 + }, + "totalBytes": 18246, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p2-linocut/persona.json b/docs/avatar-art/p2-linocut/persona.json new file mode 100644 index 0000000..d3a7d23 --- /dev/null +++ b/docs/avatar-art/p2-linocut/persona.json @@ -0,0 +1,37 @@ +{ + "code": "P2", + "publicSlug": "p2", + "rigFileName": "p2Rig.ts", + "rigExportName": "P2_LINOCUT_RIG", + "styleFrame": "../art-direction-v3/p1/r2-b-linocut.png", + "paletteSamples": { + "ink": { + "box": [330, 150, 670, 310], + "lumThreshold": 55 + }, + "motifPetalBoxes": [ + { "label": "sun", "kind": "ochre", "box": [1230, 10, 1536, 210] }, + { "label": "tulip", "kind": "ochre", "box": [1030, 280, 1170, 560] } + ], + "motifLeafBoxes": [ + { "label": "cloudLeft", "kind": "blue", "box": [20, 20, 380, 190] }, + { "label": "raincloud", "kind": "blue", "box": [520, 10, 930, 230] }, + { "label": "wiltedFlowerLeaf", "kind": "blue", "box": [520, 280, 650, 580] }, + { "label": "closedBudLeaf", "kind": "blue", "box": [10, 290, 110, 570] } + ] + }, + "faceDetail": { + "moles": [], + "region": "face", + "faceInsetPx": 24, + "matchFacelessColor": true + }, + "pivots": { + "neck": [496.44, 1021.17], + "body": [502, 1566], + "face": [492.0, 658.93] + }, + "crops": { + "bustYOffset": 40 + } +} diff --git a/docs/avatar-art/p2-linocut/preview/qa/face-art-vs-render.jpg b/docs/avatar-art/p2-linocut/preview/qa/face-art-vs-render.jpg new file mode 100644 index 0000000..7ce6f70 Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/qa/face-art-vs-render.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/qa/face-zoom.jpg b/docs/avatar-art/p2-linocut/preview/qa/face-zoom.jpg new file mode 100644 index 0000000..f1b2b62 Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/qa/face-zoom.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/qa/head-halo-check.jpg b/docs/avatar-art/p2-linocut/preview/qa/head-halo-check.jpg new file mode 100644 index 0000000..e8acae1 Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/qa/head-halo-check.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/qa/neutral-vs-art.jpg b/docs/avatar-art/p2-linocut/preview/qa/neutral-vs-art.jpg new file mode 100644 index 0000000..d64d431 Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/qa/neutral-vs-art.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/qa/normalized.jpg b/docs/avatar-art/p2-linocut/preview/qa/normalized.jpg new file mode 100644 index 0000000..0c49d6b Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/qa/normalized.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/qa/sheet-expr-bust.jpg b/docs/avatar-art/p2-linocut/preview/qa/sheet-expr-bust.jpg new file mode 100644 index 0000000..adb801b Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/qa/sheet-expr-bust.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/qa/sheet-expr-face.jpg b/docs/avatar-art/p2-linocut/preview/qa/sheet-expr-face.jpg new file mode 100644 index 0000000..e4c5bbe Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/qa/sheet-expr-face.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/qa/sheet-viseme.jpg b/docs/avatar-art/p2-linocut/preview/qa/sheet-viseme.jpg new file mode 100644 index 0000000..98d4419 Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/qa/sheet-viseme.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/qa/viseme-timeline.json b/docs/avatar-art/p2-linocut/preview/qa/viseme-timeline.json new file mode 100644 index 0000000..5f40aac --- /dev/null +++ b/docs/avatar-art/p2-linocut/preview/qa/viseme-timeline.json @@ -0,0 +1,287 @@ +[ + { + "t": 0, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00000.png" + }, + { + "t": 50, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00050.png" + }, + { + "t": 100, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00100.png" + }, + { + "t": 150, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00150.png" + }, + { + "t": 200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00200.png" + }, + { + "t": 250, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00250.png" + }, + { + "t": 300, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00300.png" + }, + { + "t": 350, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00350.png" + }, + { + "t": 400, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00400.png" + }, + { + "t": 450, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00450.png" + }, + { + "t": 500, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00500.png" + }, + { + "t": 550, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00550.png" + }, + { + "t": 600, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00600.png" + }, + { + "t": 650, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00650.png" + }, + { + "t": 700, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00700.png" + }, + { + "t": 750, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00750.png" + }, + { + "t": 800, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00800.png" + }, + { + "t": 850, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00850.png" + }, + { + "t": 900, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00900.png" + }, + { + "t": 950, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t00950.png" + }, + { + "t": 1000, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01000.png" + }, + { + "t": 1050, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01050.png" + }, + { + "t": 1100, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01100.png" + }, + { + "t": 1150, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01150.png" + }, + { + "t": 1200, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01200.png" + }, + { + "t": 1250, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01250.png" + }, + { + "t": 1300, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01300.png" + }, + { + "t": 1350, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01350.png" + }, + { + "t": 1400, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01400.png" + }, + { + "t": 1450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01450.png" + }, + { + "t": 1500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01500.png" + }, + { + "t": 1550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01550.png" + }, + { + "t": 1600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01600.png" + }, + { + "t": 1650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01650.png" + }, + { + "t": 1700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01700.png" + }, + { + "t": 1750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01750.png" + }, + { + "t": 1800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01800.png" + }, + { + "t": 1850, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01850.png" + }, + { + "t": 1900, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01900.png" + }, + { + "t": 1950, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t01950.png" + }, + { + "t": 2000, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02000.png" + }, + { + "t": 2050, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02050.png" + }, + { + "t": 2100, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02100.png" + }, + { + "t": 2150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02150.png" + }, + { + "t": 2200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02200.png" + }, + { + "t": 2250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02250.png" + }, + { + "t": 2300, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02300.png" + }, + { + "t": 2350, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02350.png" + }, + { + "t": 2400, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02400.png" + }, + { + "t": 2450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02450.png" + }, + { + "t": 2500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02500.png" + }, + { + "t": 2550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02550.png" + }, + { + "t": 2600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02600.png" + }, + { + "t": 2650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02650.png" + }, + { + "t": 2700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02700.png" + }, + { + "t": 2750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02750.png" + }, + { + "t": 2800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p2-linocut\\preview\\qa\\frames\\viseme-scan-t02800.png" + } +] \ No newline at end of file diff --git a/docs/avatar-art/p2-linocut/preview/v2/brow-centerline.jpg b/docs/avatar-art/p2-linocut/preview/v2/brow-centerline.jpg new file mode 100644 index 0000000..93c4bfd Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/v2/brow-centerline.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/v2/brow-sprite.jpg b/docs/avatar-art/p2-linocut/preview/v2/brow-sprite.jpg new file mode 100644 index 0000000..dd14fef Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/v2/brow-sprite.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/v2/export-rig-report.json b/docs/avatar-art/p2-linocut/preview/v2/export-rig-report.json new file mode 100644 index 0000000..c1af573 --- /dev/null +++ b/docs/avatar-art/p2-linocut/preview/v2/export-rig-report.json @@ -0,0 +1,676 @@ +{ + "faceOvalBBox": [ + 257.9, + 398.4, + 736.0, + 961.4 + ], + "cropsFace": [ + 181.6, + 364.6, + 630.6, + 630.6 + ], + "mouthCenter": [ + 494.6, + 812.3 + ], + "palette": { + "ink": "#1E1E1D", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#9D7253", + "lipLower": "#A87857", + "mouthLine": "#242220", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "paletteSamples": { + "eyeLeft": { + "sclera": "#D0A275", + "iris": "#2E2823", + "irisRing": "#302B23", + "n": { + "sclera": 942, + "iris": 185, + "irisRing": 377 + } + }, + "eyeRight": { + "sclera": "#CAA075", + "iris": "#2E2923", + "irisRing": "#372D26", + "n": { + "sclera": 968, + "iris": 191, + "irisRing": 384 + } + }, + "scleraIrisIrisRingFixedOverride": { + "reason": "persona.json paletteSamples.eyeOverride(고정 설계값)", + "measured": { + "sclera": "#CDA175", + "iris": "#2E2823", + "irisRing": "#342C24" + }, + "fixed": { + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F" + } + }, + "ink": { + "box": [ + 330, + 150, + 670, + 310 + ], + "lumThreshold": 55.0, + "n": 45379, + "hex": "#1E1E1D" + }, + "lipUpper": { + "box": [ + 412, + 784, + 577, + 810 + ], + "hex": "#9D7253" + }, + "lipLower": { + "box": [ + 412, + 814, + 577, + 846 + ], + "hex": "#A87857" + }, + "mouthLine": { + "box": [ + 432, + 810, + 557, + 815 + ], + "hex": "#242220" + }, + "motifPetal": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "sun": { + "box": [ + 1230, + 10, + 1536, + 210 + ], + "n": 20570, + "hex": "#D3A661" + }, + "tulip": { + "box": [ + 1030, + 280, + 1170, + 560 + ], + "n": 4314, + "hex": "#CCA063" + } + }, + "hex": "#D0A362" + }, + "motifLeaf": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "cloudLeft": { + "box": [ + 20, + 20, + 380, + 190 + ], + "n": 21312, + "hex": "#636D76" + }, + "raincloud": { + "box": [ + 520, + 10, + 930, + 230 + ], + "n": 27607, + "hex": "#586B76" + }, + "wiltedFlowerLeaf": { + "box": [ + 520, + 280, + 650, + 580 + ], + "n": 5818, + "hex": "#495961" + }, + "closedBudLeaf": { + "box": [ + 10, + 290, + 110, + 570 + ], + "n": 6589, + "hex": "#495961" + } + }, + "hex": "#53626C" + } + }, + "publish": { + "fileSizes": { + "body": 125460, + "head": 89170, + "hair-front": 16984, + "face-detail": 47270, + "paper-grain": 1034 + }, + "encodeMeta": { + "quality": 80, + "scale": 1.0, + "totalBytes": 279918 + }, + "totalBytes": 279918 + }, + "grain": { + "href": "/avatar/v3/p2/paper-grain.webp", + "size": 256 + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 15864, + "lip-lower": 14532, + "lip-shadow": 14592 + }, + "totalBytes": 44988, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 26526, + "jaw-detail": 27760 + }, + "totalBytes": 54286, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.795, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.83, + "maxAbsDiffPremultipliedRgb": 35.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 8120, + "brow-right": 10126 + }, + "totalBytes": 18246, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "rig": { + "schemaVersion": "vignette.avatar.v3.rig.v1", + "persona": "P2", + "canvas": { + "w": 1005, + "h": 1566 + }, + "layers": { + "body": { + "href": "/avatar/v3/p2/body.webp", + "x": 0, + "y": 751, + "w": 1005, + "h": 815 + }, + "head": { + "href": "/avatar/v3/p2/head.webp", + "x": 164, + "y": 84, + "w": 667, + "h": 877 + }, + "hairFront": { + "href": "/avatar/v3/p2/hair-front.webp", + "x": 240, + "y": 398, + "w": 498, + "h": 460 + }, + "faceDetail": { + "href": "/avatar/v3/p2/face-detail.webp", + "x": 274, + "y": 405, + "w": 449, + "h": 550 + } + }, + "grain": { + "href": "/avatar/v3/p2/paper-grain.webp", + "size": 256 + }, + "lipTexture": { + "upper": { + "href": "/avatar/v3/p2/lip-upper.webp", + "x": 404, + "y": 772, + "w": 182, + "h": 51 + }, + "lower": { + "href": "/avatar/v3/p2/lip-lower.webp", + "x": 404, + "y": 813, + "w": 181, + "h": 48 + }, + "shadow": { + "href": "/avatar/v3/p2/lip-shadow.webp", + "x": 414, + "y": 817, + "w": 155, + "h": 52 + } + }, + "jaw": { + "head": { + "href": "/avatar/v3/p2/jaw-head.webp", + "x": 246, + "y": 658, + "w": 506, + "h": 333 + }, + "detail": { + "href": "/avatar/v3/p2/jaw-detail.webp", + "x": 246, + "y": 658, + "w": 506, + "h": 333 + } + }, + "motif": null, + "pivots": { + "neck": [ + 496.44, + 1021.17 + ], + "body": [ + 502, + 1566 + ], + "face": [ + 492.0, + 658.93 + ] + }, + "crops": { + "portrait": [ + 0, + 0, + 1005, + 1566 + ], + "bust": [ + 0.0, + 40.0, + 1005.0, + 1005.0 + ], + "face": [ + 181.6128492420554, + 364.57844417896274, + 630.602422984314, + 630.602422984314 + ] + }, + "faceOval": [ + [ + 492.2, + 398.4 + ], + [ + 558.0, + 399.3 + ], + [ + 614.2, + 407.7 + ], + [ + 665.7, + 426.4 + ], + [ + 699.0, + 456.1 + ], + [ + 719.9, + 494.6 + ], + [ + 731.3, + 536.0 + ], + [ + 736.0, + 586.9 + ], + [ + 734.6, + 635.4 + ], + [ + 730.5, + 685.8 + ], + [ + 721.5, + 739.0 + ], + [ + 704.8, + 795.1 + ], + [ + 682.2, + 840.4 + ], + [ + 657.5, + 873.5 + ], + [ + 627.1, + 903.3 + ], + [ + 601.0, + 924.5 + ], + [ + 572.8, + 943.3 + ], + [ + 539.3, + 957.3 + ], + [ + 496.4, + 961.4 + ], + [ + 453.8, + 957.3 + ], + [ + 421.0, + 943.3 + ], + [ + 393.2, + 924.7 + ], + [ + 367.4, + 904.2 + ], + [ + 338.1, + 874.9 + ], + [ + 315.0, + 842.0 + ], + [ + 293.7, + 797.6 + ], + [ + 277.1, + 741.8 + ], + [ + 267.0, + 688.9 + ], + [ + 261.6, + 639.6 + ], + [ + 257.9, + 591.7 + ], + [ + 260.7, + 541.3 + ], + [ + 270.6, + 499.5 + ], + [ + 290.1, + 460.8 + ], + [ + 321.9, + 430.6 + ], + [ + 371.3, + 410.5 + ], + [ + 426.6, + 401.0 + ] + ], + "landmarks": { + "eyeLeft": { + "inner": [ + 436.9, + 589.7 + ], + "outer": [ + 345.9, + 578.6 + ], + "upperLidTop": [ + 382.5, + 563.5 + ], + "lowerLidBottom": [ + 387.0, + 595.5 + ], + "iris": { + "center": [ + 391.0, + 576.0 + ], + "radius": 20.0 + }, + "lineScale": 2.5 + }, + "eyeRight": { + "inner": [ + 553.4, + 588.3 + ], + "outer": [ + 643.7, + 575.1 + ], + "upperLidTop": [ + 606.6, + 560.8 + ], + "lowerLidBottom": [ + 603.5, + 593.0 + ], + "iris": { + "center": [ + 598.5, + 573.5 + ], + "radius": 20.5 + }, + "lineScale": 2.5 + }, + "browLeft": { + "inner": [ + 459.2, + 529.9 + ], + "peak": [ + 359.4, + 517.4 + ], + "outer": [ + 307.8, + 526.2 + ], + "halfWidth": [ + 12.85, + 16.46, + 2.41 + ], + "sprite": { + "href": "/avatar/v3/p2/brow-left.webp", + "x": 307.0, + "y": 500.0, + "w": 158, + "h": 55 + } + }, + "browRight": { + "inner": [ + 522.2, + 526.9 + ], + "peak": [ + 630.8, + 512.7 + ], + "outer": [ + 686.8, + 520.9 + ], + "halfWidth": [ + 15.26, + 12.23, + 6.8 + ], + "sprite": { + "href": "/avatar/v3/p2/brow-right.webp", + "x": 515.0, + "y": 492.0, + "w": 176, + "h": 57 + } + }, + "noseTip": [ + 494.7, + 718.4 + ], + "mouthCornerLeft": [ + 417.4, + 818.3 + ], + "mouthCornerRight": [ + 572.3, + 816.9 + ], + "upperLipTop": [ + 494.6, + 787.6 + ], + "lowerLipBottom": [ + 494.1, + 843.9 + ], + "mouthCenter": [ + 494.6, + 812.3 + ], + "chinTip": [ + 496.4, + 950.7 + ] + }, + "palette": { + "ink": "#1E1E1D", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#9D7253", + "lipLower": "#A87857", + "mouthLine": "#242220", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "backdrop": { + "cognitive": "#ECE3D1", + "positive": "#F1DEC2", + "negative": "#DCE0E2", + "defensive": "#E6DAD3", + "energy": "#E2E0D0" + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p2-linocut/preview/v2/ghost-check.jpg b/docs/avatar-art/p2-linocut/preview/v2/ghost-check.jpg new file mode 100644 index 0000000..91e22c5 Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/v2/ghost-check.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/v2/holes-texture.jpg b/docs/avatar-art/p2-linocut/preview/v2/holes-texture.jpg new file mode 100644 index 0000000..496029f Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/v2/holes-texture.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/v2/jaw-pieces.jpg b/docs/avatar-art/p2-linocut/preview/v2/jaw-pieces.jpg new file mode 100644 index 0000000..96490e4 Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/v2/jaw-pieces.jpg differ diff --git a/docs/avatar-art/p2-linocut/preview/v2/lip-texture.jpg b/docs/avatar-art/p2-linocut/preview/v2/lip-texture.jpg new file mode 100644 index 0000000..a874738 Binary files /dev/null and b/docs/avatar-art/p2-linocut/preview/v2/lip-texture.jpg differ diff --git a/docs/avatar-art/p2-linocut/prompts/base-faceless.txt b/docs/avatar-art/p2-linocut/prompts/base-faceless.txt new file mode 100644 index 0000000..636f1c8 --- /dev/null +++ b/docs/avatar-art/p2-linocut/prompts/base-faceless.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as faceless.png: + +Redraw exactly the same man, same frontal pose, same framing and same linocut relief-print style as the reference, but leave the face blank: remove the eyes, eyebrows and mouth completely and fill those areas with plain skin in the same flat skin color, keeping the nose, the face outline, the ears, the hair, the neck, the light blue shirt collar, the dark grey V-neck sweater and the lanyard cord exactly as they are. Do not move, resize or redraw anything else. Plain flat cream background, nothing else, no text. diff --git a/docs/avatar-art/p2-linocut/prompts/body.txt b/docs/avatar-art/p2-linocut/prompts/body.txt new file mode 100644 index 0000000..245e013 --- /dev/null +++ b/docs/avatar-art/p2-linocut/prompts/body.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as body.png: + +Keep only the neck, the light blue shirt, the dark grey V-neck sweater and the lanyard cord exactly as they are in the reference: same shapes, same position, same linocut relief-print style, same ink colors and texture. Remove the head, the face, the ears and all of the hair completely. Where the hair or the chin previously covered the neck or the clothes, continue them naturally in the same style so there are no holes. Place the result on a plain flat pure green background (#00ff00) with nothing else, no text. diff --git a/docs/avatar-art/p2-linocut/raw/body.png b/docs/avatar-art/p2-linocut/raw/body.png new file mode 100644 index 0000000..783325b Binary files /dev/null and b/docs/avatar-art/p2-linocut/raw/body.png differ diff --git a/docs/avatar-art/p3-linocut/base/base-faceless.png b/docs/avatar-art/p3-linocut/base/base-faceless.png new file mode 100644 index 0000000..bb450e8 Binary files /dev/null and b/docs/avatar-art/p3-linocut/base/base-faceless.png differ diff --git a/docs/avatar-art/p3-linocut/base/base-front.png b/docs/avatar-art/p3-linocut/base/base-front.png new file mode 100644 index 0000000..e63af36 Binary files /dev/null and b/docs/avatar-art/p3-linocut/base/base-front.png differ diff --git a/docs/avatar-art/p3-linocut/base/edits/aligned-body-1.json b/docs/avatar-art/p3-linocut/base/edits/aligned-body-1.json new file mode 100644 index 0000000..a61595d --- /dev/null +++ b/docs/avatar-art/p3-linocut/base/edits/aligned-body-1.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\body-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\aligned-body-1.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.98505, + "transform": { + "scaleSqrtDet": 1.00052, + "rotationDeg": 0.006, + "translateX": -0.405, + "translateY": -2.096, + "matrix": [ + [ + 0.999904, + 0.000487, + -0.404834 + ], + [ + 0.000102, + 1.001144, + -2.096108 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 502186, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 103878 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p3-linocut/base/edits/aligned-body-2.json b/docs/avatar-art/p3-linocut/base/edits/aligned-body-2.json new file mode 100644 index 0000000..a620dda --- /dev/null +++ b/docs/avatar-art/p3-linocut/base/edits/aligned-body-2.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\body-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\aligned-body-2.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.91082, + "transform": { + "scaleSqrtDet": 1.01057, + "rotationDeg": 0.161, + "translateX": -5.125, + "translateY": -34.475, + "matrix": [ + [ + 1.000922, + 0.003842, + -5.125106 + ], + [ + 0.00281, + 1.020314, + -34.474659 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 506002, + "chamferInMask": { + "median": 1.0, + "p90": 2.0, + "nSamples": 104082 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p3-linocut/base/edits/aligned-faceless-1.json b/docs/avatar-art/p3-linocut/base/edits/aligned-faceless-1.json new file mode 100644 index 0000000..d640398 --- /dev/null +++ b/docs/avatar-art/p3-linocut/base/edits/aligned-faceless-1.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\faceless-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\aligned-faceless-1.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.99268, + "transform": { + "scaleSqrtDet": 1.00001, + "rotationDeg": 0.001, + "translateX": 0.1, + "translateY": -0.799, + "matrix": [ + [ + 0.999892, + -7.7e-05, + 0.100431 + ], + [ + 1.9e-05, + 1.000137, + -0.79903 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 886543, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 171406 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 6518 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 378, + 445, + 527, + 530 + ], + "refInkRatio": 0.2204, + "editedInkRatio": 0.0136 + }, + "eyeB": { + "box": [ + 605, + 425, + 753, + 511 + ], + "refInkRatio": 0.1909, + "editedInkRatio": 0.0001 + }, + "browA": { + "box": [ + 331, + 367, + 536, + 473 + ], + "refInkRatio": 0.3156, + "editedInkRatio": 0.2181 + }, + "browB": { + "box": [ + 580, + 348, + 791, + 443 + ], + "refInkRatio": 0.1773, + "editedInkRatio": 0.0944 + }, + "mouth": { + "box": [ + 470, + 662, + 692, + 785 + ], + "refInkRatio": 0.0531, + "editedInkRatio": 0.0001 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 378, + 445, + 527, + 530 + ], + "eyeB": [ + 605, + 425, + 753, + 511 + ], + "browA": [ + 331, + 367, + 536, + 473 + ], + "browB": [ + 580, + 348, + 791, + 443 + ], + "mouth": [ + 470, + 662, + 692, + 785 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p3-linocut/base/edits/aligned-faceless-2.json b/docs/avatar-art/p3-linocut/base/edits/aligned-faceless-2.json new file mode 100644 index 0000000..965856f --- /dev/null +++ b/docs/avatar-art/p3-linocut/base/edits/aligned-faceless-2.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\faceless-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\aligned-faceless-2.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.99256, + "transform": { + "scaleSqrtDet": 0.99996, + "rotationDeg": 0.001, + "translateX": -0.216, + "translateY": -0.467, + "matrix": [ + [ + 1.000085, + -2.1e-05, + -0.216023 + ], + [ + 2.1e-05, + 0.999836, + -0.467444 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 886543, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 170619 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 6490 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 378, + 445, + 527, + 530 + ], + "refInkRatio": 0.2204, + "editedInkRatio": 0.0136 + }, + "eyeB": { + "box": [ + 605, + 425, + 753, + 511 + ], + "refInkRatio": 0.1909, + "editedInkRatio": 0.0 + }, + "browA": { + "box": [ + 331, + 367, + 536, + 473 + ], + "refInkRatio": 0.3156, + "editedInkRatio": 0.2181 + }, + "browB": { + "box": [ + 580, + 348, + 791, + 443 + ], + "refInkRatio": 0.1773, + "editedInkRatio": 0.0956 + }, + "mouth": { + "box": [ + 470, + 662, + 692, + 785 + ], + "refInkRatio": 0.0531, + "editedInkRatio": 0.0001 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 378, + 445, + 527, + 530 + ], + "eyeB": [ + 605, + 425, + 753, + 511 + ], + "browA": [ + 331, + 367, + 536, + 473 + ], + "browB": [ + 580, + 348, + 791, + 443 + ], + "mouth": [ + 470, + 662, + 692, + 785 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p3-linocut/base/edits/sheet.jpg b/docs/avatar-art/p3-linocut/base/edits/sheet.jpg new file mode 100644 index 0000000..5cf87cc Binary files /dev/null and b/docs/avatar-art/p3-linocut/base/edits/sheet.jpg differ diff --git a/docs/avatar-art/p3-linocut/base/normalize.json b/docs/avatar-art/p3-linocut/base/normalize.json new file mode 100644 index 0000000..600851d --- /dev/null +++ b/docs/avatar-art/p3-linocut/base/normalize.json @@ -0,0 +1,66 @@ +{ + "canvas": { + "w": 1005, + "h": 1566 + }, + "reference": { + "image": "docs\\avatar-art\\p1-linocut\\base\\base-front.png", + "eyesCenter": [ + 492.69, + 584.33 + ], + "chin": [ + 500.61, + 919.55 + ], + "eyeDistance": 215.427, + "eyeChinDistance": 335.308 + }, + "input": { + "front": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\source-front.png", + "faceless": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\aligned-faceless-1.png", + "body": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\base\\edits\\aligned-body-1.png", + "frontSize": [ + 1145, + 1374 + ], + "eyesCenter": [ + 565.52, + 484.33 + ], + "chin": [ + 590.16, + 868.28 + ], + "eyeDistance": 226.984, + "eyeChinDistance": 384.738 + }, + "transform": { + "sHead": 0.910305, + "sWidth": 0.877729, + "s": 0.910305, + "rotationDeg": 0.0, + "offsetXNatural": -22.104, + "offsetXClampRange": [ + -37.299, + 0.0 + ], + "offsetX": -22.104, + "offsetY": 143.442 + }, + "coveredRange": { + "x": [ + 0.0, + 1005 + ], + "y": [ + 143.4, + 1394.2 + ] + }, + "inputSha256": { + "front": "00b8d9c3f930dd94798fa41e66fac08be58d9c493ae66284cef460e690f25bd8", + "faceless": "ce66bd0c2ecfcc09f853bba77197cace6e74da03035316519dd16010c928c8ff", + "body": "fbaba0b506a3b0fe868a63caa3f36fd2a1947f2965a0b2c6508f3152d2e8b5ba" + } +} \ No newline at end of file diff --git a/docs/avatar-art/p3-linocut/manifest.json b/docs/avatar-art/p3-linocut/manifest.json new file mode 100644 index 0000000..8972956 --- /dev/null +++ b/docs/avatar-art/p3-linocut/manifest.json @@ -0,0 +1,1258 @@ +{ + "landmarks": { + "coordSystem": "screen (image pixel: x=0 좌측, y=0 상단; left=작은 x, right=큰 x; 인물 해부학적 좌우 아님)", + "eyeLeft": { + "innerCorner": [ + 435.06, + 593.75 + ], + "outerCorner": [ + 346.29, + 589.44 + ], + "upperLidTop": [ + 382.51, + 570.06 + ], + "lowerLidBottom": [ + 386.71, + 602.25 + ], + "iris": { + "center": [ + 394.43, + 584.74 + ], + "radius": 20.58 + } + }, + "eyeRight": { + "innerCorner": [ + 552.12, + 583.64 + ], + "outerCorner": [ + 640.75, + 564.73 + ], + "upperLidTop": [ + 600.78, + 552.08 + ], + "lowerLidBottom": [ + 601.04, + 583.93 + ], + "iris": { + "center": [ + 596.13, + 567.87 + ], + "radius": 20.39 + } + }, + "eyebrowLeft": { + "inner": [ + 437.98, + 513.19 + ], + "peak": [ + 354.9, + 519.79 + ], + "outer": [ + 312.02, + 530.82 + ] + }, + "eyebrowRight": { + "inner": [ + 521.26, + 505.36 + ], + "peak": [ + 609.3, + 496.5 + ], + "outer": [ + 654.74, + 500.99 + ] + }, + "noseTip": [ + 499.58, + 704.43 + ], + "mouthCornerLeft": [ + 432.63, + 803.41 + ], + "mouthCornerRight": [ + 583.64, + 792.2 + ], + "upperLipTopCenter": [ + 505.16, + 769.79 + ], + "lowerLipBottomCenter": [ + 509.44, + 832.35 + ], + "chinTip": [ + 518.27, + 935.21 + ], + "faceWidthAtEyeLevelLeft": [ + 271.58, + 658.08 + ], + "faceWidthAtEyeLevelRight": [ + 727.33, + 621.97 + ] + }, + "landmarkDetector": "mediapipe FaceLandmarker (tasks) 1.0.1, model=face_landmarker(float16, v1)", + "pipelineRun": { + "persona": "P3", + "timestamp": "2026-10-01T22:00:44", + "completed": true, + "stages": [ + { + "stage": "brow_sprite", + "ok": true, + "elapsedSec": 2.67 + }, + { + "stage": "paper_grain", + "ok": true, + "elapsedSec": 2.44 + }, + { + "stage": "lip_texture", + "ok": true, + "elapsedSec": 2.24 + }, + { + "stage": "jaw_pieces", + "ok": true, + "elapsedSec": 5.76 + }, + { + "stage": "export_rig", + "ok": true, + "elapsedSec": 15.14 + }, + { + "stage": "final_previews", + "ok": true, + "elapsedSec": 19.25 + } + ] + }, + "schemaVersion": "vignette.avatar.v3.layers.v1", + "persona": "P3", + "canvas": { + "w": 1005, + "h": 1566 + }, + "base": { + "front": "base/base-front.png", + "faceless": "base/base-faceless.png", + "facelessPadded": "base/base-faceless-padded.png", + "facelessSize": [ + 1005, + 1566 + ], + "padNote": "base-faceless.png 마지막 행을 0번 복제해 1005x1566(base-front.png 크기)으로 패딩한 것이 F다." + }, + "segmenter": { + "model": "selfie_multiclass_256x256.tflite (mediapipe ImageSegmenter, storage.googleapis.com)", + "categories": { + "0": "background", + "1": "hair", + "2": "bodySkin", + "3": "faceSkin", + "4": "clothes", + "5": "others" + }, + "categoryPixelCounts": { + "0": 559937, + "1": 207575, + "2": 71269, + "3": 219079, + "4": 515826, + "5": 144 + }, + "hairEdgeRefine": { + "dilatePx": 6, + "lumThreshold": 110, + "addedPixels": 10285 + } + }, + "chinLine": { + "landmarkIndex": 152, + "xy": [ + 518.27, + 935.21 + ], + "marginPx": 8, + "cutY": 943.21 + }, + "faceOval": { + "landmarkLoop": [ + 10, + 338, + 297, + 332, + 284, + 251, + 389, + 356, + 454, + 323, + 361, + 288, + 397, + 365, + 379, + 378, + 400, + 377, + 152, + 148, + 176, + 149, + 150, + 136, + 172, + 58, + 132, + 93, + 234, + 127, + 162, + 21, + 54, + 103, + 67, + 109 + ], + "scale": 1.04, + "sourceImage": "base/base-front.png" + }, + "layers": [ + { + "id": "body", + "file": "layers/body.png", + "source": "base-faceless-masked+regenerated-fill", + "alphaBBox": [ + 0, + 848, + 1005, + 1566 + ], + "opaquePixels": 609331, + "greenResidue": 0, + "fillTargetPixels": 35617, + "fillSourceRaw": "raw/body.png (rejected 재생성이 아니라 수용된 body.png의 크로마키 결과; head/hairFront와 달리 body 재생성은 승인됨)" + }, + { + "id": "head", + "file": "layers/head.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 152, + 155, + 870, + 1044 + ], + "opaquePixels": 425507, + "greenResidue": 0 + }, + { + "id": "hairFront", + "file": "layers/hairFront.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 255, + 398, + 739, + 941 + ], + "opaquePixels": 24248, + "greenResidue": 0 + } + ], + "rejectedRawEdits": { + "body": { + "file": "raw/body.png", + "status": "accepted-as-fill-source", + "reason": "정렬 (0,0), 형태 변형 없음 — head_mask 채움 전용 소스로 재사용" + } + }, + "composite": { + "meanAbsDiff": { + "full": 1.9005205983704294, + "face": 0.49715101986881705, + "hairOutline": 11.53726341942018 + }, + "target": { + "full": 3.0, + "pass": true + }, + "backgroundNote": "카테고리0(배경)은 종이결 텍스처 노이즈(표준편차 ~29/채널)를 포함해 평탄한 크림(#EEE5D3)과 자체적으로 평균절대차 ~7 차이가 난다." + }, + "browCenterline": { + "method": "Otsu(front lum in bbox) AND diff(F-front)>=25, morphological closing to merge hatching, single global degree-2 polyfit on column-weighted centroid with one-pass outlier removal", + "diffThresh": 25.0, + "bboxPad": { + "x": 25.0, + "yUp": 42.0, + "yDown": 14.0 + }, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "outlierStdMult": 2.0, + "edgeInsetFrac": 0.03, + "peakWindow": [ + 0.25, + 0.6 + ], + "peakFallbackFrac": 0.35, + "peakFlatHeightPx": 3.0, + "peakFailEdgeFrac": 0.2, + "oldPoints": { + "browLeft": { + "inner": [ + 443.39, + 528.19 + ], + "peak": [ + 388.1, + 499.38 + ], + "outer": [ + 303.13, + 541.4 + ] + }, + "browRight": { + "inner": [ + 528.36, + 521.71 + ], + "peak": [ + 617.58, + 482.54 + ], + "outer": [ + 673.41, + 510.91 + ] + } + }, + "newPoints": { + "browLeft": { + "name": "browLeft", + "bbox": [ + 278, + 457, + 468, + 555 + ], + "otsuThresh": 109.0, + "colRange": [ + 308, + 442 + ], + "width": 134.0, + "nColumns": 127, + "nOutliersRemoved": 10, + "fitCoeffs": [ + 0.0014127, + -1.19951702, + 767.56190241 + ], + "inner": [ + 437.98, + 513.19 + ], + "peak": [ + 354.9, + 519.79 + ], + "outer": [ + 312.02, + 530.82 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.9055, + "checkA_pass": true, + "halfWidthInner": 6.995, + "halfWidthPeak": 8.34, + "halfWidthOuter": 3.812, + "bandX0": 278, + "bandY0": 457, + "colMin": 308, + "colMax": 442 + }, + "browRight": { + "name": "browRight", + "bbox": [ + 503, + 441, + 698, + 536 + ], + "otsuThresh": 113.0, + "colRange": [ + 517, + 659 + ], + "width": 142.0, + "nColumns": 143, + "nOutliersRemoved": 6, + "fitCoeffs": [ + 0.00149431, + -1.79001855, + 1032.39992065 + ], + "inner": [ + 521.26, + 505.36 + ], + "peak": [ + 609.3, + 496.5 + ], + "outer": [ + 654.74, + 500.99 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.8951, + "checkA_pass": true, + "halfWidthInner": 3.896, + "halfWidthPeak": 6.997, + "halfWidthOuter": 1.973, + "bandX0": 503, + "bandY0": 441, + "colMin": 517, + "colMax": 659 + } + }, + "halfWidthLeft": [ + 6.995, + 8.34, + 3.812 + ], + "halfWidthRight": [ + 3.896, + 6.997, + 1.973 + ], + "halfWidthNote": "원화 눈썹 잉크 띠 반두께[inner,peak,outer](px, 중심선 법선 방향). export_rig.py가 persona.json browHalfWidthFromArt!=false(기본)면 RigBrow.halfWidth로 내보낸다.", + "checkB_innerMinusPeakY": { + "browLeft": -6.6, + "browRight": 8.86 + }, + "checkD_symmetry": { + "innerYDiff": 7.83, + "peakYDiff": 23.29 + }, + "evidenceImage": "preview/v2/brow-centerline.jpg" + }, + "layersV2": { + "chinBandFix": { + "targetRegionPixels": 15342, + "sourceBandHeight": 150, + "rowJitterRange": [ + -2.0, + 2.0 + ], + "rngSeed": 20260930 + }, + "hairEdgeFix": { + "bandOuterPx": 40, + "bandInnerPx": 6, + "lumSmoothstep": [ + 205.0, + 150.0 + ], + "minFragmentAreaPx": 60, + "head": { + "bandOuterPixels": 102178, + "bandInnerPixels": 41504, + "componentsBefore": 175, + "removed": 170, + "removedPixels": 963 + }, + "hairFront": { + "bandOuterPixels": 6606, + "bandInnerPixels": 16598, + "componentsBefore": 191, + "removed": 179, + "removedPixels": 536 + } + }, + "hairPaperGapFix": { + "regionDilatePx": 6, + "paperColorDistThreshold": 40.0, + "paperLumThreshold": 195.0, + "paperSatThreshold": 40.0, + "opaqueAlphaThreshold": 0.95, + "regionPixels": 230717, + "head": { + "targetPixels": 821, + "componentsBefore": 5, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + }, + "hairFront": { + "targetPixels": 0, + "componentsBefore": 12, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + } + }, + "jawInkFix": { + "mouthCenterY": 796.4, + "distThresholdPx": 14.0, + "mergePx": 3, + "aspectThreshold": 1.0, + "removedGroups": [ + { + "pixels": 838, + "bbox": [ + 554, + 900, + 608, + 942 + ], + "width": 54, + "height": 42, + "aspect": 1.286 + } + ], + "keptGroups": [ + { + "pixels": 2419, + "bbox": [ + 288, + 797, + 388, + 898 + ], + "width": 100, + "height": 101, + "aspect": 0.99 + }, + { + "pixels": 1884, + "bbox": [ + 634, + 797, + 714, + 884 + ], + "width": 80, + "height": 87, + "aspect": 0.92 + }, + { + "pixels": 84, + "bbox": [ + 434, + 924, + 444, + 934 + ], + "width": 10, + "height": 10, + "aspect": 1.0 + } + ], + "removedPixels": 838, + "strayFragmentCleanup": { + "componentsBefore": 11, + "removed": 0, + "removedPixels": 0 + } + }, + "metrics": { + "body": { + "haloPct": 0.17023346303501946 + }, + "head": { + "haloPct": 0.0, + "bgLeakAlphaMean": 0.0, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + }, + "hairFront": { + "haloPct": 0.06115272894052897, + "bgLeakAlphaMean": 0.0, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + } + }, + "layers": [ + { + "id": "body", + "bbox": [ + 0, + 848, + 1005, + 1566 + ], + "opaque": 609284, + "greenResidue": 0 + }, + { + "id": "head", + "bbox": [ + 132, + 156, + 874, + 1044 + ], + "opaque": 438690, + "greenResidue": 1 + }, + { + "id": "hairFront", + "bbox": [ + 237, + 398, + 777, + 933 + ], + "opaque": 29897, + "greenResidue": 1 + } + ], + "faceDetail": { + "browLandmarksSource": "manifest.landmarks.eyebrowLeft/Right", + "region": "face", + "faceInsetPx": 24.0, + "matchFacelessColor": true, + "matchFacelessColorDeltaRgb": { + "eyeLeft": [ + -11.32, + -12.21, + -12.78 + ], + "eyeRight": [ + -10.52, + -12.16, + -13.3 + ], + "browLeft": [ + -0.25, + 1.09, + 1.48 + ], + "browRight": [ + -0.9, + -0.03, + -0.07 + ], + "mouth": [ + -3.26, + -3.73, + -4.96 + ] + }, + "regions": { + "eyeLeft": [ + 316.3, + 509.8, + 460.1, + 672.2 + ], + "eyeRight": [ + 527.1, + 486.5, + 670.8, + 653.9 + ], + "mouth": [ + 387.6, + 729.4, + 628.6, + 920.2 + ], + "moles": [] + }, + "exclusionPixels": { + "eyeLeft": 11485, + "eyeRight": 10642, + "browLeft": 11017, + "browRight": 9084, + "mouth": 18995, + "union": 58172 + }, + "hairMaskPixels": 225679, + "bbox": [ + 279, + 397, + 722, + 939 + ], + "textureCloneStamp": { + "cloneTargetThreshold": 65.0, + "avoidThreshold": 110.0, + "lineOpeningIterations": 3, + "featherPx": 4.0, + "badTexturePixels": 5, + "preservedShadowPixels": 0, + "components": [ + { + "componentId": 1, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 2, + "pixels": 1, + "offset": [ + -100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 3, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 4, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 5, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + } + ] + }, + "genericPatches": { + "forehead": [ + 468, + 398, + 516, + 446 + ], + "cheekLeft": [ + 326, + 650, + 374, + 698 + ], + "cheekRight": [ + 519, + 631, + 567, + 679 + ] + }, + "genericPatchBaseline": { + "highFreqEnergy": 10.784726068172136, + "lineEnergy": 3.811262288996353 + }, + "checkA_meanAbsDiff": 0.41166174567512276, + "checkB_seamLumDiff": 0.06290680428432438, + "checkC_holeDarkResiduePct": 0.03185918241373131, + "checkC_violationPixels": 16, + "checkD_texturePreservation": { + "eyeLeft": { + "insideEnergy": 9.147273470585267, + "baselineEnergy": 10.784726068172136, + "ratio": 0.8481692917153162, + "pass": true + }, + "eyeRight": { + "insideEnergy": 9.392379443644488, + "baselineEnergy": 10.784726068172136, + "ratio": 0.8708964311447152, + "pass": true + }, + "browLeft": { + "insideEnergy": 11.064785620046433, + "baselineEnergy": 10.784726068172136, + "ratio": 1.0259681655430088, + "pass": true + }, + "browRight": { + "insideEnergy": 11.025329524088622, + "baselineEnergy": 10.784726068172136, + "ratio": 1.0223096492572543, + "pass": true + }, + "mouth": { + "insideEnergy": 9.73095282876833, + "baselineEnergy": 10.784726068172136, + "ratio": 0.9022902174109272, + "pass": true + } + }, + "checkD_allPass": true, + "checkE_ghostOutline": { + "eyeLeft": { + "bandLineEnergy": 5.365413565857688, + "baselineLineEnergy": 3.811262288996353, + "ratio": 1.4077786200515212, + "pass": true + }, + "eyeRight": { + "bandLineEnergy": 5.572405832019536, + "baselineLineEnergy": 3.811262288996353, + "ratio": 1.4620893051910517, + "pass": true + }, + "browLeft": { + "bandLineEnergy": 4.320421303108777, + "baselineLineEnergy": 3.811262288996353, + "ratio": 1.1335932757980045, + "pass": true + }, + "browRight": { + "bandLineEnergy": 4.382619320579252, + "baselineLineEnergy": 3.811262288996353, + "ratio": 1.149912807951446, + "pass": true + }, + "mouth": { + "bandLineEnergy": 3.0566944722024156, + "baselineLineEnergy": 3.811262288996353, + "ratio": 0.8020162981245137, + "pass": true + } + }, + "checkE_allPass": true, + "checkDarkCircle": { + "eyeLeft": { + "compositeMean": 145.38990476190475, + "frontMean": 145.17142857142855, + "diff": 0.2184761904761956, + "pass": true + }, + "eyeRight": { + "compositeMean": 145.47980952380954, + "frontMean": 145.4384761904762, + "diff": 0.041333333333341216, + "pass": true + } + }, + "checkDarkCircle_allPass": true + }, + "paperGrain": { + "sourceImage": "base/base-front.png", + "sourceOrigin": [ + 739, + 10 + ], + "tileSize": 256, + "personMarginPx": 20, + "cleanFraction": 0.9979400634765625, + "contaminatedPixelsFilled": 135, + "chromaKeep": 0.3, + "targetLumRange": [ + 245.0, + 250.0 + ], + "lumShift": 23.88299560546875, + "finalMeanLum": 247.47297462295472, + "finalLumStd": 2.194378158845552, + "seamContinuity": { + "leftRightDiff": 0.1583767181773131, + "topBottomDiff": 0.03202277288771901 + } + } + }, + "lipTexture": { + "designVersion": "A5(아랫입술 그늘 띠를 lip-shadow 조각으로 분리)", + "landmarks": { + "mouthCornerLeft": [ + 432.63, + 803.41 + ], + "mouthCornerRight": [ + 583.64, + 792.2 + ], + "upperLipTop": [ + 505.16, + 769.79 + ], + "lowerLipBottom": [ + 509.44, + 832.35 + ], + "mouthCenter": [ + 507.2048154473305, + 796.4007625579834 + ] + }, + "capBBox": [ + 427.13, + 766.07, + 589.13, + 836.07 + ], + "otsuThreshLabA": 139.0, + "diffThresh": 20.0, + "dilatePx": 10.0, + "alphaRampPx": 4.0, + "splitOverlapPx": 2.0, + "shadowBandPx": 18.0, + "shadowTopOverlapPx": 6.0, + "shadowSideRampPx": 6.0, + "shadowTopRampPx": 4.0, + "checks": { + "lip-upper": { + "regionPixelCount": 5597, + "fullOpacityPixelCount": 4832, + "rampPixelCount": 765, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 37, + 30, + 173, + 51 + ] + }, + "lip-lower": { + "regionPixelCount": 6060, + "fullOpacityPixelCount": 5346, + "rampPixelCount": 714, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 36, + 66, + 171, + 54 + ] + }, + "lip-shadow": { + "regionPixelCount": 3552, + "fullOpacityPixelCount": 1953, + "rampPixelCount": 1599, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 46, + 65, + 148, + 63 + ] + }, + "splitOverlapPixelCount": 339, + "splitOverlapBandOk": true, + "splitOverlapAlphaMaxDiff": 0, + "splitOverlapConsistentOk": true, + "splitCoverageMismatchPixelCount": 0, + "splitCheckOk": true, + "shadowLowerOverlapPixelCount": 2593, + "shadowLowerOverlapMaxDiff": 15.339100346020729, + "shadowLowerOverlapDiffGt1PixelCount": 115, + "shadowLowerOverlapOk": false + }, + "check3NeutralComposite": { + "fullOpacityMaxDiff": 0.0, + "rampMeanAbsDiff": 7.457, + "mouthBBoxMeanAbsDiff": 1.516 + }, + "pngFileSizes": { + "lip-upper": 23244, + "lip-lower": 24183, + "lip-shadow": 24527 + }, + "canvasOrigin": { + "upper": [ + 424, + 756 + ], + "lower": [ + 423, + 792 + ], + "shadow": [ + 433, + 791 + ] + }, + "evidenceImage": "preview/v2/lip-texture.jpg", + "check4WebpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jaw": { + "designVersion": "A5(결정문 §8.4 하관 띠 변형 — 턱 조각 원본)", + "noseTip": [ + 499.58, + 704.43 + ], + "chinTip": [ + 518.27, + 935.21 + ], + "yFormula": "noseTip.y - 50 - 10 .. chinTip.y + 40", + "noseToTopPx": 60.0, + "chinToBottomPx": 40.0, + "ovalOutsetPx": 18.0, + "faceOvalSource": "export_rig.detect_face_landmarks + compute_face_oval(base-front.png, 결정적)", + "bboxCanvas": [ + 243, + 644, + 755, + 976 + ], + "naiveXRangeForComparison": [ + 243, + 755 + ], + "checks": { + "head": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 381852 + }, + "detail": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 416090 + } + }, + "evidenceImage": "preview/v2/jaw-pieces.jpg", + "check1VsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 3.222, + "maxAbsDiffPremultipliedRgb": 38.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.885, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 15788, + "lip-lower": 16602, + "lip-shadow": 17250 + }, + "totalBytes": 49640, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 46270, + "jaw-detail": 25322 + }, + "totalBytes": 71592, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 3.222, + "maxAbsDiffPremultipliedRgb": 38.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.885, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSprite": { + "enabled": true, + "bandExtraHalfHeightPx": 8.0, + "bandEndExtendPx": 6.0, + "diffThresh": 25.0, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "hairSource": "layers/v2/hairFront.png alpha(게시되는 레이어 그 자체, 분할 카테고리 아님)", + "hairAlphaThresh": 128.0, + "hairDilateIterations": 1, + "rampPx": 1.5, + "inkLumMethod": "median(ink-classified pixels in band, region after hair removal)", + "minAlphaForUnmix": 0.05, + "hairMaskPixelCount": 36954, + "left": { + "bboxCanvas": [ + 314, + 502, + 129, + 38 + ], + "halfHeightPx": 16.34, + "otsuThresh": 111.0, + "lSkin": 181.667, + "lInk": 46.667, + "regionPixelCount": 1559, + "hairOverlapPixelCount": 183, + "neutralCompositeMeanAbsDiffAlphaRegion": 8.002, + "pngFileSizeBytes": 6225 + }, + "right": { + "bboxCanvas": [ + 517, + 486, + 142, + 32 + ], + "halfHeightPx": 14.997, + "otsuThresh": 117.0, + "lSkin": 181.0, + "lInk": 48.833, + "regionPixelCount": 1750, + "hairOverlapPixelCount": 8, + "neutralCompositeMeanAbsDiffAlphaRegion": 6.26, + "pngFileSizeBytes": 6292 + }, + "canvasOrigin": { + "left": [ + 314.0, + 502.0 + ], + "right": [ + 517.0, + 486.0 + ] + }, + "evidenceImage": "preview/v2/brow-sprite.jpg", + "checkWebpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "eyeLineScale": { + "enabled": true, + "method": "눈 폭 가운데 60% 열마다 upperLidTop.y-12 ~ 홍채중심y 사이 첫 연속 어두운(lum<80) 구간 길이의 중앙값", + "windowAbovePx": 12.0, + "darkLumThresh": 80.0, + "columnMiddleFrac": 0.6, + "p1BaselinePx": 2.0, + "lineScaleClampRange": [ + 1.0, + 2.5 + ], + "left": { + "measuredPx": 1.5, + "nColumns": 54, + "ratio": 0.75, + "lineScale": 1.0 + }, + "right": { + "measuredPx": 2.0, + "nColumns": 54, + "ratio": 1.0, + "lineScale": 1.0 + } + }, + "iris": { + "method": "가로: 중심 y 부근 상하 각 4행에서 중심 x를 포함하는 연속 어두운(lum<100) 구간의 중앙값으로 반지름·중심x. 세로: 중심 x 부근 좌우 각 4열에서 중심 y를 포함하는 연속 어두운 구간의 아래쪽 끝 중앙값에서 가로 반지름을 빼 중심y(세로축은 윗눈꺼풀 잉크와 홍채가 같은 톤으로 이어져 위쪽 경계를 가를 수 없다).", + "darkLumThresh": 100.0, + "scanBandPx": 4, + "left": { + "measuredCenter": [ + 389.0, + 580.0 + ], + "measuredRadius": 20.0, + "rigCenter": [ + 394.43, + 584.74 + ], + "rigRadius": 20.58, + "nRowsHorizontal": 9, + "nColsVertical": 9 + }, + "right": { + "measuredCenter": [ + 593.5, + 558.5 + ], + "measuredRadius": 19.5, + "rigCenter": [ + 596.13, + 567.87 + ], + "rigRadius": 20.39, + "nRowsHorizontal": 9, + "nColsVertical": 9 + } + }, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 3972, + "brow-right": 3772 + }, + "totalBytes": 7744, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p3-linocut/persona.json b/docs/avatar-art/p3-linocut/persona.json new file mode 100644 index 0000000..20305ad --- /dev/null +++ b/docs/avatar-art/p3-linocut/persona.json @@ -0,0 +1,32 @@ +{ + "code": "P3", + "publicSlug": "p3", + "styleFrame": "../art-direction-v3/p1/r2-b-linocut.png", + "paletteSamples": { + "ink": { "box": [430, 200, 580, 320], "lumThreshold": 55 }, + "motifPetalBoxes": [ + { "label": "sun", "kind": "ochre", "box": [1230, 10, 1536, 210] }, + { "label": "tulip", "kind": "ochre", "box": [1030, 280, 1170, 560] } + ], + "motifLeafBoxes": [ + { "label": "cloudLeft", "kind": "blue", "box": [20, 20, 380, 190] }, + { "label": "raincloud", "kind": "blue", "box": [520, 10, 930, 230] }, + { "label": "wiltedFlowerLeaf", "kind": "blue", "box": [520, 280, 650, 580] }, + { "label": "closedBudLeaf", "kind": "blue", "box": [10, 290, 110, 570] } + ] + }, + "faceDetail": { + "moles": [], + "region": "face", + "faceInsetPx": 24, + "matchFacelessColor": true + }, + "pivots": { + "neck": [518, 1005], + "body": [502, 1566], + "face": [492, 652] + }, + "crops": { + "bustYOffset": 40 + } +} diff --git a/docs/avatar-art/p3-linocut/preview/qa/face-art-vs-render.jpg b/docs/avatar-art/p3-linocut/preview/qa/face-art-vs-render.jpg new file mode 100644 index 0000000..4876e6c Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/qa/face-art-vs-render.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/qa/face-zoom.jpg b/docs/avatar-art/p3-linocut/preview/qa/face-zoom.jpg new file mode 100644 index 0000000..ae8785d Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/qa/face-zoom.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/qa/neutral-vs-art.jpg b/docs/avatar-art/p3-linocut/preview/qa/neutral-vs-art.jpg new file mode 100644 index 0000000..9ea9460 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/qa/neutral-vs-art.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/qa/normalized.jpg b/docs/avatar-art/p3-linocut/preview/qa/normalized.jpg new file mode 100644 index 0000000..2fc9880 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/qa/normalized.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/qa/sheet-expr-bust.jpg b/docs/avatar-art/p3-linocut/preview/qa/sheet-expr-bust.jpg new file mode 100644 index 0000000..c61e195 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/qa/sheet-expr-bust.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/qa/sheet-expr-face.jpg b/docs/avatar-art/p3-linocut/preview/qa/sheet-expr-face.jpg new file mode 100644 index 0000000..c37e95f Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/qa/sheet-expr-face.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/qa/sheet-viseme.jpg b/docs/avatar-art/p3-linocut/preview/qa/sheet-viseme.jpg new file mode 100644 index 0000000..6146d6d Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/qa/sheet-viseme.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/qa/viseme-timeline.json b/docs/avatar-art/p3-linocut/preview/qa/viseme-timeline.json new file mode 100644 index 0000000..2c5e4b0 --- /dev/null +++ b/docs/avatar-art/p3-linocut/preview/qa/viseme-timeline.json @@ -0,0 +1,287 @@ +[ + { + "t": 0, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00000.png" + }, + { + "t": 50, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00050.png" + }, + { + "t": 100, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00100.png" + }, + { + "t": 150, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00150.png" + }, + { + "t": 200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00200.png" + }, + { + "t": 250, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00250.png" + }, + { + "t": 300, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00300.png" + }, + { + "t": 350, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00350.png" + }, + { + "t": 400, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00400.png" + }, + { + "t": 450, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00450.png" + }, + { + "t": 500, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00500.png" + }, + { + "t": 550, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00550.png" + }, + { + "t": 600, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00600.png" + }, + { + "t": 650, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00650.png" + }, + { + "t": 700, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00700.png" + }, + { + "t": 750, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00750.png" + }, + { + "t": 800, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00800.png" + }, + { + "t": 850, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00850.png" + }, + { + "t": 900, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00900.png" + }, + { + "t": 950, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t00950.png" + }, + { + "t": 1000, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01000.png" + }, + { + "t": 1050, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01050.png" + }, + { + "t": 1100, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01100.png" + }, + { + "t": 1150, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01150.png" + }, + { + "t": 1200, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01200.png" + }, + { + "t": 1250, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01250.png" + }, + { + "t": 1300, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01300.png" + }, + { + "t": 1350, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01350.png" + }, + { + "t": 1400, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01400.png" + }, + { + "t": 1450, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01450.png" + }, + { + "t": 1500, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01500.png" + }, + { + "t": 1550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01550.png" + }, + { + "t": 1600, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01600.png" + }, + { + "t": 1650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01650.png" + }, + { + "t": 1700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01700.png" + }, + { + "t": 1750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01750.png" + }, + { + "t": 1800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01800.png" + }, + { + "t": 1850, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01850.png" + }, + { + "t": 1900, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01900.png" + }, + { + "t": 1950, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t01950.png" + }, + { + "t": 2000, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02000.png" + }, + { + "t": 2050, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02050.png" + }, + { + "t": 2100, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02100.png" + }, + { + "t": 2150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02150.png" + }, + { + "t": 2200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02200.png" + }, + { + "t": 2250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02250.png" + }, + { + "t": 2300, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02300.png" + }, + { + "t": 2350, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02350.png" + }, + { + "t": 2400, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02400.png" + }, + { + "t": 2450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02450.png" + }, + { + "t": 2500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02500.png" + }, + { + "t": 2550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02550.png" + }, + { + "t": 2600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02600.png" + }, + { + "t": 2650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02650.png" + }, + { + "t": 2700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02700.png" + }, + { + "t": 2750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02750.png" + }, + { + "t": 2800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p3-linocut\\preview\\qa\\frames\\viseme-scan-t02800.png" + } +] \ No newline at end of file diff --git a/docs/avatar-art/p3-linocut/preview/v2/brow-centerline.jpg b/docs/avatar-art/p3-linocut/preview/v2/brow-centerline.jpg new file mode 100644 index 0000000..55a5a63 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/v2/brow-centerline.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/v2/brow-sprite.jpg b/docs/avatar-art/p3-linocut/preview/v2/brow-sprite.jpg new file mode 100644 index 0000000..1dd0d81 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/v2/brow-sprite.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/v2/export-rig-report.json b/docs/avatar-art/p3-linocut/preview/v2/export-rig-report.json new file mode 100644 index 0000000..5ccf791 --- /dev/null +++ b/docs/avatar-art/p3-linocut/preview/v2/export-rig-report.json @@ -0,0 +1,676 @@ +{ + "faceOvalBBox": [ + 257.2, + 390.2, + 736.4, + 945.4 + ], + "cropsFace": [ + 185.9, + 356.9, + 621.9, + 621.9 + ], + "mouthCenter": [ + 507.2, + 796.4 + ], + "palette": { + "ink": "#242322", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#B4835D", + "lipLower": "#BD8A62", + "mouthLine": "#76553F", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "paletteSamples": { + "eyeLeft": { + "sclera": "#D2A373", + "iris": "#43382C", + "irisRing": "#725C45", + "n": { + "sclera": 968, + "iris": 191, + "irisRing": 392 + } + }, + "eyeRight": { + "sclera": "#D3A778", + "iris": "#513F2F", + "irisRing": "#47392D", + "n": { + "sclera": 961, + "iris": 189, + "irisRing": 383 + } + }, + "scleraIrisIrisRingFixedOverride": { + "reason": "persona.json paletteSamples.eyeOverride(고정 설계값)", + "measured": { + "sclera": "#D2A576", + "iris": "#4A3C2E", + "irisRing": "#5C4A39" + }, + "fixed": { + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F" + } + }, + "ink": { + "box": [ + 430, + 200, + 580, + 320 + ], + "lumThreshold": 55.0, + "n": 13942, + "hex": "#242322" + }, + "lipUpper": { + "box": [ + 427, + 766, + 588, + 794 + ], + "hex": "#B4835D" + }, + "lipLower": { + "box": [ + 427, + 798, + 588, + 835 + ], + "hex": "#BD8A62" + }, + "mouthLine": { + "box": [ + 447, + 794, + 568, + 799 + ], + "hex": "#76553F" + }, + "motifPetal": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "sun": { + "box": [ + 1230, + 10, + 1536, + 210 + ], + "n": 20570, + "hex": "#D3A661" + }, + "tulip": { + "box": [ + 1030, + 280, + 1170, + 560 + ], + "n": 4314, + "hex": "#CCA063" + } + }, + "hex": "#D0A362" + }, + "motifLeaf": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "cloudLeft": { + "box": [ + 20, + 20, + 380, + 190 + ], + "n": 21312, + "hex": "#636D76" + }, + "raincloud": { + "box": [ + 520, + 10, + 930, + 230 + ], + "n": 27607, + "hex": "#586B76" + }, + "wiltedFlowerLeaf": { + "box": [ + 520, + 280, + 650, + 580 + ], + "n": 5818, + "hex": "#495961" + }, + "closedBudLeaf": { + "box": [ + 10, + 290, + 110, + 570 + ], + "n": 6589, + "hex": "#495961" + } + }, + "hex": "#53626C" + } + }, + "publish": { + "fileSizes": { + "body": 196976, + "head": 138282, + "hair-front": 32594, + "face-detail": 45922, + "paper-grain": 980 + }, + "encodeMeta": { + "quality": 80, + "scale": 1.0, + "totalBytes": 414754 + }, + "totalBytes": 414754 + }, + "grain": { + "href": "/avatar/v3/p3/paper-grain.webp", + "size": 256 + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 15788, + "lip-lower": 16602, + "lip-shadow": 17250 + }, + "totalBytes": 49640, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 46270, + "jaw-detail": 25322 + }, + "totalBytes": 71592, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 3.222, + "maxAbsDiffPremultipliedRgb": 38.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.885, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 3972, + "brow-right": 3772 + }, + "totalBytes": 7744, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "rig": { + "schemaVersion": "vignette.avatar.v3.rig.v1", + "persona": "P3", + "canvas": { + "w": 1005, + "h": 1566 + }, + "layers": { + "body": { + "href": "/avatar/v3/p3/body.webp", + "x": 0, + "y": 848, + "w": 1005, + "h": 718 + }, + "head": { + "href": "/avatar/v3/p3/head.webp", + "x": 132, + "y": 156, + "w": 742, + "h": 888 + }, + "hairFront": { + "href": "/avatar/v3/p3/hair-front.webp", + "x": 237, + "y": 398, + "w": 540, + "h": 535 + }, + "faceDetail": { + "href": "/avatar/v3/p3/face-detail.webp", + "x": 279, + "y": 397, + "w": 443, + "h": 542 + } + }, + "grain": { + "href": "/avatar/v3/p3/paper-grain.webp", + "size": 256 + }, + "lipTexture": { + "upper": { + "href": "/avatar/v3/p3/lip-upper.webp", + "x": 424, + "y": 756, + "w": 173, + "h": 51 + }, + "lower": { + "href": "/avatar/v3/p3/lip-lower.webp", + "x": 423, + "y": 792, + "w": 171, + "h": 54 + }, + "shadow": { + "href": "/avatar/v3/p3/lip-shadow.webp", + "x": 433, + "y": 791, + "w": 148, + "h": 63 + } + }, + "jaw": { + "head": { + "href": "/avatar/v3/p3/jaw-head.webp", + "x": 243, + "y": 644, + "w": 512, + "h": 332 + }, + "detail": { + "href": "/avatar/v3/p3/jaw-detail.webp", + "x": 243, + "y": 644, + "w": 512, + "h": 332 + } + }, + "motif": null, + "pivots": { + "neck": [ + 518, + 1005 + ], + "body": [ + 502, + 1566 + ], + "face": [ + 492, + 652 + ] + }, + "crops": { + "portrait": [ + 0, + 0, + 1005, + 1566 + ], + "bust": [ + 0.0, + 40.0, + 1005.0, + 1005.0 + ], + "face": [ + 185.87612950367526, + 356.8740379088401, + 621.8837808288575, + 621.8837808288575 + ] + }, + "faceOval": [ + [ + 475.8, + 393.7 + ], + [ + 540.7, + 390.2 + ], + [ + 596.5, + 395.8 + ], + [ + 649.6, + 413.2 + ], + [ + 685.4, + 442.2 + ], + [ + 709.3, + 480.3 + ], + [ + 724.7, + 521.2 + ], + [ + 733.9, + 571.8 + ], + [ + 736.4, + 619.7 + ], + [ + 736.4, + 669.4 + ], + [ + 731.0, + 722.5 + ], + [ + 718.2, + 777.9 + ], + [ + 698.5, + 822.4 + ], + [ + 674.5, + 854.4 + ], + [ + 643.8, + 883.5 + ], + [ + 618.4, + 904.1 + ], + [ + 591.4, + 922.9 + ], + [ + 559.9, + 938.4 + ], + [ + 519.0, + 945.4 + ], + [ + 477.9, + 944.3 + ], + [ + 445.2, + 933.5 + ], + [ + 416.7, + 919.2 + ], + [ + 389.2, + 903.2 + ], + [ + 355.4, + 879.7 + ], + [ + 328.1, + 851.8 + ], + [ + 302.7, + 811.3 + ], + [ + 282.3, + 758.0 + ], + [ + 269.2, + 706.1 + ], + [ + 262.4, + 657.2 + ], + [ + 257.2, + 610.1 + ], + [ + 258.2, + 560.0 + ], + [ + 266.7, + 517.2 + ], + [ + 283.8, + 476.0 + ], + [ + 312.7, + 441.9 + ], + [ + 359.0, + 416.0 + ], + [ + 411.7, + 401.4 + ] + ], + "landmarks": { + "eyeLeft": { + "inner": [ + 435.1, + 593.8 + ], + "outer": [ + 346.3, + 589.4 + ], + "upperLidTop": [ + 382.5, + 570.1 + ], + "lowerLidBottom": [ + 386.7, + 602.2 + ], + "iris": { + "center": [ + 389.0, + 580.0 + ], + "radius": 20.0 + }, + "lineScale": 1.0 + }, + "eyeRight": { + "inner": [ + 552.1, + 583.6 + ], + "outer": [ + 640.8, + 564.7 + ], + "upperLidTop": [ + 600.8, + 552.1 + ], + "lowerLidBottom": [ + 601.0, + 583.9 + ], + "iris": { + "center": [ + 593.5, + 558.5 + ], + "radius": 19.5 + }, + "lineScale": 1.0 + }, + "browLeft": { + "inner": [ + 438.0, + 513.2 + ], + "peak": [ + 354.9, + 519.8 + ], + "outer": [ + 312.0, + 530.8 + ], + "halfWidth": [ + 7.0, + 8.34, + 3.81 + ], + "sprite": { + "href": "/avatar/v3/p3/brow-left.webp", + "x": 314.0, + "y": 502.0, + "w": 129, + "h": 38 + } + }, + "browRight": { + "inner": [ + 521.3, + 505.4 + ], + "peak": [ + 609.3, + 496.5 + ], + "outer": [ + 654.7, + 501.0 + ], + "halfWidth": [ + 3.9, + 7.0, + 1.97 + ], + "sprite": { + "href": "/avatar/v3/p3/brow-right.webp", + "x": 517.0, + "y": 486.0, + "w": 142, + "h": 32 + } + }, + "noseTip": [ + 499.6, + 704.4 + ], + "mouthCornerLeft": [ + 432.6, + 803.4 + ], + "mouthCornerRight": [ + 583.6, + 792.2 + ], + "upperLipTop": [ + 505.2, + 769.8 + ], + "lowerLipBottom": [ + 509.4, + 832.4 + ], + "mouthCenter": [ + 507.2, + 796.4 + ], + "chinTip": [ + 518.3, + 935.2 + ] + }, + "palette": { + "ink": "#242322", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#B4835D", + "lipLower": "#BD8A62", + "mouthLine": "#76553F", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "backdrop": { + "cognitive": "#ECE3D1", + "positive": "#F1DEC2", + "negative": "#DCE0E2", + "defensive": "#E6DAD3", + "energy": "#E2E0D0" + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p3-linocut/preview/v2/ghost-check.jpg b/docs/avatar-art/p3-linocut/preview/v2/ghost-check.jpg new file mode 100644 index 0000000..cde7ae4 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/v2/ghost-check.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/v2/holes-texture.jpg b/docs/avatar-art/p3-linocut/preview/v2/holes-texture.jpg new file mode 100644 index 0000000..a8df071 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/v2/holes-texture.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/v2/jaw-pieces.jpg b/docs/avatar-art/p3-linocut/preview/v2/jaw-pieces.jpg new file mode 100644 index 0000000..b3ec278 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/v2/jaw-pieces.jpg differ diff --git a/docs/avatar-art/p3-linocut/preview/v2/lip-texture.jpg b/docs/avatar-art/p3-linocut/preview/v2/lip-texture.jpg new file mode 100644 index 0000000..3cd74a2 Binary files /dev/null and b/docs/avatar-art/p3-linocut/preview/v2/lip-texture.jpg differ diff --git a/docs/avatar-art/p3-linocut/prompts/base-faceless.txt b/docs/avatar-art/p3-linocut/prompts/base-faceless.txt new file mode 100644 index 0000000..8d095a7 --- /dev/null +++ b/docs/avatar-art/p3-linocut/prompts/base-faceless.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as faceless.png: + +Redraw exactly the same woman, same frontal pose, same framing and same linocut relief-print style as the reference, but leave the face blank: remove the eyes, eyebrows and mouth completely and fill those areas with plain skin in the same flat skin color, keeping the nose, the face outline, the ears, the hair, the neck, the low bun and the loose strands of hair, the cream t-shirt and the ochre knit sweater with its small pale stain exactly as they are. Do not move, resize or redraw anything else. Plain flat cream background, nothing else, no text. diff --git a/docs/avatar-art/p3-linocut/prompts/body.txt b/docs/avatar-art/p3-linocut/prompts/body.txt new file mode 100644 index 0000000..38d8836 --- /dev/null +++ b/docs/avatar-art/p3-linocut/prompts/body.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as body.png: + +Keep only the neck, the cream t-shirt and the ochre knit sweater, including the small pale stain near the shoulder exactly as they are in the reference: same shapes, same position, same linocut relief-print style, same ink colors and texture. Remove the head, the face, the ears and all of the hair completely. Where the hair or the chin previously covered the neck or the clothes, continue them naturally in the same style so there are no holes. Place the result on a plain flat pure green background (#00ff00) with nothing else, no text. diff --git a/docs/avatar-art/p3-linocut/raw/body.png b/docs/avatar-art/p3-linocut/raw/body.png new file mode 100644 index 0000000..0a15f43 Binary files /dev/null and b/docs/avatar-art/p3-linocut/raw/body.png differ diff --git a/docs/avatar-art/p4-linocut/base/base-faceless.png b/docs/avatar-art/p4-linocut/base/base-faceless.png new file mode 100644 index 0000000..496a940 Binary files /dev/null and b/docs/avatar-art/p4-linocut/base/base-faceless.png differ diff --git a/docs/avatar-art/p4-linocut/base/base-front.png b/docs/avatar-art/p4-linocut/base/base-front.png new file mode 100644 index 0000000..57260d7 Binary files /dev/null and b/docs/avatar-art/p4-linocut/base/base-front.png differ diff --git a/docs/avatar-art/p4-linocut/base/edits/aligned-body-1.json b/docs/avatar-art/p4-linocut/base/edits/aligned-body-1.json new file mode 100644 index 0000000..802e995 --- /dev/null +++ b/docs/avatar-art/p4-linocut/base/edits/aligned-body-1.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\body-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\aligned-body-1.png", + "refSize": [ + 1024, + 1536 + ], + "editedOriginalSize": [ + 1024, + 1536 + ], + "eccCorrelation": 0.99798, + "transform": { + "scaleSqrtDet": 1.00131, + "rotationDeg": -0.001, + "translateX": -0.141, + "translateY": -3.301, + "matrix": [ + [ + 1.000428, + -0.000176, + -0.141357 + ], + [ + -1.9e-05, + 1.002198, + -3.300659 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 554683, + "chamferInMask": { + "median": 0.0, + "p90": 3.0, + "nSamples": 59193 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p4-linocut/base/edits/aligned-body-2.json b/docs/avatar-art/p4-linocut/base/edits/aligned-body-2.json new file mode 100644 index 0000000..d59d233 --- /dev/null +++ b/docs/avatar-art/p4-linocut/base/edits/aligned-body-2.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\body-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\aligned-body-2.png", + "refSize": [ + 1024, + 1536 + ], + "editedOriginalSize": [ + 1024, + 1536 + ], + "eccCorrelation": 0.99671, + "transform": { + "scaleSqrtDet": 1.00221, + "rotationDeg": 0.0, + "translateX": 0.229, + "translateY": -5.606, + "matrix": [ + [ + 1.000477, + -0.000566, + 0.229476 + ], + [ + 9e-06, + 1.003949, + -5.605988 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 555167, + "chamferInMask": { + "median": 0.0, + "p90": 3.0, + "nSamples": 60472 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p4-linocut/base/edits/aligned-faceless-1.json b/docs/avatar-art/p4-linocut/base/edits/aligned-faceless-1.json new file mode 100644 index 0000000..8af694d --- /dev/null +++ b/docs/avatar-art/p4-linocut/base/edits/aligned-faceless-1.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\faceless-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\aligned-faceless-1.png", + "refSize": [ + 1024, + 1536 + ], + "editedOriginalSize": [ + 1024, + 1536 + ], + "eccCorrelation": 0.99622, + "transform": { + "scaleSqrtDet": 0.99978, + "rotationDeg": 0.003, + "translateX": 0.238, + "translateY": -0.442, + "matrix": [ + [ + 0.999337, + -1.3e-05, + 0.238082 + ], + [ + 4.8e-05, + 1.00023, + -0.441719 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 849049, + "chamferInMask": { + "median": 0.0, + "p90": 1.414, + "nSamples": 100203 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 6849 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 319, + 506, + 465, + 595 + ], + "refInkRatio": 0.1879, + "editedInkRatio": 0.0 + }, + "eyeB": { + "box": [ + 550, + 501, + 696, + 590 + ], + "refInkRatio": 0.1823, + "editedInkRatio": 0.0 + }, + "browA": { + "box": [ + 273, + 434, + 481, + 534 + ], + "refInkRatio": 0.0979, + "editedInkRatio": 0.015 + }, + "browB": { + "box": [ + 531, + 427, + 742, + 532 + ], + "refInkRatio": 0.0989, + "editedInkRatio": 0.0125 + }, + "mouth": { + "box": [ + 409, + 738, + 608, + 852 + ], + "refInkRatio": 0.0547, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 319, + 506, + 465, + 595 + ], + "eyeB": [ + 550, + 501, + 696, + 590 + ], + "browA": [ + 273, + 434, + 481, + 534 + ], + "browB": [ + 531, + 427, + 742, + 532 + ], + "mouth": [ + 409, + 738, + 608, + 852 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p4-linocut/base/edits/aligned-faceless-2.json b/docs/avatar-art/p4-linocut/base/edits/aligned-faceless-2.json new file mode 100644 index 0000000..eba07d4 --- /dev/null +++ b/docs/avatar-art/p4-linocut/base/edits/aligned-faceless-2.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\faceless-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\aligned-faceless-2.png", + "refSize": [ + 1024, + 1536 + ], + "editedOriginalSize": [ + 1024, + 1536 + ], + "eccCorrelation": 0.99715, + "transform": { + "scaleSqrtDet": 1.00005, + "rotationDeg": 0.002, + "translateX": -0.14, + "translateY": -0.529, + "matrix": [ + [ + 0.999762, + 5e-06, + -0.140065 + ], + [ + 2.8e-05, + 1.000345, + -0.529061 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 849049, + "chamferInMask": { + "median": 0.0, + "p90": 2.0, + "nSamples": 107586 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 7307 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 319, + 506, + 465, + 595 + ], + "refInkRatio": 0.1879, + "editedInkRatio": 0.0 + }, + "eyeB": { + "box": [ + 550, + 501, + 696, + 590 + ], + "refInkRatio": 0.1823, + "editedInkRatio": 0.0 + }, + "browA": { + "box": [ + 273, + 434, + 481, + 534 + ], + "refInkRatio": 0.0979, + "editedInkRatio": 0.0147 + }, + "browB": { + "box": [ + 531, + 427, + 742, + 532 + ], + "refInkRatio": 0.0989, + "editedInkRatio": 0.0126 + }, + "mouth": { + "box": [ + 409, + 738, + 608, + 852 + ], + "refInkRatio": 0.0547, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 319, + 506, + 465, + 595 + ], + "eyeB": [ + 550, + 501, + 696, + 590 + ], + "browA": [ + 273, + 434, + 481, + 534 + ], + "browB": [ + 531, + 427, + 742, + 532 + ], + "mouth": [ + 409, + 738, + 608, + 852 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p4-linocut/base/edits/sheet-face-zoom.jpg b/docs/avatar-art/p4-linocut/base/edits/sheet-face-zoom.jpg new file mode 100644 index 0000000..5aa5dcc Binary files /dev/null and b/docs/avatar-art/p4-linocut/base/edits/sheet-face-zoom.jpg differ diff --git a/docs/avatar-art/p4-linocut/base/edits/sheet.jpg b/docs/avatar-art/p4-linocut/base/edits/sheet.jpg new file mode 100644 index 0000000..bc3af55 Binary files /dev/null and b/docs/avatar-art/p4-linocut/base/edits/sheet.jpg differ diff --git a/docs/avatar-art/p4-linocut/base/normalize.json b/docs/avatar-art/p4-linocut/base/normalize.json new file mode 100644 index 0000000..3eeb26a --- /dev/null +++ b/docs/avatar-art/p4-linocut/base/normalize.json @@ -0,0 +1,66 @@ +{ + "canvas": { + "w": 1005, + "h": 1566 + }, + "reference": { + "image": "docs\\avatar-art\\p1-linocut\\base\\base-front.png", + "eyesCenter": [ + 492.69, + 584.33 + ], + "chin": [ + 500.61, + 919.55 + ], + "eyeDistance": 215.427, + "eyeChinDistance": 335.308 + }, + "input": { + "front": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\source-front.png", + "faceless": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\aligned-faceless-1.png", + "body": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\base\\edits\\aligned-body-1.png", + "frontSize": [ + 1024, + 1536 + ], + "eyesCenter": [ + 507.78, + 552.52 + ], + "chin": [ + 512.62, + 915.91 + ], + "eyeDistance": 231.073, + "eyeChinDistance": 363.428 + }, + "transform": { + "sHead": 0.927458, + "sWidth": 0.981445, + "s": 0.981445, + "rotationDeg": 0.0, + "offsetXNatural": -5.667, + "offsetXClampRange": [ + 0.0, + 0.0 + ], + "offsetX": 0.0, + "offsetY": 42.064 + }, + "coveredRange": { + "x": [ + 0.0, + 1005 + ], + "y": [ + 42.1, + 1549.6 + ] + }, + "inputSha256": { + "front": "b19f4a737e976352dc27adf1ec63d14c777c141acfb90685605f21c1be9921f5", + "faceless": "b2e6111c745e54dc6ba3eb43f67b4da5b07cf9ce42082c0951e27908f7d9a6be", + "body": "fbec8186707a8150c8989ed0e887714611bfe55d46f5cf760b0aafecc96f17ef" + } +} \ No newline at end of file diff --git a/docs/avatar-art/p4-linocut/manifest.json b/docs/avatar-art/p4-linocut/manifest.json new file mode 100644 index 0000000..ad9b7af --- /dev/null +++ b/docs/avatar-art/p4-linocut/manifest.json @@ -0,0 +1,1216 @@ +{ + "landmarks": { + "coordSystem": "screen (image pixel: x=0 좌측, y=0 상단; left=작은 x, right=큰 x; 인물 해부학적 좌우 아님)", + "eyeLeft": { + "innerCorner": [ + 430.65, + 594.22 + ], + "outerCorner": [ + 337.59, + 576.66 + ], + "upperLidTop": [ + 375.88, + 563.92 + ], + "lowerLidBottom": [ + 380.92, + 598.49 + ], + "iris": { + "center": [ + 384.73, + 580.01 + ], + "radius": 21.31 + } + }, + "eyeRight": { + "innerCorner": [ + 566.39, + 593.44 + ], + "outerCorner": [ + 659.22, + 572.86 + ], + "upperLidTop": [ + 621.39, + 561.68 + ], + "lowerLidBottom": [ + 616.77, + 596.57 + ], + "iris": { + "center": [ + 613.31, + 577.95 + ], + "radius": 21.41 + } + }, + "eyebrowLeft": { + "inner": [ + 449.35, + 524.62 + ], + "peak": [ + 353.25, + 508.35 + ], + "outer": [ + 303.65, + 507.6 + ] + }, + "eyebrowRight": { + "inner": [ + 540.92, + 523.73 + ], + "peak": [ + 642.6, + 502.27 + ], + "outer": [ + 695.08, + 500.19 + ] + }, + "noseTip": [ + 498.62, + 728.19 + ], + "mouthCornerLeft": [ + 426.22, + 819.4 + ], + "mouthCornerRight": [ + 571.46, + 818.64 + ], + "upperLipTopCenter": [ + 497.87, + 791.61 + ], + "lowerLipBottomCenter": [ + 498.73, + 852.31 + ], + "chinTip": [ + 502.66, + 940.61 + ], + "faceWidthAtEyeLevelLeft": [ + 268.63, + 621.0 + ], + "faceWidthAtEyeLevelRight": [ + 734.35, + 616.97 + ] + }, + "landmarkDetector": "mediapipe FaceLandmarker (tasks) 1.0.1, model=face_landmarker(float16, v1)", + "pipelineRun": { + "persona": "P4", + "timestamp": "2026-10-01T22:01:29", + "completed": true, + "stages": [ + { + "stage": "brow_sprite", + "ok": true, + "elapsedSec": 2.66 + }, + { + "stage": "paper_grain", + "ok": true, + "elapsedSec": 2.27 + }, + { + "stage": "lip_texture", + "ok": true, + "elapsedSec": 2.11 + }, + { + "stage": "jaw_pieces", + "ok": true, + "elapsedSec": 2.16 + }, + { + "stage": "export_rig", + "ok": true, + "elapsedSec": 16.36 + }, + { + "stage": "final_previews", + "ok": true, + "elapsedSec": 19.22 + } + ] + }, + "browCenterline": { + "method": "Otsu(front lum in bbox) AND diff(F-front)>=25, morphological closing to merge hatching, single global degree-2 polyfit on column-weighted centroid with one-pass outlier removal", + "diffThresh": 25.0, + "bboxPad": { + "x": 25.0, + "yUp": 42.0, + "yDown": 14.0 + }, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "outlierStdMult": 2.0, + "edgeInsetFrac": 0.03, + "peakWindow": [ + 0.25, + 0.6 + ], + "peakFallbackFrac": 0.35, + "peakFlatHeightPx": 3.0, + "peakFailEdgeFrac": 0.2, + "oldPoints": { + "browLeft": { + "inner": [ + 446.99, + 539.65 + ], + "peak": [ + 342.01, + 492.32 + ], + "outer": [ + 291.42, + 518.67 + ] + }, + "browRight": { + "inner": [ + 548.3, + 538.45 + ], + "peak": [ + 652.48, + 487.92 + ], + "outer": [ + 706.06, + 512.97 + ] + } + }, + "newPoints": { + "browLeft": { + "name": "browLeft", + "bbox": [ + 266, + 450, + 472, + 554 + ], + "otsuThresh": 121.0, + "colRange": [ + 299, + 454 + ], + "width": 155.0, + "nColumns": 156, + "nOutliersRemoved": 4, + "fitCoeffs": [ + 0.00105736, + -0.67933648, + 616.38397622 + ], + "inner": [ + 449.35, + 524.62 + ], + "peak": [ + 353.25, + 508.35 + ], + "outer": [ + 303.65, + 507.6 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.9295, + "checkA_pass": true, + "halfWidthInner": 6.756, + "halfWidthPeak": 6.485, + "halfWidthOuter": 2.498, + "bandX0": 266, + "bandY0": 450, + "colMin": 299, + "colMax": 454 + }, + "browRight": { + "name": "browRight", + "bbox": [ + 523, + 446, + 731, + 552 + ], + "otsuThresh": 121.0, + "colRange": [ + 536, + 700 + ], + "width": 164.0, + "nColumns": 165, + "nOutliersRemoved": 7, + "fitCoeffs": [ + 0.00111283, + -1.52815002, + 1024.73237057 + ], + "inner": [ + 540.92, + 523.73 + ], + "peak": [ + 642.6, + 502.27 + ], + "outer": [ + 695.08, + 500.19 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.903, + "checkA_pass": true, + "halfWidthInner": 2.378, + "halfWidthPeak": 6.718, + "halfWidthOuter": 1.5, + "bandX0": 523, + "bandY0": 446, + "colMin": 536, + "colMax": 700 + } + }, + "halfWidthLeft": [ + 6.756, + 6.485, + 2.498 + ], + "halfWidthRight": [ + 2.378, + 6.718, + 1.5 + ], + "halfWidthNote": "원화 눈썹 잉크 띠 반두께[inner,peak,outer](px, 중심선 법선 방향). export_rig.py가 persona.json browHalfWidthFromArt!=false(기본)면 RigBrow.halfWidth로 내보낸다.", + "checkB_innerMinusPeakY": { + "browLeft": 16.27, + "browRight": 21.46 + }, + "checkD_symmetry": { + "innerYDiff": 0.89, + "peakYDiff": 6.08 + }, + "evidenceImage": "preview/v2/brow-centerline.jpg" + }, + "schemaVersion": "vignette.avatar.v3.layers.v1", + "persona": "P4", + "canvas": { + "w": 1005, + "h": 1566 + }, + "base": { + "front": "base/base-front.png", + "faceless": "base/base-faceless.png", + "facelessPadded": "base/base-faceless-padded.png", + "facelessSize": [ + 1005, + 1566 + ], + "padNote": "base-faceless.png 마지막 행을 0번 복제해 1005x1566(base-front.png 크기)으로 패딩한 것이 F다." + }, + "segmenter": { + "model": "selfie_multiclass_256x256.tflite (mediapipe ImageSegmenter, storage.googleapis.com)", + "categories": { + "0": "background", + "1": "hair", + "2": "bodySkin", + "3": "faceSkin", + "4": "clothes", + "5": "others" + }, + "categoryPixelCounts": { + "0": 614690, + "1": 147103, + "2": 69058, + "3": 257454, + "4": 475638, + "5": 9887 + }, + "hairEdgeRefine": { + "dilatePx": 6, + "lumThreshold": 110, + "addedPixels": 9030 + } + }, + "chinLine": { + "landmarkIndex": 152, + "xy": [ + 502.66, + 940.61 + ], + "marginPx": 8, + "cutY": 948.61 + }, + "faceOval": { + "landmarkLoop": [ + 10, + 338, + 297, + 332, + 284, + 251, + 389, + 356, + 454, + 323, + 361, + 288, + 397, + 365, + 379, + 378, + 400, + 377, + 152, + 148, + 176, + 149, + 150, + 136, + 172, + 58, + 132, + 93, + 234, + 127, + 162, + 21, + 54, + 103, + 67, + 109 + ], + "scale": 1.04, + "sourceImage": "base/base-front.png" + }, + "layers": [ + { + "id": "body", + "file": "layers/body.png", + "source": "base-faceless-masked+regenerated-fill", + "alphaBBox": [ + 0, + 436, + 1005, + 1566 + ], + "opaquePixels": 566179, + "greenResidue": 0, + "fillTargetPixels": 25601, + "fillSourceRaw": "raw/body.png (rejected 재생성이 아니라 수용된 body.png의 크로마키 결과; head/hairFront와 달리 body 재생성은 승인됨)" + }, + { + "id": "head", + "file": "layers/head.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 171, + 114, + 822, + 1011 + ], + "opaquePixels": 405288, + "greenResidue": 0 + }, + { + "id": "hairFront", + "file": "layers/hairFront.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 250, + 405, + 751, + 856 + ], + "opaquePixels": 7245, + "greenResidue": 0 + } + ], + "rejectedRawEdits": { + "body": { + "file": "raw/body.png", + "status": "accepted-as-fill-source", + "reason": "정렬 (0,0), 형태 변형 없음 — head_mask 채움 전용 소스로 재사용" + } + }, + "composite": { + "meanAbsDiff": { + "full": 2.063827732347204, + "face": 0.31170282724581405, + "hairOutline": 10.115052289163106 + }, + "target": { + "full": 3.0, + "pass": true + }, + "backgroundNote": "카테고리0(배경)은 종이결 텍스처 노이즈(표준편차 ~29/채널)를 포함해 평탄한 크림(#EEE5D3)과 자체적으로 평균절대차 ~7 차이가 난다." + }, + "layersV2": { + "chinBandFix": { + "targetRegionPixels": 15310, + "sourceBandHeight": 150, + "rowJitterRange": [ + -2.0, + 2.0 + ], + "rngSeed": 20260930 + }, + "hairEdgeFix": { + "bandOuterPx": 40, + "bandInnerPx": 6, + "lumSmoothstep": [ + 205.0, + 150.0 + ], + "minFragmentAreaPx": 60, + "head": { + "bandOuterPixels": 91955, + "bandInnerPixels": 28677, + "componentsBefore": 203, + "removed": 197, + "removedPixels": 1271 + }, + "hairFront": { + "bandOuterPixels": 10689, + "bandInnerPixels": 9516, + "componentsBefore": 228, + "removed": 220, + "removedPixels": 983 + } + }, + "hairPaperGapFix": { + "regionDilatePx": 6, + "paperColorDistThreshold": 40.0, + "paperLumThreshold": 195.0, + "paperSatThreshold": 40.0, + "opaqueAlphaThreshold": 0.95, + "regionPixels": 162151, + "head": { + "targetPixels": 943, + "componentsBefore": 6, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + }, + "hairFront": { + "targetPixels": 1, + "componentsBefore": 8, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + } + }, + "jawInkFix": { + "mouthCenterY": 815.65, + "distThresholdPx": 14.0, + "mergePx": 3, + "aspectThreshold": 1.0, + "removedGroups": [ + { + "pixels": 237, + "bbox": [ + 308, + 816, + 342, + 843 + ], + "width": 34, + "height": 27, + "aspect": 1.259 + } + ], + "keptGroups": [ + { + "pixels": 755, + "bbox": [ + 650, + 816, + 686, + 857 + ], + "width": 36, + "height": 41, + "aspect": 0.878 + } + ], + "removedPixels": 237, + "strayFragmentCleanup": { + "componentsBefore": 8, + "removed": 0, + "removedPixels": 0 + } + }, + "metrics": { + "body": { + "haloPct": 1.1048826062230888 + }, + "head": { + "haloPct": 0.4306284483918719, + "bgLeakAlphaMean": 0.0002120053053522035, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + }, + "hairFront": { + "haloPct": 0.0, + "bgLeakAlphaMean": 0.0, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + } + }, + "layers": [ + { + "id": "body", + "bbox": [ + 0, + 436, + 1005, + 1566 + ], + "opaque": 528300, + "greenResidue": 0 + }, + { + "id": "head", + "bbox": [ + 161, + 97, + 822, + 1021 + ], + "opaque": 412754, + "greenResidue": 0 + }, + { + "id": "hairFront", + "bbox": [ + 234, + 405, + 768, + 890 + ], + "opaque": 11323, + "greenResidue": 0 + } + ], + "faceDetail": { + "browLandmarksSource": "manifest.landmarks.eyebrowLeft/Right", + "region": "face", + "faceInsetPx": 24.0, + "matchFacelessColor": true, + "matchFacelessColorDeltaRgb": { + "eyeLeft": [ + -12.17, + -11.69, + -12.49 + ], + "eyeRight": [ + -11.08, + -10.8, + -11.58 + ], + "browLeft": [ + -4.26, + -3.81, + -5.51 + ], + "browRight": [ + -4.9, + -4.31, + -5.97 + ], + "mouth": [ + -3.64, + -3.3, + -4.77 + ] + }, + "regions": { + "eyeLeft": [ + 307.6, + 498.4, + 455.6, + 668.5 + ], + "eyeRight": [ + 541.4, + 492.3, + 689.2, + 666.6 + ], + "mouth": [ + 381.2, + 753.2, + 616.5, + 925.6 + ], + "moles": [] + }, + "exclusionPixels": { + "eyeLeft": 12156, + "eyeRight": 11941, + "browLeft": 9643, + "browRight": 9985, + "mouth": 18139, + "union": 58587 + }, + "hairMaskPixels": 159429, + "bbox": [ + 266, + 394, + 736, + 945 + ], + "textureCloneStamp": { + "cloneTargetThreshold": 65.0, + "avoidThreshold": 110.0, + "lineOpeningIterations": 3, + "featherPx": 4.0, + "badTexturePixels": 13, + "preservedShadowPixels": 0, + "components": [ + { + "componentId": 1, + "pixels": 3, + "offset": [ + 0, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 2, + "pixels": 1, + "offset": [ + -40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 3, + "pixels": 9, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + } + ] + }, + "genericPatches": { + "forehead": [ + 380, + 402, + 428, + 450 + ], + "cheekLeft": [ + 327, + 646, + 375, + 694 + ], + "cheekRight": [ + 518, + 644, + 566, + 692 + ] + }, + "genericPatchBaseline": { + "highFreqEnergy": 7.458109656082686, + "lineEnergy": 3.8710488075882026 + }, + "checkA_meanAbsDiff": 0.4965093898211362, + "checkB_seamLumDiff": 1.6296153373646405, + "checkC_holeDarkResiduePct": 0.010252729789306404, + "checkC_violationPixels": 6, + "checkD_texturePreservation": { + "eyeLeft": { + "insideEnergy": 6.2165950887128805, + "baselineEnergy": 7.458109656082686, + "ratio": 0.8335349539467751, + "pass": true + }, + "eyeRight": { + "insideEnergy": 5.8870599073096015, + "baselineEnergy": 7.458109656082686, + "ratio": 0.7893501408239865, + "pass": true + }, + "browLeft": { + "insideEnergy": 7.674279349434956, + "baselineEnergy": 7.458109656082686, + "ratio": 1.0289845152887993, + "pass": true + }, + "browRight": { + "insideEnergy": 8.00513210373071, + "baselineEnergy": 7.458109656082686, + "ratio": 1.0733459915277437, + "pass": true + }, + "mouth": { + "insideEnergy": 5.4462341485874255, + "baselineEnergy": 7.458109656082686, + "ratio": 0.7302432385323786, + "pass": true + } + }, + "checkD_allPass": true, + "checkE_ghostOutline": { + "eyeLeft": { + "bandLineEnergy": 7.300975232426853, + "baselineLineEnergy": 3.8710488075882026, + "ratio": 1.8860457708813063, + "pass": false + }, + "eyeRight": { + "bandLineEnergy": 6.426403576872062, + "baselineLineEnergy": 3.8710488075882026, + "ratio": 1.6601194912021617, + "pass": false + }, + "browLeft": { + "bandLineEnergy": 5.16448064507108, + "baselineLineEnergy": 3.8710488075882026, + "ratio": 1.3341295606884198, + "pass": true + }, + "browRight": { + "bandLineEnergy": 4.6860081826909505, + "baselineLineEnergy": 3.8710488075882026, + "ratio": 1.2105267630584322, + "pass": true + }, + "mouth": { + "bandLineEnergy": 3.2433439561515796, + "baselineLineEnergy": 3.8710488075882026, + "ratio": 0.8378463091950255, + "pass": true + } + }, + "checkE_allPass": false, + "checkDarkCircle": { + "eyeLeft": { + "compositeMean": 149.70914285714284, + "frontMean": 149.53695238095236, + "diff": 0.17219047619047956, + "pass": true + }, + "eyeRight": { + "compositeMean": 155.92419047619046, + "frontMean": 155.87638095238097, + "diff": 0.047809523809490884, + "pass": true + } + }, + "checkDarkCircle_allPass": true + }, + "paperGrain": { + "sourceImage": "base/base-front.png", + "sourceOrigin": [ + 10, + 734 + ], + "tileSize": 256, + "personMarginPx": 20, + "cleanFraction": 0.9996795654296875, + "contaminatedPixelsFilled": 21, + "chromaKeep": 0.3, + "targetLumRange": [ + 245.0, + 250.0 + ], + "lumShift": 23.586695353190095, + "finalMeanLum": 247.41994095532309, + "finalLumStd": 7.731769387649097, + "seamContinuity": { + "leftRightDiff": 0.33841442178375775, + "topBottomDiff": 0.11046582323295222 + } + } + }, + "lipTexture": { + "designVersion": "A5(아랫입술 그늘 띠를 lip-shadow 조각으로 분리)", + "landmarks": { + "mouthCornerLeft": [ + 426.22, + 819.4 + ], + "mouthCornerRight": [ + 571.46, + 818.64 + ], + "upperLipTop": [ + 497.87, + 791.61 + ], + "lowerLipBottom": [ + 498.73, + 852.31 + ], + "mouthCenter": [ + 498.3611898869276, + 815.6509176492691 + ] + }, + "capBBox": [ + 417.84, + 786.96, + 579.84, + 856.96 + ], + "otsuThreshLabA": 139.0, + "diffThresh": 20.0, + "dilatePx": 10.0, + "alphaRampPx": 4.0, + "splitOverlapPx": 2.0, + "shadowBandPx": 18.0, + "shadowTopOverlapPx": 6.0, + "shadowSideRampPx": 6.0, + "shadowTopRampPx": 4.0, + "checks": { + "lip-upper": { + "regionPixelCount": 5425, + "fullOpacityPixelCount": 4663, + "rampPixelCount": 762, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 32, + 30, + 179, + 46 + ] + }, + "lip-lower": { + "regionPixelCount": 5651, + "fullOpacityPixelCount": 4868, + "rampPixelCount": 783, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 32, + 69, + 178, + 51 + ] + }, + "lip-shadow": { + "regionPixelCount": 3264, + "fullOpacityPixelCount": 1504, + "rampPixelCount": 1760, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 42, + 67, + 159, + 61 + ] + }, + "splitOverlapPixelCount": 355, + "splitOverlapBandOk": true, + "splitOverlapAlphaMaxDiff": 0, + "splitOverlapConsistentOk": true, + "splitCoverageMismatchPixelCount": 0, + "splitCheckOk": true, + "shadowLowerOverlapPixelCount": 2539, + "shadowLowerOverlapMaxDiff": 64.72410611303343, + "shadowLowerOverlapDiffGt1PixelCount": 306, + "shadowLowerOverlapOk": false + }, + "check3NeutralComposite": { + "fullOpacityMaxDiff": 0.0, + "rampMeanAbsDiff": 4.973, + "mouthBBoxMeanAbsDiff": 1.491 + }, + "pngFileSizes": { + "lip-upper": 21921, + "lip-lower": 24895, + "lip-shadow": 26686 + }, + "canvasOrigin": { + "upper": [ + 410, + 777 + ], + "lower": [ + 410, + 816 + ], + "shadow": [ + 420, + 814 + ] + }, + "evidenceImage": "preview/v2/lip-texture.jpg", + "check4WebpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jaw": { + "designVersion": "A5(결정문 §8.4 하관 띠 변형 — 턱 조각 원본)", + "noseTip": [ + 498.62, + 728.19 + ], + "chinTip": [ + 502.66, + 940.61 + ], + "yFormula": "noseTip.y - 50 - 10 .. chinTip.y + 40", + "noseToTopPx": 60.0, + "chinToBottomPx": 40.0, + "ovalOutsetPx": 18.0, + "faceOvalSource": "export_rig.detect_face_landmarks + compute_face_oval(base-front.png, 결정적)", + "bboxCanvas": [ + 250, + 668, + 754, + 981 + ], + "naiveXRangeForComparison": [ + 250, + 754 + ], + "checks": { + "head": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 328118 + }, + "detail": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 379279 + } + }, + "evidenceImage": "preview/v2/jaw-pieces.jpg", + "check1VsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.629, + "maxAbsDiffPremultipliedRgb": 42.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.718, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 14906, + "lip-lower": 17226, + "lip-shadow": 19124 + }, + "totalBytes": 51256, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 33156, + "jaw-detail": 22606 + }, + "totalBytes": 55762, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.629, + "maxAbsDiffPremultipliedRgb": 42.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.718, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSprite": { + "enabled": true, + "bandExtraHalfHeightPx": 8.0, + "bandEndExtendPx": 6.0, + "diffThresh": 25.0, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "hairSource": "layers/v2/hairFront.png alpha(게시되는 레이어 그 자체, 분할 카테고리 아님)", + "hairAlphaThresh": 128.0, + "hairDilateIterations": 1, + "rampPx": 1.5, + "inkLumMethod": "median(ink-classified pixels in band, region after hair removal)", + "minAlphaForUnmix": 0.05, + "hairMaskPixelCount": 14569, + "left": { + "bboxCanvas": [ + 299, + 499, + 156, + 36 + ], + "halfHeightPx": 14.756, + "otsuThresh": 123.0, + "lSkin": 183.667, + "lInk": 62.0, + "regionPixelCount": 1987, + "hairOverlapPixelCount": 0, + "neutralCompositeMeanAbsDiffAlphaRegion": 2.883, + "pngFileSizeBytes": 7862 + }, + "right": { + "bboxCanvas": [ + 536, + 491, + 164, + 42 + ], + "halfHeightPx": 14.718, + "otsuThresh": 122.0, + "lSkin": 182.667, + "lInk": 60.333, + "regionPixelCount": 1987, + "hairOverlapPixelCount": 0, + "neutralCompositeMeanAbsDiffAlphaRegion": 3.014, + "pngFileSizeBytes": 7777 + }, + "canvasOrigin": { + "left": [ + 299.0, + 499.0 + ], + "right": [ + 536.0, + 491.0 + ] + }, + "evidenceImage": "preview/v2/brow-sprite.jpg", + "checkWebpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "eyeLineScale": { + "enabled": true, + "method": "눈 폭 가운데 60% 열마다 upperLidTop.y-12 ~ 홍채중심y 사이 첫 연속 어두운(lum<80) 구간 길이의 중앙값", + "windowAbovePx": 12.0, + "darkLumThresh": 80.0, + "columnMiddleFrac": 0.6, + "p1BaselinePx": 2.0, + "lineScaleClampRange": [ + 1.0, + 2.5 + ], + "left": { + "measuredPx": 10.0, + "nColumns": 57, + "ratio": 5.0, + "lineScale": 2.5 + }, + "right": { + "measuredPx": 11.0, + "nColumns": 57, + "ratio": 5.5, + "lineScale": 2.5 + } + }, + "iris": { + "method": "가로: 중심 y 부근 상하 각 4행에서 중심 x를 포함하는 연속 어두운(lum<100) 구간의 중앙값으로 반지름·중심x. 세로: 중심 x 부근 좌우 각 4열에서 중심 y를 포함하는 연속 어두운 구간의 아래쪽 끝 중앙값에서 가로 반지름을 빼 중심y(세로축은 윗눈꺼풀 잉크와 홍채가 같은 톤으로 이어져 위쪽 경계를 가를 수 없다).", + "darkLumThresh": 100.0, + "scanBandPx": 4, + "left": { + "measuredCenter": [ + 385.0, + 576.0 + ], + "measuredRadius": 20.0, + "rigCenter": [ + 384.73, + 580.01 + ], + "rigRadius": 21.31, + "nRowsHorizontal": 9, + "nColsVertical": 9 + }, + "right": { + "measuredCenter": [ + 611.5, + 574.5 + ], + "measuredRadius": 18.5, + "rigCenter": [ + 613.31, + 577.95 + ], + "rigRadius": 21.41, + "nRowsHorizontal": 9, + "nColsVertical": 9 + } + }, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 5150, + "brow-right": 4998 + }, + "totalBytes": 10148, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p4-linocut/persona.json b/docs/avatar-art/p4-linocut/persona.json new file mode 100644 index 0000000..09fd463 --- /dev/null +++ b/docs/avatar-art/p4-linocut/persona.json @@ -0,0 +1,32 @@ +{ + "code": "P4", + "publicSlug": "p4", + "styleFrame": "../art-direction-v3/p1/r2-b-linocut.png", + "paletteSamples": { + "ink": { "box": [350, 170, 580, 270], "lumThreshold": 55 }, + "motifPetalBoxes": [ + { "label": "sun", "kind": "ochre", "box": [1230, 10, 1536, 210] }, + { "label": "tulip", "kind": "ochre", "box": [1030, 280, 1170, 560] } + ], + "motifLeafBoxes": [ + { "label": "cloudLeft", "kind": "blue", "box": [20, 20, 380, 190] }, + { "label": "raincloud", "kind": "blue", "box": [520, 10, 930, 230] }, + { "label": "wiltedFlowerLeaf", "kind": "blue", "box": [520, 280, 650, 580] }, + { "label": "closedBudLeaf", "kind": "blue", "box": [10, 290, 110, 570] } + ] + }, + "faceDetail": { + "moles": [], + "region": "face", + "faceInsetPx": 24, + "matchFacelessColor": true + }, + "pivots": { + "neck": [502.66, 1011.06], + "face": [496.02, 654.98], + "body": [502, 1566] + }, + "crops": { + "bustYOffset": 40 + } +} diff --git a/docs/avatar-art/p4-linocut/preview/qa/face-art-vs-render.jpg b/docs/avatar-art/p4-linocut/preview/qa/face-art-vs-render.jpg new file mode 100644 index 0000000..bd945a0 Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/qa/face-art-vs-render.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/qa/face-zoom.jpg b/docs/avatar-art/p4-linocut/preview/qa/face-zoom.jpg new file mode 100644 index 0000000..4286bcf Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/qa/face-zoom.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/qa/neutral-vs-art.jpg b/docs/avatar-art/p4-linocut/preview/qa/neutral-vs-art.jpg new file mode 100644 index 0000000..9c90a72 Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/qa/neutral-vs-art.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/qa/normalized.jpg b/docs/avatar-art/p4-linocut/preview/qa/normalized.jpg new file mode 100644 index 0000000..aaa6ece Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/qa/normalized.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/qa/sheet-expr-bust.jpg b/docs/avatar-art/p4-linocut/preview/qa/sheet-expr-bust.jpg new file mode 100644 index 0000000..24bb25e Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/qa/sheet-expr-bust.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/qa/sheet-expr-face.jpg b/docs/avatar-art/p4-linocut/preview/qa/sheet-expr-face.jpg new file mode 100644 index 0000000..554dfc4 Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/qa/sheet-expr-face.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/qa/sheet-viseme.jpg b/docs/avatar-art/p4-linocut/preview/qa/sheet-viseme.jpg new file mode 100644 index 0000000..52ce999 Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/qa/sheet-viseme.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/qa/viseme-timeline.json b/docs/avatar-art/p4-linocut/preview/qa/viseme-timeline.json new file mode 100644 index 0000000..b09caab --- /dev/null +++ b/docs/avatar-art/p4-linocut/preview/qa/viseme-timeline.json @@ -0,0 +1,287 @@ +[ + { + "t": 0, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00000.png" + }, + { + "t": 50, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00050.png" + }, + { + "t": 100, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00100.png" + }, + { + "t": 150, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00150.png" + }, + { + "t": 200, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00200.png" + }, + { + "t": 250, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00250.png" + }, + { + "t": 300, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00300.png" + }, + { + "t": 350, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00350.png" + }, + { + "t": 400, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00400.png" + }, + { + "t": 450, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00450.png" + }, + { + "t": 500, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00500.png" + }, + { + "t": 550, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00550.png" + }, + { + "t": 600, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00600.png" + }, + { + "t": 650, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00650.png" + }, + { + "t": 700, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00700.png" + }, + { + "t": 750, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00750.png" + }, + { + "t": 800, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00800.png" + }, + { + "t": 850, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00850.png" + }, + { + "t": 900, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00900.png" + }, + { + "t": 950, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t00950.png" + }, + { + "t": 1000, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01000.png" + }, + { + "t": 1050, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01050.png" + }, + { + "t": 1100, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01100.png" + }, + { + "t": 1150, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01150.png" + }, + { + "t": 1200, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01200.png" + }, + { + "t": 1250, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01250.png" + }, + { + "t": 1300, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01300.png" + }, + { + "t": 1350, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01350.png" + }, + { + "t": 1400, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01400.png" + }, + { + "t": 1450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01450.png" + }, + { + "t": 1500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01500.png" + }, + { + "t": 1550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01550.png" + }, + { + "t": 1600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01600.png" + }, + { + "t": 1650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01650.png" + }, + { + "t": 1700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01700.png" + }, + { + "t": 1750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01750.png" + }, + { + "t": 1800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01800.png" + }, + { + "t": 1850, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01850.png" + }, + { + "t": 1900, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01900.png" + }, + { + "t": 1950, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t01950.png" + }, + { + "t": 2000, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02000.png" + }, + { + "t": 2050, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02050.png" + }, + { + "t": 2100, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02100.png" + }, + { + "t": 2150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02150.png" + }, + { + "t": 2200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02200.png" + }, + { + "t": 2250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02250.png" + }, + { + "t": 2300, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02300.png" + }, + { + "t": 2350, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02350.png" + }, + { + "t": 2400, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02400.png" + }, + { + "t": 2450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02450.png" + }, + { + "t": 2500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02500.png" + }, + { + "t": 2550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02550.png" + }, + { + "t": 2600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02600.png" + }, + { + "t": 2650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02650.png" + }, + { + "t": 2700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02700.png" + }, + { + "t": 2750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02750.png" + }, + { + "t": 2800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p4-linocut\\preview\\qa\\frames\\viseme-scan-t02800.png" + } +] \ No newline at end of file diff --git a/docs/avatar-art/p4-linocut/preview/v2/brow-centerline.jpg b/docs/avatar-art/p4-linocut/preview/v2/brow-centerline.jpg new file mode 100644 index 0000000..cbf15c5 Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/v2/brow-centerline.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/v2/brow-sprite.jpg b/docs/avatar-art/p4-linocut/preview/v2/brow-sprite.jpg new file mode 100644 index 0000000..419a67b Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/v2/brow-sprite.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/v2/export-rig-report.json b/docs/avatar-art/p4-linocut/preview/v2/export-rig-report.json new file mode 100644 index 0000000..230a7ee --- /dev/null +++ b/docs/avatar-art/p4-linocut/preview/v2/export-rig-report.json @@ -0,0 +1,676 @@ +{ + "faceOvalBBox": [ + 252.2, + 388.0, + 748.9, + 951.6 + ], + "cropsFace": [ + 184.9, + 354.2, + 631.2, + 631.2 + ], + "mouthCenter": [ + 498.4, + 815.7 + ], + "palette": { + "ink": "#22211F", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#B48460", + "lipLower": "#C08E69", + "mouthLine": "#332B26", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "paletteSamples": { + "eyeLeft": { + "sclera": "#D0AB82", + "iris": "#292926", + "irisRing": "#886E5B", + "n": { + "sclera": 1146, + "iris": 204, + "irisRing": 420 + } + }, + "eyeRight": { + "sclera": "#CFAA82", + "iris": "#2E2D2A", + "irisRing": "#8C705A", + "n": { + "sclera": 1077, + "iris": 208, + "irisRing": 424 + } + }, + "scleraIrisIrisRingFixedOverride": { + "reason": "persona.json paletteSamples.eyeOverride(고정 설계값)", + "measured": { + "sclera": "#D0AA82", + "iris": "#2C2B28", + "irisRing": "#8A705A" + }, + "fixed": { + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F" + } + }, + "ink": { + "box": [ + 350, + 170, + 580, + 270 + ], + "lumThreshold": 55.0, + "n": 16599, + "hex": "#22211F" + }, + "lipUpper": { + "box": [ + 421, + 788, + 576, + 813 + ], + "hex": "#B48460" + }, + "lipLower": { + "box": [ + 421, + 817, + 576, + 855 + ], + "hex": "#C08E69" + }, + "mouthLine": { + "box": [ + 441, + 813, + 556, + 818 + ], + "hex": "#332B26" + }, + "motifPetal": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "sun": { + "box": [ + 1230, + 10, + 1536, + 210 + ], + "n": 20570, + "hex": "#D3A661" + }, + "tulip": { + "box": [ + 1030, + 280, + 1170, + 560 + ], + "n": 4314, + "hex": "#CCA063" + } + }, + "hex": "#D0A362" + }, + "motifLeaf": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "cloudLeft": { + "box": [ + 20, + 20, + 380, + 190 + ], + "n": 21312, + "hex": "#636D76" + }, + "raincloud": { + "box": [ + 520, + 10, + 930, + 230 + ], + "n": 27607, + "hex": "#586B76" + }, + "wiltedFlowerLeaf": { + "box": [ + 520, + 280, + 650, + 580 + ], + "n": 5818, + "hex": "#495961" + }, + "closedBudLeaf": { + "box": [ + 10, + 290, + 110, + 570 + ], + "n": 6589, + "hex": "#495961" + } + }, + "hex": "#53626C" + } + }, + "publish": { + "fileSizes": { + "body": 137422, + "head": 116202, + "hair-front": 19270, + "face-detail": 50508, + "paper-grain": 2428 + }, + "encodeMeta": { + "quality": 80, + "scale": 1.0, + "totalBytes": 325830 + }, + "totalBytes": 325830 + }, + "grain": { + "href": "/avatar/v3/p4/paper-grain.webp", + "size": 256 + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 14906, + "lip-lower": 17226, + "lip-shadow": 19124 + }, + "totalBytes": 51256, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 33156, + "jaw-detail": 22606 + }, + "totalBytes": 55762, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.629, + "maxAbsDiffPremultipliedRgb": 42.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.718, + "maxAbsDiffPremultipliedRgb": 36.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 5150, + "brow-right": 4998 + }, + "totalBytes": 10148, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "rig": { + "schemaVersion": "vignette.avatar.v3.rig.v1", + "persona": "P4", + "canvas": { + "w": 1005, + "h": 1566 + }, + "layers": { + "body": { + "href": "/avatar/v3/p4/body.webp", + "x": 0, + "y": 436, + "w": 1005, + "h": 1130 + }, + "head": { + "href": "/avatar/v3/p4/head.webp", + "x": 161, + "y": 97, + "w": 661, + "h": 924 + }, + "hairFront": { + "href": "/avatar/v3/p4/hair-front.webp", + "x": 234, + "y": 405, + "w": 534, + "h": 485 + }, + "faceDetail": { + "href": "/avatar/v3/p4/face-detail.webp", + "x": 266, + "y": 394, + "w": 470, + "h": 551 + } + }, + "grain": { + "href": "/avatar/v3/p4/paper-grain.webp", + "size": 256 + }, + "lipTexture": { + "upper": { + "href": "/avatar/v3/p4/lip-upper.webp", + "x": 410, + "y": 777, + "w": 179, + "h": 46 + }, + "lower": { + "href": "/avatar/v3/p4/lip-lower.webp", + "x": 410, + "y": 816, + "w": 178, + "h": 51 + }, + "shadow": { + "href": "/avatar/v3/p4/lip-shadow.webp", + "x": 420, + "y": 814, + "w": 159, + "h": 61 + } + }, + "jaw": { + "head": { + "href": "/avatar/v3/p4/jaw-head.webp", + "x": 250, + "y": 668, + "w": 504, + "h": 313 + }, + "detail": { + "href": "/avatar/v3/p4/jaw-detail.webp", + "x": 250, + "y": 668, + "w": 504, + "h": 313 + } + }, + "motif": null, + "pivots": { + "neck": [ + 502.66, + 1011.06 + ], + "body": [ + 502, + 1566 + ], + "face": [ + 496.02, + 654.98 + ] + }, + "crops": { + "portrait": [ + 0, + 0, + 1005, + 1566 + ], + "bust": [ + 0.0, + 40.0, + 1005.0, + 1005.0 + ], + "face": [ + 184.90839997490644, + 354.1878642927646, + 631.1857242919922, + 631.1857242919922 + ] + }, + "faceOval": [ + [ + 495.7, + 388.0 + ], + [ + 569.6, + 388.6 + ], + [ + 631.4, + 396.4 + ], + [ + 687.2, + 414.1 + ], + [ + 721.3, + 442.7 + ], + [ + 739.9, + 479.9 + ], + [ + 748.2, + 519.6 + ], + [ + 748.9, + 568.1 + ], + [ + 743.7, + 615.0 + ], + [ + 735.8, + 663.9 + ], + [ + 723.6, + 715.1 + ], + [ + 704.8, + 769.9 + ], + [ + 681.9, + 816.1 + ], + [ + 657.7, + 851.5 + ], + [ + 628.5, + 883.7 + ], + [ + 603.9, + 907.3 + ], + [ + 576.9, + 929.1 + ], + [ + 544.6, + 946.1 + ], + [ + 502.7, + 951.6 + ], + [ + 461.8, + 946.3 + ], + [ + 430.4, + 929.7 + ], + [ + 403.7, + 908.3 + ], + [ + 378.7, + 885.5 + ], + [ + 348.8, + 854.0 + ], + [ + 324.0, + 819.1 + ], + [ + 300.1, + 773.9 + ], + [ + 280.7, + 719.0 + ], + [ + 267.6, + 667.8 + ], + [ + 259.3, + 619.2 + ], + [ + 252.7, + 572.5 + ], + [ + 252.2, + 524.3 + ], + [ + 258.8, + 484.1 + ], + [ + 275.1, + 446.8 + ], + [ + 306.7, + 417.8 + ], + [ + 360.2, + 398.8 + ], + [ + 421.5, + 390.1 + ] + ], + "landmarks": { + "eyeLeft": { + "inner": [ + 430.6, + 594.2 + ], + "outer": [ + 337.6, + 576.7 + ], + "upperLidTop": [ + 375.9, + 563.9 + ], + "lowerLidBottom": [ + 380.9, + 598.5 + ], + "iris": { + "center": [ + 385.0, + 576.0 + ], + "radius": 20.0 + }, + "lineScale": 2.5 + }, + "eyeRight": { + "inner": [ + 566.4, + 593.4 + ], + "outer": [ + 659.2, + 572.9 + ], + "upperLidTop": [ + 621.4, + 561.7 + ], + "lowerLidBottom": [ + 616.8, + 596.6 + ], + "iris": { + "center": [ + 611.5, + 574.5 + ], + "radius": 18.5 + }, + "lineScale": 2.5 + }, + "browLeft": { + "inner": [ + 449.4, + 524.6 + ], + "peak": [ + 353.2, + 508.4 + ], + "outer": [ + 303.6, + 507.6 + ], + "halfWidth": [ + 6.76, + 6.49, + 2.5 + ], + "sprite": { + "href": "/avatar/v3/p4/brow-left.webp", + "x": 299.0, + "y": 499.0, + "w": 156, + "h": 36 + } + }, + "browRight": { + "inner": [ + 540.9, + 523.7 + ], + "peak": [ + 642.6, + 502.3 + ], + "outer": [ + 695.1, + 500.2 + ], + "halfWidth": [ + 2.38, + 6.72, + 1.5 + ], + "sprite": { + "href": "/avatar/v3/p4/brow-right.webp", + "x": 536.0, + "y": 491.0, + "w": 164, + "h": 42 + } + }, + "noseTip": [ + 498.6, + 728.2 + ], + "mouthCornerLeft": [ + 426.2, + 819.4 + ], + "mouthCornerRight": [ + 571.5, + 818.6 + ], + "upperLipTop": [ + 497.9, + 791.6 + ], + "lowerLipBottom": [ + 498.7, + 852.3 + ], + "mouthCenter": [ + 498.4, + 815.7 + ], + "chinTip": [ + 502.7, + 940.6 + ] + }, + "palette": { + "ink": "#22211F", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#B48460", + "lipLower": "#C08E69", + "mouthLine": "#332B26", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "backdrop": { + "cognitive": "#ECE3D1", + "positive": "#F1DEC2", + "negative": "#DCE0E2", + "defensive": "#E6DAD3", + "energy": "#E2E0D0" + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p4-linocut/preview/v2/ghost-check.jpg b/docs/avatar-art/p4-linocut/preview/v2/ghost-check.jpg new file mode 100644 index 0000000..04c4fff Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/v2/ghost-check.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/v2/holes-texture.jpg b/docs/avatar-art/p4-linocut/preview/v2/holes-texture.jpg new file mode 100644 index 0000000..33b531e Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/v2/holes-texture.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/v2/jaw-pieces.jpg b/docs/avatar-art/p4-linocut/preview/v2/jaw-pieces.jpg new file mode 100644 index 0000000..f4de558 Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/v2/jaw-pieces.jpg differ diff --git a/docs/avatar-art/p4-linocut/preview/v2/lip-texture.jpg b/docs/avatar-art/p4-linocut/preview/v2/lip-texture.jpg new file mode 100644 index 0000000..b318e89 Binary files /dev/null and b/docs/avatar-art/p4-linocut/preview/v2/lip-texture.jpg differ diff --git a/docs/avatar-art/p4-linocut/prompts/base-faceless.txt b/docs/avatar-art/p4-linocut/prompts/base-faceless.txt new file mode 100644 index 0000000..0c5e914 --- /dev/null +++ b/docs/avatar-art/p4-linocut/prompts/base-faceless.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as faceless.png: + +Redraw exactly the same girl, same frontal pose, same framing and same linocut relief-print style as the reference, but leave the face blank: remove the eyes, eyebrows and mouth completely and fill those areas with plain skin in the same flat skin color, keeping the nose, the face outline, the ears, the hair, the neck, the pencil tucked behind her ear, the white shirt collar and the navy crew-neck sweater exactly as they are. Do not move, resize or redraw anything else. Plain flat cream background, nothing else, no text. diff --git a/docs/avatar-art/p4-linocut/prompts/body.txt b/docs/avatar-art/p4-linocut/prompts/body.txt new file mode 100644 index 0000000..b868b0a --- /dev/null +++ b/docs/avatar-art/p4-linocut/prompts/body.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as body.png: + +Keep only the neck, the white shirt collar and the navy crew-neck sweater exactly as they are in the reference: same shapes, same position, same linocut relief-print style, same ink colors and texture. Remove the head, the face, the ears and all of the hair completely. Where the hair or the chin previously covered the neck or the clothes, continue them naturally in the same style so there are no holes. Place the result on a plain flat pure green background (#00ff00) with nothing else, no text. diff --git a/docs/avatar-art/p4-linocut/raw/body.png b/docs/avatar-art/p4-linocut/raw/body.png new file mode 100644 index 0000000..42ec9f8 Binary files /dev/null and b/docs/avatar-art/p4-linocut/raw/body.png differ diff --git a/docs/avatar-art/p5-linocut/base/base-faceless.png b/docs/avatar-art/p5-linocut/base/base-faceless.png new file mode 100644 index 0000000..1cb8a01 Binary files /dev/null and b/docs/avatar-art/p5-linocut/base/base-faceless.png differ diff --git a/docs/avatar-art/p5-linocut/base/base-front.png b/docs/avatar-art/p5-linocut/base/base-front.png new file mode 100644 index 0000000..502e24f Binary files /dev/null and b/docs/avatar-art/p5-linocut/base/base-front.png differ diff --git a/docs/avatar-art/p5-linocut/base/edits/aligned-body-1.json b/docs/avatar-art/p5-linocut/base/edits/aligned-body-1.json new file mode 100644 index 0000000..620cdc4 --- /dev/null +++ b/docs/avatar-art/p5-linocut/base/edits/aligned-body-1.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\body-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\aligned-body-1.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.89496, + "transform": { + "scaleSqrtDet": 1.00107, + "rotationDeg": 0.009, + "translateX": 0.868, + "translateY": -2.827, + "matrix": [ + [ + 1.000537, + -0.000853, + 0.867875 + ], + [ + 0.000151, + 1.001599, + -2.827145 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 551610, + "chamferInMask": { + "median": 0.0, + "p90": 2.0, + "nSamples": 76942 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p5-linocut/base/edits/aligned-body-2.json b/docs/avatar-art/p5-linocut/base/edits/aligned-body-2.json new file mode 100644 index 0000000..f2902b7 --- /dev/null +++ b/docs/avatar-art/p5-linocut/base/edits/aligned-body-2.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\body-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\aligned-body-2.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.99029, + "transform": { + "scaleSqrtDet": 1.00132, + "rotationDeg": 0.005, + "translateX": -0.386, + "translateY": -3.197, + "matrix": [ + [ + 1.000755, + 2.9e-05, + -0.385584 + ], + [ + 9.5e-05, + 1.001881, + -3.197296 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 540648, + "chamferInMask": { + "median": 0.0, + "p90": 1.414, + "nSamples": 74241 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p5-linocut/base/edits/aligned-faceless-1.json b/docs/avatar-art/p5-linocut/base/edits/aligned-faceless-1.json new file mode 100644 index 0000000..69c1d57 --- /dev/null +++ b/docs/avatar-art/p5-linocut/base/edits/aligned-faceless-1.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\faceless-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\aligned-faceless-1.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.99531, + "transform": { + "scaleSqrtDet": 0.99998, + "rotationDeg": 0.004, + "translateX": -0.129, + "translateY": -0.135, + "matrix": [ + [ + 1.000166, + -9.9e-05, + -0.128815 + ], + [ + 6.5e-05, + 0.999797, + -0.135042 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 828124, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 116456 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 5503 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 398, + 453, + 539, + 533 + ], + "refInkRatio": 0.1947, + "editedInkRatio": 0.0 + }, + "eyeB": { + "box": [ + 614, + 452, + 754, + 533 + ], + "refInkRatio": 0.1799, + "editedInkRatio": 0.0 + }, + "browA": { + "box": [ + 352, + 385, + 557, + 475 + ], + "refInkRatio": 0.2908, + "editedInkRatio": 0.1291 + }, + "browB": { + "box": [ + 599, + 387, + 802, + 476 + ], + "refInkRatio": 0.3371, + "editedInkRatio": 0.181 + }, + "mouth": { + "box": [ + 475, + 653, + 672, + 769 + ], + "refInkRatio": 0.1209, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 398, + 453, + 539, + 533 + ], + "eyeB": [ + 614, + 452, + 754, + 533 + ], + "browA": [ + 352, + 385, + 557, + 475 + ], + "browB": [ + 599, + 387, + 802, + 476 + ], + "mouth": [ + 475, + 653, + 672, + 769 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p5-linocut/base/edits/aligned-faceless-2.json b/docs/avatar-art/p5-linocut/base/edits/aligned-faceless-2.json new file mode 100644 index 0000000..f911922 --- /dev/null +++ b/docs/avatar-art/p5-linocut/base/edits/aligned-faceless-2.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\faceless-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\aligned-faceless-2.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.99558, + "transform": { + "scaleSqrtDet": 0.99969, + "rotationDeg": 0.004, + "translateX": 0.599, + "translateY": 0.017, + "matrix": [ + [ + 0.999723, + -0.000189, + 0.599433 + ], + [ + 6.2e-05, + 0.999659, + 0.017416 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 828124, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 112934 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 5305 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 398, + 453, + 539, + 533 + ], + "refInkRatio": 0.1947, + "editedInkRatio": 0.0 + }, + "eyeB": { + "box": [ + 614, + 452, + 754, + 533 + ], + "refInkRatio": 0.1799, + "editedInkRatio": 0.0 + }, + "browA": { + "box": [ + 352, + 385, + 557, + 475 + ], + "refInkRatio": 0.2908, + "editedInkRatio": 0.1199 + }, + "browB": { + "box": [ + 599, + 387, + 802, + 476 + ], + "refInkRatio": 0.3371, + "editedInkRatio": 0.1758 + }, + "mouth": { + "box": [ + 475, + 653, + 672, + 769 + ], + "refInkRatio": 0.1209, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 398, + 453, + 539, + 533 + ], + "eyeB": [ + 614, + 452, + 754, + 533 + ], + "browA": [ + 352, + 385, + 557, + 475 + ], + "browB": [ + 599, + 387, + 802, + 476 + ], + "mouth": [ + 475, + 653, + 672, + 769 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p5-linocut/base/edits/sheet.jpg b/docs/avatar-art/p5-linocut/base/edits/sheet.jpg new file mode 100644 index 0000000..845a901 Binary files /dev/null and b/docs/avatar-art/p5-linocut/base/edits/sheet.jpg differ diff --git a/docs/avatar-art/p5-linocut/base/normalize.json b/docs/avatar-art/p5-linocut/base/normalize.json new file mode 100644 index 0000000..6a680a5 --- /dev/null +++ b/docs/avatar-art/p5-linocut/base/normalize.json @@ -0,0 +1,66 @@ +{ + "canvas": { + "w": 1005, + "h": 1566 + }, + "reference": { + "image": "docs\\avatar-art\\p1-linocut\\base\\base-front.png", + "eyesCenter": [ + 492.69, + 584.33 + ], + "chin": [ + 500.61, + 919.55 + ], + "eyeDistance": 215.427, + "eyeChinDistance": 335.308 + }, + "input": { + "front": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\source-front.png", + "faceless": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\aligned-faceless-2.png", + "body": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\base\\edits\\aligned-body-2.png", + "frontSize": [ + 1145, + 1374 + ], + "eyesCenter": [ + 576.41, + 497.08 + ], + "chin": [ + 572.45, + 849.95 + ], + "eyeDistance": 215.702, + "eyeChinDistance": 352.891 + }, + "transform": { + "sHead": 0.974449, + "sWidth": 0.877729, + "s": 0.974449, + "rotationDeg": 0.0, + "offsetXNatural": -68.995, + "offsetXClampRange": [ + -110.745, + 0.0 + ], + "offsetX": -68.995, + "offsetY": 99.949 + }, + "coveredRange": { + "x": [ + 0.0, + 1005 + ], + "y": [ + 99.9, + 1438.8 + ] + }, + "inputSha256": { + "front": "a929adfeb240a1abb64302c9a31ab5a9911c93afd791fd91c8bda23c79144ac7", + "faceless": "c27e51dc63a5ae515bbfc918b8aad40c892f70e4cacbead4e416ce4453bec8bc", + "body": "fda852c1132d4338adb2e0e34c81ce824659282756edd2d700120c50e51ea089" + } +} \ No newline at end of file diff --git a/docs/avatar-art/p5-linocut/manifest.json b/docs/avatar-art/p5-linocut/manifest.json new file mode 100644 index 0000000..f117158 --- /dev/null +++ b/docs/avatar-art/p5-linocut/manifest.json @@ -0,0 +1,1683 @@ +{ + "landmarks": { + "coordSystem": "screen (image pixel: x=0 좌측, y=0 상단; left=작은 x, right=큰 x; 인물 해부학적 좌우 아님)", + "eyeLeft": { + "innerCorner": [ + 431.57, + 588.95 + ], + "outerCorner": [ + 343.75, + 578.52 + ], + "upperLidTop": [ + 381.91, + 566.75 + ], + "lowerLidBottom": [ + 383.03, + 593.99 + ], + "iris": { + "center": [ + 391.83, + 577.93 + ], + "radius": 19.8 + } + }, + "eyeRight": { + "innerCorner": [ + 553.91, + 588.17 + ], + "outerCorner": [ + 641.75, + 576.34 + ], + "upperLidTop": [ + 605.36, + 564.53 + ], + "lowerLidBottom": [ + 602.91, + 593.0 + ], + "iris": { + "center": [ + 595.29, + 577.62 + ], + "radius": 19.89 + } + }, + "eyebrowLeft": { + "inner": [ + 454.2, + 526.5 + ], + "peak": [ + 355.0, + 512.29 + ], + "outer": [ + 303.8, + 521.39 + ] + }, + "eyebrowRight": { + "inner": [ + 524.86, + 526.22 + ], + "peak": [ + 625.3, + 510.74 + ], + "outer": [ + 677.14, + 518.59 + ] + }, + "noseTip": [ + 493.15, + 693.89 + ], + "mouthCornerLeft": [ + 418.91, + 801.37 + ], + "mouthCornerRight": [ + 557.32, + 801.82 + ], + "upperLipTopCenter": [ + 490.87, + 759.43 + ], + "lowerLipBottomCenter": [ + 489.47, + 828.29 + ], + "chinTip": [ + 488.31, + 929.72 + ], + "faceWidthAtEyeLevelLeft": [ + 263.01, + 635.57 + ], + "faceWidthAtEyeLevelRight": [ + 719.75, + 635.96 + ] + }, + "landmarkDetector": "mediapipe FaceLandmarker (tasks) 1.0.1, model=face_landmarker(float16, v1)", + "pipelineRun": { + "persona": "P5", + "timestamp": "2026-10-01T22:02:14", + "completed": true, + "stages": [ + { + "stage": "brow_sprite", + "ok": true, + "elapsedSec": 2.78 + }, + { + "stage": "paper_grain", + "ok": true, + "elapsedSec": 2.26 + }, + { + "stage": "lip_texture", + "ok": true, + "elapsedSec": 2.14 + }, + { + "stage": "jaw_pieces", + "ok": true, + "elapsedSec": 2.11 + }, + { + "stage": "export_rig", + "ok": true, + "elapsedSec": 16.02 + }, + { + "stage": "final_previews", + "ok": true, + "elapsedSec": 19.23 + } + ] + }, + "browCenterline": { + "method": "Otsu(front lum in bbox) AND diff(F-front)>=25, morphological closing to merge hatching, single global degree-2 polyfit on column-weighted centroid with one-pass outlier removal", + "diffThresh": 25.0, + "bboxPad": { + "x": 25.0, + "yUp": 42.0, + "yDown": 14.0 + }, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "outlierStdMult": 2.0, + "edgeInsetFrac": 0.03, + "peakWindow": [ + 0.25, + 0.6 + ], + "peakFallbackFrac": 0.35, + "peakFlatHeightPx": 3.0, + "peakFailEdgeFrac": 0.2, + "oldPoints": { + "browLeft": { + "inner": [ + 450.26, + 535.21 + ], + "peak": [ + 353.7, + 497.84 + ], + "outer": [ + 300.84, + 526.38 + ] + }, + "browRight": { + "inner": [ + 539.17, + 534.15 + ], + "peak": [ + 636.28, + 497.52 + ], + "outer": [ + 687.12, + 526.6 + ] + } + }, + "newPoints": { + "browLeft": { + "name": "browLeft", + "bbox": [ + 276, + 456, + 475, + 549 + ], + "otsuThresh": 107.0, + "colRange": [ + 299, + 459 + ], + "width": 160.0, + "nColumns": 161, + "nOutliersRemoved": 5, + "fitCoeffs": [ + 0.00213457, + -1.58403406, + 805.60949545 + ], + "inner": [ + 454.2, + 526.5 + ], + "peak": [ + 355.0, + 512.29 + ], + "outer": [ + 303.8, + 521.39 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.9627, + "checkA_pass": true, + "halfWidthInner": 7.068, + "halfWidthPeak": 12.97, + "halfWidthOuter": 3.364, + "bandX0": 276, + "bandY0": 456, + "colMin": 299, + "colMax": 459 + }, + "browRight": { + "name": "browRight", + "bbox": [ + 514, + 456, + 712, + 548 + ], + "otsuThresh": 103.0, + "colRange": [ + 520, + 682 + ], + "width": 162.0, + "nColumns": 162, + "nOutliersRemoved": 10, + "fitCoeffs": [ + 0.00200644, + -2.46191027, + 1265.65200503 + ], + "inner": [ + 524.86, + 526.22 + ], + "peak": [ + 625.3, + 510.74 + ], + "outer": [ + 677.14, + 518.59 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.9012, + "checkA_pass": true, + "halfWidthInner": 2.12, + "halfWidthPeak": 12.985, + "halfWidthOuter": 1.938, + "bandX0": 514, + "bandY0": 456, + "colMin": 520, + "colMax": 682 + } + }, + "halfWidthLeft": [ + 7.068, + 12.97, + 3.364 + ], + "halfWidthRight": [ + 2.12, + 12.985, + 1.938 + ], + "halfWidthNote": "원화 눈썹 잉크 띠 반두께[inner,peak,outer](px, 중심선 법선 방향). export_rig.py가 persona.json browHalfWidthFromArt!=false(기본)면 RigBrow.halfWidth로 내보낸다.", + "checkB_innerMinusPeakY": { + "browLeft": 14.21, + "browRight": 15.48 + }, + "checkD_symmetry": { + "innerYDiff": 0.28, + "peakYDiff": 1.55 + }, + "evidenceImage": "preview/v2/brow-centerline.jpg" + }, + "schemaVersion": "vignette.avatar.v3.layers.v1", + "persona": "P5", + "canvas": { + "w": 1005, + "h": 1566 + }, + "base": { + "front": "base/base-front.png", + "faceless": "base/base-faceless.png", + "facelessPadded": "base/base-faceless-padded.png", + "facelessSize": [ + 1005, + 1566 + ], + "padNote": "base-faceless.png 마지막 행을 0번 복제해 1005x1566(base-front.png 크기)으로 패딩한 것이 F다." + }, + "segmenter": { + "model": "selfie_multiclass_256x256.tflite (mediapipe ImageSegmenter, storage.googleapis.com)", + "categories": { + "0": "background", + "1": "hair", + "2": "bodySkin", + "3": "faceSkin", + "4": "clothes", + "5": "others" + }, + "categoryPixelCounts": { + "0": 542067, + "1": 184962, + "2": 65918, + "3": 172849, + "4": 581666, + "5": 26368 + }, + "hairEdgeRefine": { + "dilatePx": 6, + "lumThreshold": 110, + "addedPixels": 6809 + } + }, + "chinLine": { + "landmarkIndex": 152, + "xy": [ + 488.31, + 929.72 + ], + "marginPx": 8, + "cutY": 937.72 + }, + "faceOval": { + "landmarkLoop": [ + 10, + 338, + 297, + 332, + 284, + 251, + 389, + 356, + 454, + 323, + 361, + 288, + 397, + 365, + 379, + 378, + 400, + 377, + 152, + 148, + 176, + 149, + 150, + 136, + 172, + 58, + 132, + 93, + 234, + 127, + 162, + 21, + 54, + 103, + 67, + 109 + ], + "scale": 1.04, + "sourceImage": "base/base-front.png" + }, + "layers": [ + { + "id": "body", + "file": "layers/body.png", + "source": "base-faceless-masked+regenerated-fill", + "alphaBBox": [ + 0, + 696, + 1005, + 1566 + ], + "opaquePixels": 674797, + "greenResidue": 0, + "fillTargetPixels": 22883, + "fillSourceRaw": "raw/body.png (rejected 재생성이 아니라 수용된 body.png의 크로마키 결과; head/hairFront와 달리 body 재생성은 승인됨)" + }, + { + "id": "head", + "file": "layers/head.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 149, + 125, + 816, + 964 + ], + "opaquePixels": 361315, + "greenResidue": 0 + }, + { + "id": "hairFront", + "file": "layers/hairFront.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 249, + 401, + 735, + 817 + ], + "opaquePixels": 26097, + "greenResidue": 0 + } + ], + "rejectedRawEdits": { + "body": { + "file": "raw/body.png", + "status": "accepted-as-fill-source", + "reason": "정렬 (0,0), 형태 변형 없음 — head_mask 채움 전용 소스로 재사용" + } + }, + "composite": { + "meanAbsDiff": { + "full": 1.243436711716005, + "face": 0.2742245656452269, + "hairOutline": 5.635600721411412 + }, + "target": { + "full": 3.0, + "pass": true + }, + "backgroundNote": "카테고리0(배경)은 종이결 텍스처 노이즈(표준편차 ~29/채널)를 포함해 평탄한 크림(#EEE5D3)과 자체적으로 평균절대차 ~7 차이가 난다." + }, + "layersV2": { + "chinBandFix": { + "targetRegionPixels": 20911, + "sourceBandHeight": 150, + "rowJitterRange": [ + -2.0, + 2.0 + ], + "rngSeed": 20260930 + }, + "hairEdgeFix": { + "bandOuterPx": 40, + "bandInnerPx": 6, + "lumSmoothstep": [ + 205.0, + 150.0 + ], + "minFragmentAreaPx": 60, + "head": { + "bandOuterPixels": 70561, + "bandInnerPixels": 23467, + "componentsBefore": 105, + "removed": 103, + "removedPixels": 923 + }, + "hairFront": { + "bandOuterPixels": 7722, + "bandInnerPixels": 15821, + "componentsBefore": 110, + "removed": 106, + "removedPixels": 404 + } + }, + "hairPaperGapFix": { + "regionDilatePx": 6, + "paperColorDistThreshold": 40.0, + "paperLumThreshold": 195.0, + "paperSatThreshold": 40.0, + "opaqueAlphaThreshold": 0.95, + "regionPixels": 195388, + "head": { + "targetPixels": 525, + "componentsBefore": 3, + "removed": 1, + "removedPixels": 1, + "faceSkinAlphaDiff": 0.0 + }, + "hairFront": { + "targetPixels": 1, + "componentsBefore": 4, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + } + }, + "jawInkFix": { + "mouthCenterY": 791.01, + "distThresholdPx": 14.0, + "mergePx": 3, + "aspectThreshold": 1.0, + "removedGroups": [], + "keptGroups": [ + { + "pixels": 349, + "bbox": [ + 292, + 792, + 314, + 833 + ], + "width": 22, + "height": 41, + "aspect": 0.537 + }, + { + "pixels": 231, + "bbox": [ + 670, + 792, + 689, + 825 + ], + "width": 19, + "height": 33, + "aspect": 0.576 + } + ], + "removedPixels": 0, + "strayFragmentCleanup": { + "componentsBefore": 4, + "removed": 0, + "removedPixels": 0 + } + }, + "metrics": { + "body": { + "haloPct": 0.012540757461750688 + }, + "head": { + "haloPct": 0.5167255915148219, + "bgLeakAlphaMean": 7.273158758317319e-06, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + }, + "hairFront": { + "haloPct": 0.021427040925648167, + "bgLeakAlphaMean": 0.0, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + } + }, + "layers": [ + { + "id": "body", + "bbox": [ + 0, + 696, + 1005, + 1566 + ], + "opaque": 674737, + "greenResidue": 0 + }, + { + "id": "head", + "bbox": [ + 144, + 118, + 832, + 964 + ], + "opaque": 363494, + "greenResidue": 0 + }, + { + "id": "hairFront", + "bbox": [ + 231, + 401, + 744, + 837 + ], + "opaque": 31688, + "greenResidue": 0 + } + ], + "faceDetail": { + "browLandmarksSource": "manifest.landmarks.eyebrowLeft/Right", + "region": "face", + "faceInsetPx": 24.0, + "matchFacelessColor": true, + "matchFacelessColorDeltaRgb": { + "eyeLeft": [ + -3.9, + -3.12, + -5.83 + ], + "eyeRight": [ + -2.81, + -1.58, + -3.64 + ], + "browLeft": [ + 1.08, + 1.94, + -0.54 + ], + "browRight": [ + 2.72, + 2.6, + -0.6 + ], + "mouth": [ + 1.12, + 2.15, + 0.21 + ] + }, + "regions": { + "eyeLeft": [ + 313.8, + 502.3, + 456.6, + 664.0 + ], + "eyeRight": [ + 528.9, + 500.7, + 671.8, + 663.0 + ], + "mouth": [ + 373.9, + 718.9, + 602.3, + 914.7 + ], + "moles": [] + }, + "exclusionPixels": { + "eyeLeft": 11010, + "eyeRight": 10929, + "browLeft": 12371, + "browRight": 12781, + "mouth": 19339, + "union": 61340 + }, + "hairMaskPixels": 200393, + "bbox": [ + 262, + 410, + 717, + 933 + ], + "textureCloneStamp": { + "cloneTargetThreshold": 65.0, + "avoidThreshold": 110.0, + "lineOpeningIterations": 3, + "featherPx": 4.0, + "badTexturePixels": 200, + "preservedShadowPixels": 0, + "components": [ + { + "componentId": 1, + "pixels": 10, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 2, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 3, + "pixels": 10, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 4, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 5, + "pixels": 23, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 6, + "pixels": 1, + "offset": [ + -100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 7, + "pixels": 1, + "offset": [ + -100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 8, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 9, + "pixels": 21, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 10, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 11, + "pixels": 1, + "offset": [ + 100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 12, + "pixels": 1, + "offset": [ + 100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 13, + "pixels": 1, + "offset": [ + -120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 14, + "pixels": 3, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 15, + "pixels": 4, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 16, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 17, + "pixels": 4, + "offset": [ + 80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 18, + "pixels": 12, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 19, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 20, + "pixels": 1, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 21, + "pixels": 1, + "offset": [ + 80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 22, + "pixels": 2, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 23, + "pixels": 10, + "offset": [ + 60, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 24, + "pixels": 12, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 25, + "pixels": 1, + "offset": [ + -120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 26, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 27, + "pixels": 3, + "offset": [ + 0, + 60 + ], + "method": "clone-stamp" + }, + { + "componentId": 28, + "pixels": 6, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 29, + "pixels": 2, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 30, + "pixels": 1, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 31, + "pixels": 1, + "offset": [ + 40, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 32, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 33, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 34, + "pixels": 4, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 35, + "pixels": 1, + "offset": [ + 100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 36, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 37, + "pixels": 1, + "offset": [ + 60, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 38, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 39, + "pixels": 2, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 40, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 41, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 42, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 43, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 44, + "pixels": 2, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 45, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 46, + "pixels": 1, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 47, + "pixels": 2, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 48, + "pixels": 2, + "offset": [ + 0, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 49, + "pixels": 4, + "offset": [ + 0, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 50, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 51, + "pixels": 9, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 52, + "pixels": 17, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 53, + "pixels": 3, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 54, + "pixels": 2, + "offset": [ + 0, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 55, + "pixels": 1, + "offset": [ + 60, + 0 + ], + "method": "clone-stamp" + } + ] + }, + "genericPatches": { + "forehead": [ + 427, + 427, + 475, + 475 + ], + "cheekLeft": [ + 315, + 641, + 363, + 689 + ], + "cheekRight": [ + 513, + 641, + 561, + 689 + ] + }, + "genericPatchBaseline": { + "highFreqEnergy": 12.290699434604397, + "lineEnergy": 5.573410843314015 + }, + "checkA_meanAbsDiff": 0.5169706474597274, + "checkB_seamLumDiff": 4.451138758843115, + "checkC_holeDarkResiduePct": 0.2609019754006709, + "checkC_violationPixels": 133, + "checkD_texturePreservation": { + "eyeLeft": { + "insideEnergy": 9.425555350978705, + "baselineEnergy": 12.290699434604397, + "ratio": 0.7668851883596718, + "pass": true + }, + "eyeRight": { + "insideEnergy": 9.216862851981398, + "baselineEnergy": 12.290699434604397, + "ratio": 0.7499054794254728, + "pass": true + }, + "browLeft": { + "insideEnergy": 12.002887950664995, + "baselineEnergy": 12.290699434604397, + "ratio": 0.9765829857388694, + "pass": true + }, + "browRight": { + "insideEnergy": 14.719453370459323, + "baselineEnergy": 12.290699434604397, + "ratio": 1.197609090416513, + "pass": true + }, + "mouth": { + "insideEnergy": 8.53175518777407, + "baselineEnergy": 12.290699434604397, + "ratio": 0.6941635204057599, + "pass": false + } + }, + "checkD_allPass": false, + "checkE_ghostOutline": { + "eyeLeft": { + "bandLineEnergy": 9.137192706471845, + "baselineLineEnergy": 5.573410843314015, + "ratio": 1.6394256521449555, + "pass": false + }, + "eyeRight": { + "bandLineEnergy": 8.752331751844649, + "baselineLineEnergy": 5.573410843314015, + "ratio": 1.5703726134498297, + "pass": false + }, + "browLeft": { + "bandLineEnergy": 7.052766801064451, + "baselineLineEnergy": 5.573410843314015, + "ratio": 1.265430989987954, + "pass": true + }, + "browRight": { + "bandLineEnergy": 11.933111816196243, + "baselineLineEnergy": 5.573410843314015, + "ratio": 2.141078802850406, + "pass": false + }, + "mouth": { + "bandLineEnergy": 4.056343043170454, + "baselineLineEnergy": 5.573410843314015, + "ratio": 0.7278026252158553, + "pass": true + } + }, + "checkE_allPass": false, + "checkDarkCircle": { + "eyeLeft": { + "compositeMean": 151.9087619047619, + "frontMean": 151.84533333333331, + "diff": 0.06342857142857383, + "pass": true + }, + "eyeRight": { + "compositeMean": 154.33238095238096, + "frontMean": 154.11866666666668, + "diff": 0.21371428571427487, + "pass": true + } + }, + "checkDarkCircle_allPass": true + }, + "paperGrain": { + "sourceImage": "base/base-front.png", + "sourceOrigin": [ + 739, + 10 + ], + "tileSize": 256, + "personMarginPx": 20, + "cleanFraction": 0.98876953125, + "contaminatedPixelsFilled": 736, + "chromaKeep": 0.3, + "targetLumRange": [ + 245.0, + 250.0 + ], + "lumShift": 21.50800069173178, + "finalMeanLum": 247.48452908064607, + "finalLumStd": 3.3447698831173556, + "seamContinuity": { + "leftRightDiff": 0.018985015006137473, + "topBottomDiff": 0.9613975569983685 + } + } + }, + "lipTexture": { + "designVersion": "A5(아랫입술 그늘 띠를 lip-shadow 조각으로 분리)", + "landmarks": { + "mouthCornerLeft": [ + 418.91, + 801.37 + ], + "mouthCornerRight": [ + 557.32, + 801.82 + ], + "upperLipTop": [ + 490.87, + 759.43 + ], + "lowerLipBottom": [ + 489.47, + 828.29 + ], + "mouthCenter": [ + 490.65367832779884, + 791.0127539634705 + ] + }, + "capBBox": [ + 407.12, + 758.86, + 569.12, + 828.86 + ], + "otsuThreshLabA": 139.0, + "diffThresh": 20.0, + "dilatePx": 10.0, + "alphaRampPx": 4.0, + "splitOverlapPx": 2.0, + "shadowBandPx": 18.0, + "shadowTopOverlapPx": 6.0, + "shadowSideRampPx": 6.0, + "shadowTopRampPx": 4.0, + "checks": { + "lip-upper": { + "regionPixelCount": 4380, + "fullOpacityPixelCount": 3701, + "rampPixelCount": 679, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 56, + 30, + 124, + 54 + ] + }, + "lip-lower": { + "regionPixelCount": 4907, + "fullOpacityPixelCount": 4223, + "rampPixelCount": 684, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 56, + 72, + 136, + 46 + ] + }, + "lip-shadow": { + "regionPixelCount": 2664, + "fullOpacityPixelCount": 1167, + "rampPixelCount": 1497, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 66, + 78, + 116, + 48 + ] + }, + "splitOverlapPixelCount": 236, + "splitOverlapBandOk": true, + "splitOverlapAlphaMaxDiff": 0, + "splitOverlapConsistentOk": true, + "splitCoverageMismatchPixelCount": 0, + "splitCheckOk": true, + "shadowLowerOverlapPixelCount": 1925, + "shadowLowerOverlapMaxDiff": 109.4890426758939, + "shadowLowerOverlapDiffGt1PixelCount": 110, + "shadowLowerOverlapOk": false + }, + "check3NeutralComposite": { + "fullOpacityMaxDiff": 0.0, + "rampMeanAbsDiff": 20.088, + "mouthBBoxMeanAbsDiff": 10.82 + }, + "pngFileSizes": { + "lip-upper": 19327, + "lip-lower": 17953, + "lip-shadow": 16440 + }, + "canvasOrigin": { + "upper": [ + 423, + 749 + ], + "lower": [ + 423, + 791 + ], + "shadow": [ + 433, + 797 + ] + }, + "evidenceImage": "preview/v2/lip-texture.jpg", + "check4WebpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jaw": { + "designVersion": "A5(결정문 §8.4 하관 띠 변형 — 턱 조각 원본)", + "noseTip": [ + 493.15, + 693.89 + ], + "chinTip": [ + 488.31, + 929.72 + ], + "yFormula": "noseTip.y - 50 - 10 .. chinTip.y + 40", + "noseToTopPx": 60.0, + "chinToBottomPx": 40.0, + "ovalOutsetPx": 18.0, + "faceOvalSource": "export_rig.detect_face_landmarks + compute_face_oval(base-front.png, 결정적)", + "bboxCanvas": [ + 236, + 633, + 748, + 970 + ], + "naiveXRangeForComparison": [ + 236, + 748 + ], + "checks": { + "head": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 376691 + }, + "detail": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 416696 + } + }, + "evidenceImage": "preview/v2/jaw-pieces.jpg", + "check1VsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.353, + "maxAbsDiffPremultipliedRgb": 40.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 2.178, + "maxAbsDiffPremultipliedRgb": 41.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + } + } + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 13726, + "lip-lower": 12934, + "lip-shadow": 12258 + }, + "totalBytes": 38918, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 34964, + "jaw-detail": 30114 + }, + "totalBytes": 65078, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.353, + "maxAbsDiffPremultipliedRgb": 40.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 2.178, + "maxAbsDiffPremultipliedRgb": 41.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + } + } + }, + "motifPublish": null, + "browSprite": { + "enabled": true, + "bandExtraHalfHeightPx": 8.0, + "bandEndExtendPx": 6.0, + "diffThresh": 25.0, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "hairSource": "layers/v2/hairFront.png alpha(게시되는 레이어 그 자체, 분할 카테고리 아님)", + "hairAlphaThresh": 128.0, + "hairDilateIterations": 1, + "rampPx": 1.5, + "inkLumMethod": "median(ink-classified pixels in band, region after hair removal)", + "minAlphaForUnmix": 0.05, + "hairMaskPixelCount": 36082, + "left": { + "bboxCanvas": [ + 299, + 495, + 161, + 48 + ], + "halfHeightPx": 20.97, + "otsuThresh": 108.0, + "lSkin": 175.333, + "lInk": 36.0, + "regionPixelCount": 3246, + "hairOverlapPixelCount": 121, + "neutralCompositeMeanAbsDiffAlphaRegion": 6.367, + "pngFileSizeBytes": 10174 + }, + "right": { + "bboxCanvas": [ + 520, + 495, + 162, + 44 + ], + "halfHeightPx": 20.985, + "otsuThresh": 107.0, + "lSkin": 174.333, + "lInk": 34.667, + "regionPixelCount": 2808, + "hairOverlapPixelCount": 186, + "neutralCompositeMeanAbsDiffAlphaRegion": 6.668, + "pngFileSizeBytes": 8822 + }, + "canvasOrigin": { + "left": [ + 299.0, + 495.0 + ], + "right": [ + 520.0, + 495.0 + ] + }, + "evidenceImage": "preview/v2/brow-sprite.jpg", + "checkWebpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "eyeLineScale": { + "enabled": true, + "method": "눈 폭 가운데 60% 열마다 upperLidTop.y-12 ~ 홍채중심y 사이 첫 연속 어두운(lum<80) 구간 길이의 중앙값", + "windowAbovePx": 12.0, + "darkLumThresh": 80.0, + "columnMiddleFrac": 0.6, + "p1BaselinePx": 2.0, + "lineScaleClampRange": [ + 1.0, + 2.5 + ], + "left": { + "measuredPx": 8.0, + "nColumns": 54, + "ratio": 4.0, + "lineScale": 2.5 + }, + "right": { + "measuredPx": 13.5, + "nColumns": 54, + "ratio": 6.75, + "lineScale": 2.5 + } + }, + "iris": { + "method": "가로: 중심 y 부근 상하 각 4행에서 중심 x를 포함하는 연속 어두운(lum<100) 구간의 중앙값으로 반지름·중심x. 세로: 중심 x 부근 좌우 각 4열에서 중심 y를 포함하는 연속 어두운 구간의 아래쪽 끝 중앙값에서 가로 반지름을 빼 중심y(세로축은 윗눈꺼풀 잉크와 홍채가 같은 톤으로 이어져 위쪽 경계를 가를 수 없다).", + "darkLumThresh": 100.0, + "scanBandPx": 4, + "left": { + "measuredCenter": [ + 387.5, + 574.5 + ], + "measuredRadius": 18.5, + "rigCenter": [ + 391.83, + 577.93 + ], + "rigRadius": 19.8, + "nRowsHorizontal": 8, + "nColsVertical": 9 + }, + "right": { + "measuredCenter": [ + 594.0, + 573.0 + ], + "measuredRadius": 18.0, + "rigCenter": [ + 595.29, + 577.62 + ], + "rigRadius": 19.89, + "nRowsHorizontal": 9, + "nColsVertical": 9 + } + }, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 6584, + "brow-right": 5736 + }, + "totalBytes": 12320, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p5-linocut/persona.json b/docs/avatar-art/p5-linocut/persona.json new file mode 100644 index 0000000..ae1fb27 --- /dev/null +++ b/docs/avatar-art/p5-linocut/persona.json @@ -0,0 +1,37 @@ +{ + "code": "P5", + "publicSlug": "p5", + "rigFileName": "p5Rig.ts", + "rigExportName": "P5_LINOCUT_RIG", + "styleFrame": "../art-direction-v3/p1/r2-b-linocut.png", + "paletteSamples": { + "ink": { + "box": [260, 245, 660, 330], + "lumThreshold": 55 + }, + "motifPetalBoxes": [ + { "label": "sun", "kind": "ochre", "box": [1230, 10, 1536, 210] }, + { "label": "tulip", "kind": "ochre", "box": [1030, 280, 1170, 560] } + ], + "motifLeafBoxes": [ + { "label": "cloudLeft", "kind": "blue", "box": [20, 20, 380, 190] }, + { "label": "raincloud", "kind": "blue", "box": [520, 10, 930, 230] }, + { "label": "wiltedFlowerLeaf", "kind": "blue", "box": [520, 280, 650, 580] }, + { "label": "closedBudLeaf", "kind": "blue", "box": [10, 290, 110, 570] } + ] + }, + "faceDetail": { + "moles": [], + "region": "face", + "faceInsetPx": 24, + "matchFacelessColor": true + }, + "pivots": { + "neck": [488, 1001], + "body": [502, 1566], + "face": [490, 659] + }, + "crops": { + "bustYOffset": 40 + } +} diff --git a/docs/avatar-art/p5-linocut/preview/qa/face-art-vs-render.jpg b/docs/avatar-art/p5-linocut/preview/qa/face-art-vs-render.jpg new file mode 100644 index 0000000..ffc5ba6 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/qa/face-art-vs-render.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/qa/face-zoom.jpg b/docs/avatar-art/p5-linocut/preview/qa/face-zoom.jpg new file mode 100644 index 0000000..93f2c01 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/qa/face-zoom.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/qa/neutral-vs-art.jpg b/docs/avatar-art/p5-linocut/preview/qa/neutral-vs-art.jpg new file mode 100644 index 0000000..9e3c101 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/qa/neutral-vs-art.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/qa/normalized.jpg b/docs/avatar-art/p5-linocut/preview/qa/normalized.jpg new file mode 100644 index 0000000..662cbd5 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/qa/normalized.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/qa/pad-check.jpg b/docs/avatar-art/p5-linocut/preview/qa/pad-check.jpg new file mode 100644 index 0000000..66c9b5a Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/qa/pad-check.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/qa/sheet-expr-bust.jpg b/docs/avatar-art/p5-linocut/preview/qa/sheet-expr-bust.jpg new file mode 100644 index 0000000..71fdaf6 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/qa/sheet-expr-bust.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/qa/sheet-expr-face.jpg b/docs/avatar-art/p5-linocut/preview/qa/sheet-expr-face.jpg new file mode 100644 index 0000000..20357ed Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/qa/sheet-expr-face.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/qa/sheet-viseme.jpg b/docs/avatar-art/p5-linocut/preview/qa/sheet-viseme.jpg new file mode 100644 index 0000000..e066603 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/qa/sheet-viseme.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/qa/viseme-timeline.json b/docs/avatar-art/p5-linocut/preview/qa/viseme-timeline.json new file mode 100644 index 0000000..d0b2bce --- /dev/null +++ b/docs/avatar-art/p5-linocut/preview/qa/viseme-timeline.json @@ -0,0 +1,287 @@ +[ + { + "t": 0, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00000.png" + }, + { + "t": 50, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00050.png" + }, + { + "t": 100, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00100.png" + }, + { + "t": 150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00150.png" + }, + { + "t": 200, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00200.png" + }, + { + "t": 250, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00250.png" + }, + { + "t": 300, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00300.png" + }, + { + "t": 350, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00350.png" + }, + { + "t": 400, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00400.png" + }, + { + "t": 450, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00450.png" + }, + { + "t": 500, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00500.png" + }, + { + "t": 550, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00550.png" + }, + { + "t": 600, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00600.png" + }, + { + "t": 650, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00650.png" + }, + { + "t": 700, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00700.png" + }, + { + "t": 750, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00750.png" + }, + { + "t": 800, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00800.png" + }, + { + "t": 850, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00850.png" + }, + { + "t": 900, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00900.png" + }, + { + "t": 950, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t00950.png" + }, + { + "t": 1000, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01000.png" + }, + { + "t": 1050, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01050.png" + }, + { + "t": 1100, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01100.png" + }, + { + "t": 1150, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01150.png" + }, + { + "t": 1200, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01200.png" + }, + { + "t": 1250, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01250.png" + }, + { + "t": 1300, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01300.png" + }, + { + "t": 1350, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01350.png" + }, + { + "t": 1400, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01400.png" + }, + { + "t": 1450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01450.png" + }, + { + "t": 1500, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01500.png" + }, + { + "t": 1550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01550.png" + }, + { + "t": 1600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01600.png" + }, + { + "t": 1650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01650.png" + }, + { + "t": 1700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01700.png" + }, + { + "t": 1750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01750.png" + }, + { + "t": 1800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01800.png" + }, + { + "t": 1850, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01850.png" + }, + { + "t": 1900, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01900.png" + }, + { + "t": 1950, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t01950.png" + }, + { + "t": 2000, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02000.png" + }, + { + "t": 2050, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02050.png" + }, + { + "t": 2100, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02100.png" + }, + { + "t": 2150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02150.png" + }, + { + "t": 2200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02200.png" + }, + { + "t": 2250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02250.png" + }, + { + "t": 2300, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02300.png" + }, + { + "t": 2350, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02350.png" + }, + { + "t": 2400, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02400.png" + }, + { + "t": 2450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02450.png" + }, + { + "t": 2500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02500.png" + }, + { + "t": 2550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02550.png" + }, + { + "t": 2600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02600.png" + }, + { + "t": 2650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02650.png" + }, + { + "t": 2700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02700.png" + }, + { + "t": 2750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02750.png" + }, + { + "t": 2800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p5-linocut\\preview\\qa\\frames\\viseme-scan-t02800.png" + } +] \ No newline at end of file diff --git a/docs/avatar-art/p5-linocut/preview/v2/brow-centerline.jpg b/docs/avatar-art/p5-linocut/preview/v2/brow-centerline.jpg new file mode 100644 index 0000000..1569852 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/v2/brow-centerline.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/v2/brow-sprite.jpg b/docs/avatar-art/p5-linocut/preview/v2/brow-sprite.jpg new file mode 100644 index 0000000..dc6adfa Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/v2/brow-sprite.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/v2/export-rig-report.json b/docs/avatar-art/p5-linocut/preview/v2/export-rig-report.json new file mode 100644 index 0000000..65cad9c --- /dev/null +++ b/docs/avatar-art/p5-linocut/preview/v2/export-rig-report.json @@ -0,0 +1,676 @@ +{ + "faceOvalBBox": [ + 251.6, + 403.0, + 732.9, + 939.9 + ], + "cropsFace": [ + 191.6, + 370.8, + 601.3, + 601.3 + ], + "mouthCenter": [ + 490.7, + 791.0 + ], + "palette": { + "ink": "#222221", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#B1845F", + "lipLower": "#CC926C", + "mouthLine": "#A5694F", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "paletteSamples": { + "eyeLeft": { + "sclera": "#DAAC7D", + "iris": "#262625", + "irisRing": "#AC8660", + "n": { + "sclera": 1011, + "iris": 175, + "irisRing": 366 + } + }, + "eyeRight": { + "sclera": "#DDAD7C", + "iris": "#252423", + "irisRing": "#D6A676", + "n": { + "sclera": 1122, + "iris": 179, + "irisRing": 366 + } + }, + "scleraIrisIrisRingFixedOverride": { + "reason": "persona.json paletteSamples.eyeOverride(고정 설계값)", + "measured": { + "sclera": "#DCAC7C", + "iris": "#262524", + "irisRing": "#C1966B" + }, + "fixed": { + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F" + } + }, + "ink": { + "box": [ + 260, + 245, + 660, + 330 + ], + "lumThreshold": 55.0, + "n": 27060, + "hex": "#222221" + }, + "lipUpper": { + "box": [ + 413, + 756, + 562, + 789 + ], + "hex": "#B1845F" + }, + "lipLower": { + "box": [ + 413, + 793, + 562, + 831 + ], + "hex": "#CC926C" + }, + "mouthLine": { + "box": [ + 433, + 789, + 542, + 794 + ], + "hex": "#A5694F" + }, + "motifPetal": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "sun": { + "box": [ + 1230, + 10, + 1536, + 210 + ], + "n": 20570, + "hex": "#D3A661" + }, + "tulip": { + "box": [ + 1030, + 280, + 1170, + 560 + ], + "n": 4314, + "hex": "#CCA063" + } + }, + "hex": "#D0A362" + }, + "motifLeaf": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "cloudLeft": { + "box": [ + 20, + 20, + 380, + 190 + ], + "n": 21312, + "hex": "#636D76" + }, + "raincloud": { + "box": [ + 520, + 10, + 930, + 230 + ], + "n": 27607, + "hex": "#586B76" + }, + "wiltedFlowerLeaf": { + "box": [ + 520, + 280, + 650, + 580 + ], + "n": 5818, + "hex": "#495961" + }, + "closedBudLeaf": { + "box": [ + 10, + 290, + 110, + 570 + ], + "n": 6589, + "hex": "#495961" + } + }, + "hex": "#53626C" + } + }, + "publish": { + "fileSizes": { + "body": 142558, + "head": 102774, + "hair-front": 23854, + "face-detail": 49332, + "paper-grain": 1452 + }, + "encodeMeta": { + "quality": 80, + "scale": 1.0, + "totalBytes": 319970 + }, + "totalBytes": 319970 + }, + "grain": { + "href": "/avatar/v3/p5/paper-grain.webp", + "size": 256 + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 13726, + "lip-lower": 12934, + "lip-shadow": 12258 + }, + "totalBytes": 38918, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 34964, + "jaw-detail": 30114 + }, + "totalBytes": 65078, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.353, + "maxAbsDiffPremultipliedRgb": 40.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 2.178, + "maxAbsDiffPremultipliedRgb": 41.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + } + } + }, + "motifPublish": null, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 6584, + "brow-right": 5736 + }, + "totalBytes": 12320, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "rig": { + "schemaVersion": "vignette.avatar.v3.rig.v1", + "persona": "P5", + "canvas": { + "w": 1005, + "h": 1566 + }, + "layers": { + "body": { + "href": "/avatar/v3/p5/body.webp", + "x": 0, + "y": 696, + "w": 1005, + "h": 870 + }, + "head": { + "href": "/avatar/v3/p5/head.webp", + "x": 144, + "y": 118, + "w": 688, + "h": 846 + }, + "hairFront": { + "href": "/avatar/v3/p5/hair-front.webp", + "x": 231, + "y": 401, + "w": 513, + "h": 436 + }, + "faceDetail": { + "href": "/avatar/v3/p5/face-detail.webp", + "x": 262, + "y": 410, + "w": 455, + "h": 523 + } + }, + "grain": { + "href": "/avatar/v3/p5/paper-grain.webp", + "size": 256 + }, + "lipTexture": { + "upper": { + "href": "/avatar/v3/p5/lip-upper.webp", + "x": 423, + "y": 749, + "w": 124, + "h": 54 + }, + "lower": { + "href": "/avatar/v3/p5/lip-lower.webp", + "x": 423, + "y": 791, + "w": 136, + "h": 46 + }, + "shadow": { + "href": "/avatar/v3/p5/lip-shadow.webp", + "x": 433, + "y": 797, + "w": 116, + "h": 48 + } + }, + "jaw": { + "head": { + "href": "/avatar/v3/p5/jaw-head.webp", + "x": 236, + "y": 633, + "w": 512, + "h": 337 + }, + "detail": { + "href": "/avatar/v3/p5/jaw-detail.webp", + "x": 236, + "y": 633, + "w": 512, + "h": 337 + } + }, + "motif": null, + "pivots": { + "neck": [ + 488, + 1001 + ], + "body": [ + 502, + 1566 + ], + "face": [ + 490, + 659 + ] + }, + "crops": { + "portrait": [ + 0, + 0, + 1005, + 1566 + ], + "bust": [ + 0.0, + 40.0, + 1005.0, + 1005.0 + ], + "face": [ + 191.593571319131, + 370.8326851064444, + 601.2719892333985, + 601.2719892333985 + ] + }, + "faceOval": [ + [ + 496.1, + 403.0 + ], + [ + 564.0, + 405.0 + ], + [ + 621.1, + 414.5 + ], + [ + 672.8, + 434.4 + ], + [ + 705.1, + 464.2 + ], + [ + 723.6, + 501.7 + ], + [ + 732.1, + 541.0 + ], + [ + 732.9, + 589.2 + ], + [ + 728.9, + 634.4 + ], + [ + 723.7, + 681.0 + ], + [ + 714.5, + 730.1 + ], + [ + 698.1, + 782.2 + ], + [ + 675.7, + 823.6 + ], + [ + 650.1, + 853.0 + ], + [ + 619.0, + 879.9 + ], + [ + 592.9, + 900.0 + ], + [ + 565.2, + 919.2 + ], + [ + 531.9, + 934.8 + ], + [ + 488.2, + 939.9 + ], + [ + 444.8, + 934.7 + ], + [ + 411.7, + 918.9 + ], + [ + 384.1, + 899.3 + ], + [ + 358.4, + 879.0 + ], + [ + 328.1, + 851.8 + ], + [ + 303.5, + 822.2 + ], + [ + 281.3, + 781.3 + ], + [ + 265.8, + 729.0 + ], + [ + 257.4, + 680.0 + ], + [ + 253.9, + 634.0 + ], + [ + 251.6, + 589.2 + ], + [ + 255.3, + 541.7 + ], + [ + 265.7, + 502.0 + ], + [ + 286.1, + 464.7 + ], + [ + 319.6, + 435.0 + ], + [ + 371.3, + 414.7 + ], + [ + 428.2, + 405.3 + ] + ], + "landmarks": { + "eyeLeft": { + "inner": [ + 431.6, + 589.0 + ], + "outer": [ + 343.8, + 578.5 + ], + "upperLidTop": [ + 381.9, + 566.8 + ], + "lowerLidBottom": [ + 383.0, + 594.0 + ], + "iris": { + "center": [ + 387.5, + 574.5 + ], + "radius": 18.5 + }, + "lineScale": 2.5 + }, + "eyeRight": { + "inner": [ + 553.9, + 588.2 + ], + "outer": [ + 641.8, + 576.3 + ], + "upperLidTop": [ + 605.4, + 564.5 + ], + "lowerLidBottom": [ + 602.9, + 593.0 + ], + "iris": { + "center": [ + 594.0, + 573.0 + ], + "radius": 18.0 + }, + "lineScale": 2.5 + }, + "browLeft": { + "inner": [ + 454.2, + 526.5 + ], + "peak": [ + 355.0, + 512.3 + ], + "outer": [ + 303.8, + 521.4 + ], + "halfWidth": [ + 7.07, + 12.97, + 3.36 + ], + "sprite": { + "href": "/avatar/v3/p5/brow-left.webp", + "x": 299.0, + "y": 495.0, + "w": 161, + "h": 48 + } + }, + "browRight": { + "inner": [ + 524.9, + 526.2 + ], + "peak": [ + 625.3, + 510.7 + ], + "outer": [ + 677.1, + 518.6 + ], + "halfWidth": [ + 2.12, + 12.98, + 1.94 + ], + "sprite": { + "href": "/avatar/v3/p5/brow-right.webp", + "x": 520.0, + "y": 495.0, + "w": 162, + "h": 44 + } + }, + "noseTip": [ + 493.1, + 693.9 + ], + "mouthCornerLeft": [ + 418.9, + 801.4 + ], + "mouthCornerRight": [ + 557.3, + 801.8 + ], + "upperLipTop": [ + 490.9, + 759.4 + ], + "lowerLipBottom": [ + 489.5, + 828.3 + ], + "mouthCenter": [ + 490.7, + 791.0 + ], + "chinTip": [ + 488.3, + 929.7 + ] + }, + "palette": { + "ink": "#222221", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#B1845F", + "lipLower": "#CC926C", + "mouthLine": "#A5694F", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "backdrop": { + "cognitive": "#ECE3D1", + "positive": "#F1DEC2", + "negative": "#DCE0E2", + "defensive": "#E6DAD3", + "energy": "#E2E0D0" + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p5-linocut/preview/v2/ghost-check.jpg b/docs/avatar-art/p5-linocut/preview/v2/ghost-check.jpg new file mode 100644 index 0000000..ffb0f8f Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/v2/ghost-check.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/v2/holes-texture.jpg b/docs/avatar-art/p5-linocut/preview/v2/holes-texture.jpg new file mode 100644 index 0000000..51e1100 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/v2/holes-texture.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/v2/jaw-pieces.jpg b/docs/avatar-art/p5-linocut/preview/v2/jaw-pieces.jpg new file mode 100644 index 0000000..a6fc626 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/v2/jaw-pieces.jpg differ diff --git a/docs/avatar-art/p5-linocut/preview/v2/lip-texture.jpg b/docs/avatar-art/p5-linocut/preview/v2/lip-texture.jpg new file mode 100644 index 0000000..3ffa2a0 Binary files /dev/null and b/docs/avatar-art/p5-linocut/preview/v2/lip-texture.jpg differ diff --git a/docs/avatar-art/p5-linocut/prompts/base-faceless.txt b/docs/avatar-art/p5-linocut/prompts/base-faceless.txt new file mode 100644 index 0000000..17718c4 --- /dev/null +++ b/docs/avatar-art/p5-linocut/prompts/base-faceless.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as faceless.png: + +Redraw exactly the same boy, same frontal pose, same framing and same linocut relief-print style as the reference, but leave the face blank: remove the eyes, eyebrows and mouth completely and fill those areas with plain skin in the same flat skin color, keeping the nose, the face outline, the ears, the hair, the neck, the grey t-shirt, the black zip-up track jacket and the white wired earphones exactly as they are. Do not move, resize or redraw anything else. Plain flat cream background, nothing else, no text. diff --git a/docs/avatar-art/p5-linocut/prompts/body.txt b/docs/avatar-art/p5-linocut/prompts/body.txt new file mode 100644 index 0000000..70d20e0 --- /dev/null +++ b/docs/avatar-art/p5-linocut/prompts/body.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as body.png: + +Keep only the neck, the grey t-shirt, the black zip-up track jacket and the parts of the white earphone cords that lie on the jacket exactly as they are in the reference: same shapes, same position, same linocut relief-print style, same ink colors and texture. Remove the head, the face, the ears and all of the hair completely. Where the hair or the chin previously covered the neck or the clothes, continue them naturally in the same style so there are no holes. Place the result on a plain flat pure green background (#00ff00) with nothing else, no text. diff --git a/docs/avatar-art/p5-linocut/raw/body.png b/docs/avatar-art/p5-linocut/raw/body.png new file mode 100644 index 0000000..9f06840 Binary files /dev/null and b/docs/avatar-art/p5-linocut/raw/body.png differ diff --git a/docs/avatar-art/p6-linocut/base/base-faceless.png b/docs/avatar-art/p6-linocut/base/base-faceless.png new file mode 100644 index 0000000..64039b0 Binary files /dev/null and b/docs/avatar-art/p6-linocut/base/base-faceless.png differ diff --git a/docs/avatar-art/p6-linocut/base/base-front.png b/docs/avatar-art/p6-linocut/base/base-front.png new file mode 100644 index 0000000..ab797d5 Binary files /dev/null and b/docs/avatar-art/p6-linocut/base/base-front.png differ diff --git a/docs/avatar-art/p6-linocut/base/edits/aligned-body-1.json b/docs/avatar-art/p6-linocut/base/edits/aligned-body-1.json new file mode 100644 index 0000000..12ecd9c --- /dev/null +++ b/docs/avatar-art/p6-linocut/base/edits/aligned-body-1.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\body-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\aligned-body-1.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.78033, + "transform": { + "scaleSqrtDet": 1.00045, + "rotationDeg": -0.002, + "translateX": -0.468, + "translateY": -2.06, + "matrix": [ + [ + 0.999511, + 0.000548, + -0.468036 + ], + [ + -3.8e-05, + 1.001399, + -2.060432 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 478631, + "chamferInMask": { + "median": 0.0, + "p90": 1.414, + "nSamples": 80775 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p6-linocut/base/edits/aligned-body-2.json b/docs/avatar-art/p6-linocut/base/edits/aligned-body-2.json new file mode 100644 index 0000000..2a9d1da --- /dev/null +++ b/docs/avatar-art/p6-linocut/base/edits/aligned-body-2.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\body-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\aligned-body-2.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.76917, + "transform": { + "scaleSqrtDet": 1.00098, + "rotationDeg": 0.002, + "translateX": -0.523, + "translateY": -3.41, + "matrix": [ + [ + 0.99945, + 0.000442, + -0.523264 + ], + [ + 3.3e-05, + 1.002504, + -3.409868 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 480048, + "chamferInMask": { + "median": 0.0, + "p90": 2.0, + "nSamples": 82384 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p6-linocut/base/edits/aligned-faceless-1.json b/docs/avatar-art/p6-linocut/base/edits/aligned-faceless-1.json new file mode 100644 index 0000000..ab9a956 --- /dev/null +++ b/docs/avatar-art/p6-linocut/base/edits/aligned-faceless-1.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\faceless-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\aligned-faceless-1.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.99634, + "transform": { + "scaleSqrtDet": 0.99986, + "rotationDeg": 0.0, + "translateX": -0.3, + "translateY": -0.333, + "matrix": [ + [ + 0.999866, + -1.6e-05, + -0.299886 + ], + [ + 8e-06, + 0.999857, + -0.333271 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 884598, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 148881 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 6403 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 390, + 488, + 535, + 574 + ], + "refInkRatio": 0.2302, + "editedInkRatio": 0.0 + }, + "eyeB": { + "box": [ + 606, + 478, + 750, + 564 + ], + "refInkRatio": 0.2649, + "editedInkRatio": 0.0232 + }, + "browA": { + "box": [ + 351, + 423, + 546, + 514 + ], + "refInkRatio": 0.3136, + "editedInkRatio": 0.1598 + }, + "browB": { + "box": [ + 587, + 412, + 783, + 506 + ], + "refInkRatio": 0.4015, + "editedInkRatio": 0.2383 + }, + "mouth": { + "box": [ + 476, + 709, + 680, + 823 + ], + "refInkRatio": 0.0804, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 390, + 488, + 535, + 574 + ], + "eyeB": [ + 606, + 478, + 750, + 564 + ], + "browA": [ + 351, + 423, + 546, + 514 + ], + "browB": [ + 587, + 412, + 783, + 506 + ], + "mouth": [ + 476, + 709, + 680, + 823 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p6-linocut/base/edits/aligned-faceless-2.json b/docs/avatar-art/p6-linocut/base/edits/aligned-faceless-2.json new file mode 100644 index 0000000..382b1e4 --- /dev/null +++ b/docs/avatar-art/p6-linocut/base/edits/aligned-faceless-2.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\faceless-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\aligned-faceless-2.png", + "refSize": [ + 1145, + 1374 + ], + "editedOriginalSize": [ + 1145, + 1374 + ], + "eccCorrelation": 0.99628, + "transform": { + "scaleSqrtDet": 0.99981, + "rotationDeg": 0.001, + "translateX": -0.117, + "translateY": -0.47, + "matrix": [ + [ + 0.999689, + -2.3e-05, + -0.116897 + ], + [ + 2.1e-05, + 0.999929, + -0.469733 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 884598, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 150035 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 6389 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 390, + 488, + 535, + 574 + ], + "refInkRatio": 0.2302, + "editedInkRatio": 0.0 + }, + "eyeB": { + "box": [ + 606, + 478, + 750, + 564 + ], + "refInkRatio": 0.2649, + "editedInkRatio": 0.0207 + }, + "browA": { + "box": [ + 351, + 423, + 546, + 514 + ], + "refInkRatio": 0.3136, + "editedInkRatio": 0.1554 + }, + "browB": { + "box": [ + 587, + 412, + 783, + 506 + ], + "refInkRatio": 0.4015, + "editedInkRatio": 0.2278 + }, + "mouth": { + "box": [ + 476, + 709, + 680, + 823 + ], + "refInkRatio": 0.0804, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 390, + 488, + 535, + 574 + ], + "eyeB": [ + 606, + 478, + 750, + 564 + ], + "browA": [ + 351, + 423, + 546, + 514 + ], + "browB": [ + 587, + 412, + 783, + 506 + ], + "mouth": [ + 476, + 709, + 680, + 823 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p6-linocut/base/edits/sheet.jpg b/docs/avatar-art/p6-linocut/base/edits/sheet.jpg new file mode 100644 index 0000000..5b66dc1 Binary files /dev/null and b/docs/avatar-art/p6-linocut/base/edits/sheet.jpg differ diff --git a/docs/avatar-art/p6-linocut/base/normalize.json b/docs/avatar-art/p6-linocut/base/normalize.json new file mode 100644 index 0000000..390c240 --- /dev/null +++ b/docs/avatar-art/p6-linocut/base/normalize.json @@ -0,0 +1,66 @@ +{ + "canvas": { + "w": 1005, + "h": 1566 + }, + "reference": { + "image": "docs\\avatar-art\\p1-linocut\\base\\base-front.png", + "eyesCenter": [ + 492.69, + 584.33 + ], + "chin": [ + 500.61, + 919.55 + ], + "eyeDistance": 215.427, + "eyeChinDistance": 335.308 + }, + "input": { + "front": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\source-front.png", + "faceless": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\aligned-faceless-2.png", + "body": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\base\\edits\\aligned-body-1.png", + "frontSize": [ + 1145, + 1374 + ], + "eyesCenter": [ + 570.22, + 532.03 + ], + "chin": [ + 583.57, + 891.58 + ], + "eyeDistance": 215.577, + "eyeChinDistance": 359.799 + }, + "transform": { + "sHead": 0.965618, + "sWidth": 0.877729, + "s": 0.965618, + "rotationDeg": 0.0, + "offsetXNatural": -57.922, + "offsetXClampRange": [ + -100.632, + 0.0 + ], + "offsetX": -57.922, + "offsetY": 70.594 + }, + "coveredRange": { + "x": [ + 0.0, + 1005 + ], + "y": [ + 70.6, + 1397.4 + ] + }, + "inputSha256": { + "front": "cd4ec9305f7d8b54ad9ed0b9e7bb6c3b9f2cc71d57783854dbd21727a0d8a542", + "faceless": "2cfeb265c33dfcb714c955f831d3c0f2a87cf0518d368f0b47e873640414157b", + "body": "5e544ce3daefa7781f7aadeb7a3886c3b54707a2f0e3a0211666b0a71ee6db88" + } +} \ No newline at end of file diff --git a/docs/avatar-art/p6-linocut/manifest.json b/docs/avatar-art/p6-linocut/manifest.json new file mode 100644 index 0000000..e68d15a --- /dev/null +++ b/docs/avatar-art/p6-linocut/manifest.json @@ -0,0 +1,1346 @@ +{ + "landmarks": { + "coordSystem": "screen (image pixel: x=0 좌측, y=0 상단; left=작은 x, right=큰 x; 인물 해부학적 좌우 아님)", + "eyeLeft": { + "innerCorner": [ + 432.37, + 593.74 + ], + "outerCorner": [ + 341.43, + 583.87 + ], + "upperLidTop": [ + 378.12, + 565.98 + ], + "lowerLidBottom": [ + 383.39, + 600.15 + ], + "iris": { + "center": [ + 388.77, + 581.09 + ], + "radius": 20.65 + } + }, + "eyeRight": { + "innerCorner": [ + 548.91, + 589.6 + ], + "outerCorner": [ + 639.76, + 570.83 + ], + "upperLidTop": [ + 601.39, + 555.92 + ], + "lowerLidBottom": [ + 598.38, + 591.82 + ], + "iris": { + "center": [ + 594.19, + 571.71 + ], + "radius": 20.75 + } + }, + "eyebrowLeft": { + "inner": [ + 451.92, + 530.26 + ], + "peak": [ + 367.6, + 517.35 + ], + "outer": [ + 324.08, + 521.47 + ] + }, + "eyebrowRight": { + "inner": [ + 518.29, + 525.41 + ], + "peak": [ + 606.95, + 510.29 + ], + "outer": [ + 652.71, + 515.57 + ] + }, + "noseTip": [ + 495.58, + 716.54 + ], + "mouthCornerLeft": [ + 423.83, + 811.05 + ], + "mouthCornerRight": [ + 575.09, + 805.14 + ], + "upperLipTopCenter": [ + 498.47, + 778.0 + ], + "lowerLipBottomCenter": [ + 501.51, + 841.17 + ], + "chinTip": [ + 506.07, + 930.63 + ], + "faceWidthAtEyeLevelLeft": [ + 274.49, + 635.04 + ], + "faceWidthAtEyeLevelRight": [ + 708.42, + 617.94 + ] + }, + "landmarkDetector": "mediapipe FaceLandmarker (tasks) 1.0.1, model=face_landmarker(float16, v1)", + "pipelineRun": { + "persona": "P6", + "timestamp": "2026-10-01T22:02:58", + "completed": true, + "stages": [ + { + "stage": "brow_sprite", + "ok": true, + "elapsedSec": 2.67 + }, + { + "stage": "paper_grain", + "ok": true, + "elapsedSec": 2.23 + }, + { + "stage": "lip_texture", + "ok": true, + "elapsedSec": 2.14 + }, + { + "stage": "jaw_pieces", + "ok": true, + "elapsedSec": 2.12 + }, + { + "stage": "export_rig", + "ok": true, + "elapsedSec": 15.98 + }, + { + "stage": "final_previews", + "ok": true, + "elapsedSec": 19.27 + } + ] + }, + "browCenterline": { + "method": "Otsu(front lum in bbox) AND diff(F-front)>=25, morphological closing to merge hatching, single global degree-2 polyfit on column-weighted centroid with one-pass outlier removal", + "diffThresh": 25.0, + "bboxPad": { + "x": 25.0, + "yUp": 42.0, + "yDown": 14.0 + }, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "outlierStdMult": 2.0, + "edgeInsetFrac": 0.03, + "peakWindow": [ + 0.25, + 0.6 + ], + "peakFallbackFrac": 0.35, + "peakFlatHeightPx": 3.0, + "peakFailEdgeFrac": 0.2, + "oldPoints": { + "browLeft": { + "inner": [ + 444.36, + 539.65 + ], + "peak": [ + 348.93, + 502.68 + ], + "outer": [ + 300.84, + 531.41 + ] + }, + "browRight": { + "inner": [ + 532.29, + 536.84 + ], + "peak": [ + 623.51, + 491.68 + ], + "outer": [ + 674.23, + 515.8 + ] + } + }, + "newPoints": { + "browLeft": { + "name": "browLeft", + "bbox": [ + 276, + 461, + 469, + 554 + ], + "otsuThresh": 110.0, + "colRange": [ + 320, + 456 + ], + "width": 136.0, + "nColumns": 137, + "nOutliersRemoved": 10, + "fitCoeffs": [ + 0.00193771, + -1.43485171, + 782.95866324 + ], + "inner": [ + 451.92, + 530.26 + ], + "peak": [ + 367.6, + 517.35 + ], + "outer": [ + 324.08, + 521.47 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.9854, + "checkA_pass": true, + "halfWidthInner": 15.731, + "halfWidthPeak": 10.999, + "halfWidthOuter": 7.875, + "bandX0": 276, + "bandY0": 461, + "colMin": 320, + "colMax": 456 + }, + "browRight": { + "name": "browRight", + "bbox": [ + 507, + 450, + 699, + 551 + ], + "otsuThresh": 107.0, + "colRange": [ + 514, + 657 + ], + "width": 143.0, + "nColumns": 144, + "nOutliersRemoved": 8, + "fitCoeffs": [ + 0.00212651, + -2.56332945, + 1282.72280877 + ], + "inner": [ + 518.29, + 525.41 + ], + "peak": [ + 606.95, + 510.29 + ], + "outer": [ + 652.71, + 515.57 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.9028, + "checkA_pass": true, + "halfWidthInner": 5.647, + "halfWidthPeak": 25.496, + "halfWidthOuter": 4.891, + "bandX0": 507, + "bandY0": 450, + "colMin": 514, + "colMax": 657 + } + }, + "halfWidthLeft": [ + 15.731, + 10.999, + 7.875 + ], + "halfWidthRight": [ + 5.647, + 25.496, + 4.891 + ], + "halfWidthNote": "원화 눈썹 잉크 띠 반두께[inner,peak,outer](px, 중심선 법선 방향). export_rig.py가 persona.json browHalfWidthFromArt!=false(기본)면 RigBrow.halfWidth로 내보낸다.", + "checkB_innerMinusPeakY": { + "browLeft": 12.91, + "browRight": 15.12 + }, + "checkD_symmetry": { + "innerYDiff": 4.85, + "peakYDiff": 7.06 + }, + "evidenceImage": "preview/v2/brow-centerline.jpg" + }, + "schemaVersion": "vignette.avatar.v3.layers.v1", + "persona": "P6", + "canvas": { + "w": 1005, + "h": 1566 + }, + "base": { + "front": "base/base-front.png", + "faceless": "base/base-faceless.png", + "facelessPadded": "base/base-faceless-padded.png", + "facelessSize": [ + 1005, + 1566 + ], + "padNote": "base-faceless.png 마지막 행을 0번 복제해 1005x1566(base-front.png 크기)으로 패딩한 것이 F다." + }, + "segmenter": { + "model": "selfie_multiclass_256x256.tflite (mediapipe ImageSegmenter, storage.googleapis.com)", + "categories": { + "0": "background", + "1": "hair", + "2": "bodySkin", + "3": "faceSkin", + "4": "clothes", + "5": "others" + }, + "categoryPixelCounts": { + "0": 492868, + "1": 349798, + "2": 71758, + "3": 188365, + "4": 471041 + }, + "hairEdgeRefine": { + "dilatePx": 6, + "lumThreshold": 110, + "addedPixels": 16042 + } + }, + "chinLine": { + "landmarkIndex": 152, + "xy": [ + 506.07, + 930.63 + ], + "marginPx": 8, + "cutY": 938.63 + }, + "faceOval": { + "landmarkLoop": [ + 10, + 338, + 297, + 332, + 284, + 251, + 389, + 356, + 454, + 323, + 361, + 288, + 397, + 365, + 379, + 378, + 400, + 377, + 152, + 148, + 176, + 149, + 150, + 136, + 172, + 58, + 132, + 93, + 234, + 127, + 162, + 21, + 54, + 103, + 67, + 109 + ], + "scale": 1.04, + "sourceImage": "base/base-front.png" + }, + "layers": [ + { + "id": "body", + "file": "layers/body.png", + "source": "base-faceless-masked+regenerated-fill", + "alphaBBox": [ + 0, + 844, + 1005, + 1566 + ], + "opaquePixels": 586434, + "greenResidue": 0, + "fillTargetPixels": 66153, + "fillSourceRaw": "raw/body.png (rejected 재생성이 아니라 수용된 body.png의 크로마키 결과; head/hairFront와 달리 body 재생성은 승인됨)" + }, + { + "id": "head", + "file": "layers/head.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 70, + 81, + 905, + 1146 + ], + "opaquePixels": 534350, + "greenResidue": 0 + }, + { + "id": "hairFront", + "file": "layers/hairFront.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 257, + 399, + 720, + 944 + ], + "opaquePixels": 26531, + "greenResidue": 0 + } + ], + "rejectedRawEdits": { + "body": { + "file": "raw/body.png", + "status": "accepted-as-fill-source", + "reason": "정렬 (0,0), 형태 변형 없음 — head_mask 채움 전용 소스로 재사용" + } + }, + "composite": { + "meanAbsDiff": { + "full": 1.40462036348695, + "face": 0.4177874589464975, + "hairOutline": 7.014684261853622 + }, + "target": { + "full": 3.0, + "pass": true + }, + "backgroundNote": "카테고리0(배경)은 종이결 텍스처 노이즈(표준편차 ~29/채널)를 포함해 평탄한 크림(#EEE5D3)과 자체적으로 평균절대차 ~7 차이가 난다." + }, + "layersV2": { + "chinBandFix": { + "targetRegionPixels": 14071, + "sourceBandHeight": 150, + "rowJitterRange": [ + -2.0, + 2.0 + ], + "rngSeed": 20260930 + }, + "hairEdgeFix": { + "bandOuterPx": 40, + "bandInnerPx": 6, + "lumSmoothstep": [ + 205.0, + 150.0 + ], + "minFragmentAreaPx": 60, + "head": { + "bandOuterPixels": 105949, + "bandInnerPixels": 58333, + "componentsBefore": 173, + "removed": 171, + "removedPixels": 951 + }, + "hairFront": { + "bandOuterPixels": 0, + "bandInnerPixels": 16912, + "componentsBefore": 149, + "removed": 147, + "removedPixels": 307 + } + }, + "hairPaperGapFix": { + "regionDilatePx": 6, + "paperColorDistThreshold": 40.0, + "paperLumThreshold": 195.0, + "paperSatThreshold": 40.0, + "opaqueAlphaThreshold": 0.95, + "regionPixels": 380353, + "head": { + "targetPixels": 1237, + "componentsBefore": 3, + "removed": 1, + "removedPixels": 1, + "faceSkinAlphaDiff": 0.0 + }, + "hairFront": { + "targetPixels": 1, + "componentsBefore": 2, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + } + }, + "jawInkFix": { + "mouthCenterY": 803.47, + "distThresholdPx": 14.0, + "mergePx": 3, + "aspectThreshold": 1.0, + "removedGroups": [ + { + "pixels": 7827, + "bbox": [ + 311, + 804, + 681, + 945 + ], + "width": 370, + "height": 141, + "aspect": 2.624 + } + ], + "keptGroups": [], + "removedPixels": 7827, + "strayFragmentCleanup": { + "componentsBefore": 5, + "removed": 3, + "removedPixels": 3 + } + }, + "metrics": { + "body": { + "haloPct": 3.2908268202385846 + }, + "head": { + "haloPct": 0.3532219570405728, + "bgLeakAlphaMean": 0.0, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + }, + "hairFront": { + "haloPct": 0.0, + "bgLeakAlphaMean": 0.0, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + } + }, + "layers": [ + { + "id": "body", + "bbox": [ + 0, + 844, + 1005, + 1566 + ], + "opaque": 586357, + "greenResidue": 0 + }, + { + "id": "head", + "bbox": [ + 37, + 83, + 924, + 1146 + ], + "opaque": 547008, + "greenResidue": 0 + }, + { + "id": "hairFront", + "bbox": [ + 257, + 399, + 720, + 928 + ], + "opaque": 27620, + "greenResidue": 0 + } + ], + "faceDetail": { + "browLandmarksSource": "manifest.landmarks.eyebrowLeft/Right", + "region": "face", + "faceInsetPx": 24.0, + "matchFacelessColor": true, + "matchFacelessColorDeltaRgb": { + "eyeLeft": [ + -17.96, + -18.35, + -19.46 + ], + "eyeRight": [ + -21.14, + -21.78, + -21.82 + ], + "browLeft": [ + -1.83, + -1.9, + -4.89 + ], + "browRight": [ + -2.88, + -3.74, + -7.0 + ], + "mouth": [ + -1.85, + -0.97, + -2.98 + ] + }, + "regions": { + "eyeLeft": [ + 311.4, + 507.4, + 457.4, + 670.1 + ], + "eyeRight": [ + 523.9, + 500.3, + 669.8, + 661.8 + ], + "mouth": [ + 378.8, + 741.5, + 620.1, + 915.6 + ], + "moles": [] + }, + "exclusionPixels": { + "eyeLeft": 12236, + "eyeRight": 12954, + "browLeft": 11741, + "browRight": 13108, + "mouth": 19919, + "union": 57733 + }, + "hairMaskPixels": 370233, + "bbox": [ + 272, + 404, + 711, + 933 + ], + "textureCloneStamp": { + "cloneTargetThreshold": 65.0, + "avoidThreshold": 110.0, + "lineOpeningIterations": 3, + "featherPx": 4.0, + "badTexturePixels": 66, + "preservedShadowPixels": 0, + "components": [ + { + "componentId": 1, + "pixels": 29, + "offset": [ + 60, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 2, + "pixels": 1, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 3, + "pixels": 1, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 4, + "pixels": 8, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 5, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 6, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 7, + "pixels": 2, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 8, + "pixels": 1, + "offset": [ + -40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 9, + "pixels": 1, + "offset": [ + 0, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 10, + "pixels": 9, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 11, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 12, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 13, + "pixels": 2, + "offset": [ + 40, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 14, + "pixels": 2, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 15, + "pixels": 2, + "offset": [ + 0, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 16, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 17, + "pixels": 1, + "offset": [ + 0, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 18, + "pixels": 1, + "offset": [ + -40, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 19, + "pixels": 1, + "offset": [ + -40, + -40 + ], + "method": "clone-stamp" + } + ] + }, + "genericPatches": { + "forehead": [ + 443, + 410, + 491, + 458 + ], + "cheekLeft": [ + 331, + 648, + 379, + 696 + ], + "cheekRight": [ + 515, + 639, + 563, + 687 + ] + }, + "genericPatchBaseline": { + "highFreqEnergy": 9.2469051470674, + "lineEnergy": 4.048168758136364 + }, + "checkA_meanAbsDiff": 0.4896796010315382, + "checkB_seamLumDiff": 0.5417158200004906, + "checkC_holeDarkResiduePct": 0.15155003069367712, + "checkC_violationPixels": 79, + "checkD_texturePreservation": { + "eyeLeft": { + "insideEnergy": 9.229265393541892, + "baselineEnergy": 9.2469051470674, + "ratio": 0.9980923613636178, + "pass": true + }, + "eyeRight": { + "insideEnergy": 10.786136096647196, + "baselineEnergy": 9.2469051470674, + "ratio": 1.166459039548811, + "pass": true + }, + "browLeft": { + "insideEnergy": 8.548916746600598, + "baselineEnergy": 9.2469051470674, + "ratio": 0.9245165393863519, + "pass": true + }, + "browRight": { + "insideEnergy": 9.979914063921097, + "baselineEnergy": 9.2469051470674, + "ratio": 1.0792707295246957, + "pass": true + }, + "mouth": { + "insideEnergy": 8.022835014361053, + "baselineEnergy": 9.2469051470674, + "ratio": 0.867623803506349, + "pass": true + } + }, + "checkD_allPass": true, + "checkE_ghostOutline": { + "eyeLeft": { + "bandLineEnergy": 7.355716132534533, + "baselineLineEnergy": 4.048168758136364, + "ratio": 1.8170477991438403, + "pass": false + }, + "eyeRight": { + "bandLineEnergy": 7.604336496690048, + "baselineLineEnergy": 4.048168758136364, + "ratio": 1.8784633129254276, + "pass": false + }, + "browLeft": { + "bandLineEnergy": 3.446691194533974, + "baselineLineEnergy": 4.048168758136364, + "ratio": 0.8514198395525168, + "pass": true + }, + "browRight": { + "bandLineEnergy": 3.9400153277490557, + "baselineLineEnergy": 4.048168758136364, + "ratio": 0.9732833691357525, + "pass": true + }, + "mouth": { + "bandLineEnergy": 3.3578240037031386, + "baselineLineEnergy": 4.048168758136364, + "ratio": 0.8294673973149687, + "pass": true + } + }, + "checkE_allPass": false, + "checkDarkCircle": { + "eyeLeft": { + "compositeMean": 133.09809523809525, + "frontMean": 132.64361904761904, + "diff": 0.454476190476214, + "pass": true + }, + "eyeRight": { + "compositeMean": 135.7567619047619, + "frontMean": 135.64457142857142, + "diff": 0.11219047619047728, + "pass": true + } + }, + "checkDarkCircle_allPass": true + }, + "paperGrain": { + "sourceImage": "base/base-front.png", + "sourceOrigin": [ + 739, + 10 + ], + "tileSize": 256, + "personMarginPx": 20, + "cleanFraction": 0.98858642578125, + "contaminatedPixelsFilled": 748, + "chromaKeep": 0.3, + "targetLumRange": [ + 245.0, + 250.0 + ], + "lumShift": 22.521382649739564, + "finalMeanLum": 247.44620143538134, + "finalLumStd": 3.3603736380015956, + "seamContinuity": { + "leftRightDiff": 0.1671720490391048, + "topBottomDiff": 0.34696069563338483 + } + } + }, + "lipTexture": { + "designVersion": "A5(아랫입술 그늘 띠를 lip-shadow 조각으로 분리)", + "landmarks": { + "mouthCornerLeft": [ + 423.83, + 811.05 + ], + "mouthCornerRight": [ + 575.09, + 805.14 + ], + "upperLipTop": [ + 498.47, + 778.0 + ], + "lowerLipBottom": [ + 501.51, + 841.17 + ], + "mouthCenter": [ + 499.7782923281193, + 803.4675067663193 + ] + }, + "capBBox": [ + 418.46, + 774.59, + 580.46, + 844.59 + ], + "otsuThreshLabA": 139.0, + "diffThresh": 20.0, + "dilatePx": 10.0, + "alphaRampPx": 4.0, + "splitOverlapPx": 2.0, + "shadowBandPx": 18.0, + "shadowTopOverlapPx": 6.0, + "shadowSideRampPx": 6.0, + "shadowTopRampPx": 4.0, + "checks": { + "lip-upper": { + "regionPixelCount": 5306, + "fullOpacityPixelCount": 4597, + "rampPixelCount": 709, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 42, + 30, + 158, + 49 + ] + }, + "lip-lower": { + "regionPixelCount": 6041, + "fullOpacityPixelCount": 5354, + "rampPixelCount": 687, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 41, + 69, + 160, + 48 + ] + }, + "lip-shadow": { + "regionPixelCount": 3360, + "fullOpacityPixelCount": 1880, + "rampPixelCount": 1480, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 51, + 72, + 140, + 53 + ] + }, + "splitOverlapPixelCount": 316, + "splitOverlapBandOk": true, + "splitOverlapAlphaMaxDiff": 0, + "splitOverlapConsistentOk": true, + "splitCoverageMismatchPixelCount": 0, + "splitCheckOk": true, + "shadowLowerOverlapPixelCount": 2445, + "shadowLowerOverlapMaxDiff": 21.91372549019607, + "shadowLowerOverlapDiffGt1PixelCount": 116, + "shadowLowerOverlapOk": false + }, + "check3NeutralComposite": { + "fullOpacityMaxDiff": 0.0, + "rampMeanAbsDiff": 10.831, + "mouthBBoxMeanAbsDiff": 2.13 + }, + "pngFileSizes": { + "lip-upper": 21193, + "lip-lower": 21453, + "lip-shadow": 20989 + }, + "canvasOrigin": { + "upper": [ + 420, + 765 + ], + "lower": [ + 419, + 804 + ], + "shadow": [ + 429, + 807 + ] + }, + "evidenceImage": "preview/v2/lip-texture.jpg", + "check4WebpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jaw": { + "designVersion": "A5(결정문 §8.4 하관 띠 변형 — 턱 조각 원본)", + "noseTip": [ + 495.58, + 716.54 + ], + "chinTip": [ + 506.07, + 930.63 + ], + "yFormula": "noseTip.y - 50 - 10 .. chinTip.y + 40", + "noseToTopPx": 60.0, + "chinToBottomPx": 40.0, + "ovalOutsetPx": 18.0, + "faceOvalSource": "export_rig.detect_face_landmarks + compute_face_oval(base-front.png, 결정적)", + "bboxCanvas": [ + 251, + 656, + 733, + 971 + ], + "naiveXRangeForComparison": [ + 251, + 733 + ], + "checks": { + "head": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 333372 + }, + "detail": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 366349 + } + }, + "evidenceImage": "preview/v2/jaw-pieces.jpg", + "check1VsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 3.533, + "maxAbsDiffPremultipliedRgb": 52.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.784, + "maxAbsDiffPremultipliedRgb": 40.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 14714, + "lip-lower": 15166, + "lip-shadow": 15138 + }, + "totalBytes": 45018, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 31190, + "jaw-detail": 24094 + }, + "totalBytes": 55284, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 3.533, + "maxAbsDiffPremultipliedRgb": 52.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.784, + "maxAbsDiffPremultipliedRgb": 40.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSprite": { + "enabled": true, + "bandExtraHalfHeightPx": 8.0, + "bandEndExtendPx": 6.0, + "diffThresh": 25.0, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "hairSource": "layers/v2/hairFront.png alpha(게시되는 레이어 그 자체, 분할 카테고리 아님)", + "hairAlphaThresh": 128.0, + "hairDilateIterations": 1, + "rampPx": 1.5, + "inkLumMethod": "median(ink-classified pixels in band, region after hair removal)", + "minAlphaForUnmix": 0.05, + "hairMaskPixelCount": 30780, + "left": { + "bboxCanvas": [ + 323, + 504, + 134, + 49 + ], + "halfHeightPx": 23.731, + "otsuThresh": 111.0, + "lSkin": 184.333, + "lInk": 42.667, + "regionPixelCount": 2898, + "hairOverlapPixelCount": 43, + "neutralCompositeMeanAbsDiffAlphaRegion": 5.492, + "pngFileSizeBytes": 9675 + }, + "right": { + "bboxCanvas": [ + 514, + 492, + 137, + 57 + ], + "halfHeightPx": 33.496, + "otsuThresh": 107.0, + "lSkin": 183.0, + "lInk": 42.333, + "regionPixelCount": 2888, + "hairOverlapPixelCount": 77, + "neutralCompositeMeanAbsDiffAlphaRegion": 4.641, + "pngFileSizeBytes": 10134 + }, + "canvasOrigin": { + "left": [ + 323.0, + 504.0 + ], + "right": [ + 514.0, + 492.0 + ] + }, + "evidenceImage": "preview/v2/brow-sprite.jpg", + "checkWebpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "eyeLineScale": { + "enabled": true, + "method": "눈 폭 가운데 60% 열마다 upperLidTop.y-12 ~ 홍채중심y 사이 첫 연속 어두운(lum<80) 구간 길이의 중앙값", + "windowAbovePx": 12.0, + "darkLumThresh": 80.0, + "columnMiddleFrac": 0.6, + "p1BaselinePx": 2.0, + "lineScaleClampRange": [ + 1.0, + 2.5 + ], + "left": { + "measuredPx": 2.0, + "nColumns": 55, + "ratio": 1.0, + "lineScale": 1.0 + }, + "right": { + "measuredPx": 2.0, + "nColumns": 56, + "ratio": 1.0, + "lineScale": 1.0 + } + }, + "iris": { + "method": "가로: 중심 y 부근 상하 각 4행에서 중심 x를 포함하는 연속 어두운(lum<100) 구간의 중앙값으로 반지름·중심x. 세로: 중심 x 부근 좌우 각 4열에서 중심 y를 포함하는 연속 어두운 구간의 아래쪽 끝 중앙값에서 가로 반지름을 빼 중심y(세로축은 윗눈꺼풀 잉크와 홍채가 같은 톤으로 이어져 위쪽 경계를 가를 수 없다).", + "darkLumThresh": 100.0, + "scanBandPx": 4, + "left": { + "measuredCenter": [ + 386.5, + 577.5 + ], + "measuredRadius": 20.5, + "rigCenter": [ + 388.77, + 581.09 + ], + "rigRadius": 20.65, + "nRowsHorizontal": 9, + "nColsVertical": 9 + }, + "right": { + "measuredCenter": [ + 595.0, + 568.0 + ], + "measuredRadius": 20.0, + "rigCenter": [ + 594.19, + 571.71 + ], + "rigRadius": 20.75, + "nRowsHorizontal": 9, + "nColsVertical": 9 + } + }, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 6056, + "brow-right": 6426 + }, + "totalBytes": 12482, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p6-linocut/persona.json b/docs/avatar-art/p6-linocut/persona.json new file mode 100644 index 0000000..9a06bb2 --- /dev/null +++ b/docs/avatar-art/p6-linocut/persona.json @@ -0,0 +1,37 @@ +{ + "code": "P6", + "publicSlug": "p6", + "rigFileName": "p6Rig.ts", + "rigExportName": "P6_LINOCUT_RIG", + "styleFrame": "../art-direction-v3/p1/r2-b-linocut.png", + "paletteSamples": { + "ink": { + "box": [300, 150, 650, 300], + "lumThreshold": 55 + }, + "motifPetalBoxes": [ + { "label": "sun", "kind": "ochre", "box": [1230, 10, 1536, 210] }, + { "label": "tulip", "kind": "ochre", "box": [1030, 280, 1170, 560] } + ], + "motifLeafBoxes": [ + { "label": "cloudLeft", "kind": "blue", "box": [20, 20, 380, 190] }, + { "label": "raincloud", "kind": "blue", "box": [520, 10, 930, 230] }, + { "label": "wiltedFlowerLeaf", "kind": "blue", "box": [520, 280, 650, 580] }, + { "label": "closedBudLeaf", "kind": "blue", "box": [10, 290, 110, 570] } + ] + }, + "faceDetail": { + "moles": [], + "region": "face", + "faceInsetPx": 24, + "matchFacelessColor": true + }, + "pivots": { + "neck": [506, 1001], + "body": [502, 1566], + "face": [488, 661] + }, + "crops": { + "bustYOffset": 40 + } +} diff --git a/docs/avatar-art/p6-linocut/preview/qa/face-art-vs-render.jpg b/docs/avatar-art/p6-linocut/preview/qa/face-art-vs-render.jpg new file mode 100644 index 0000000..aa01c4c Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/qa/face-art-vs-render.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/qa/face-zoom.jpg b/docs/avatar-art/p6-linocut/preview/qa/face-zoom.jpg new file mode 100644 index 0000000..b9ee5d1 Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/qa/face-zoom.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/qa/neutral-vs-art.jpg b/docs/avatar-art/p6-linocut/preview/qa/neutral-vs-art.jpg new file mode 100644 index 0000000..0dc9dea Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/qa/neutral-vs-art.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/qa/normalized.jpg b/docs/avatar-art/p6-linocut/preview/qa/normalized.jpg new file mode 100644 index 0000000..63c124a Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/qa/normalized.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/qa/sheet-expr-bust.jpg b/docs/avatar-art/p6-linocut/preview/qa/sheet-expr-bust.jpg new file mode 100644 index 0000000..7a53085 Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/qa/sheet-expr-bust.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/qa/sheet-expr-face.jpg b/docs/avatar-art/p6-linocut/preview/qa/sheet-expr-face.jpg new file mode 100644 index 0000000..36d083e Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/qa/sheet-expr-face.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/qa/sheet-viseme.jpg b/docs/avatar-art/p6-linocut/preview/qa/sheet-viseme.jpg new file mode 100644 index 0000000..bac742d Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/qa/sheet-viseme.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/qa/viseme-timeline.json b/docs/avatar-art/p6-linocut/preview/qa/viseme-timeline.json new file mode 100644 index 0000000..16698bd --- /dev/null +++ b/docs/avatar-art/p6-linocut/preview/qa/viseme-timeline.json @@ -0,0 +1,287 @@ +[ + { + "t": 0, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00000.png" + }, + { + "t": 50, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00050.png" + }, + { + "t": 100, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00100.png" + }, + { + "t": 150, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00150.png" + }, + { + "t": 200, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00200.png" + }, + { + "t": 250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00250.png" + }, + { + "t": 300, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00300.png" + }, + { + "t": 350, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00350.png" + }, + { + "t": 400, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00400.png" + }, + { + "t": 450, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00450.png" + }, + { + "t": 500, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00500.png" + }, + { + "t": 550, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00550.png" + }, + { + "t": 600, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00600.png" + }, + { + "t": 650, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00650.png" + }, + { + "t": 700, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00700.png" + }, + { + "t": 750, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00750.png" + }, + { + "t": 800, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00800.png" + }, + { + "t": 850, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00850.png" + }, + { + "t": 900, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00900.png" + }, + { + "t": 950, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t00950.png" + }, + { + "t": 1000, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01000.png" + }, + { + "t": 1050, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01050.png" + }, + { + "t": 1100, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01100.png" + }, + { + "t": 1150, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01150.png" + }, + { + "t": 1200, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01200.png" + }, + { + "t": 1250, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01250.png" + }, + { + "t": 1300, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01300.png" + }, + { + "t": 1350, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01350.png" + }, + { + "t": 1400, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01400.png" + }, + { + "t": 1450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01450.png" + }, + { + "t": 1500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01500.png" + }, + { + "t": 1550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01550.png" + }, + { + "t": 1600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01600.png" + }, + { + "t": 1650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01650.png" + }, + { + "t": 1700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01700.png" + }, + { + "t": 1750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01750.png" + }, + { + "t": 1800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01800.png" + }, + { + "t": 1850, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01850.png" + }, + { + "t": 1900, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01900.png" + }, + { + "t": 1950, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t01950.png" + }, + { + "t": 2000, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02000.png" + }, + { + "t": 2050, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02050.png" + }, + { + "t": 2100, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02100.png" + }, + { + "t": 2150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02150.png" + }, + { + "t": 2200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02200.png" + }, + { + "t": 2250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02250.png" + }, + { + "t": 2300, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02300.png" + }, + { + "t": 2350, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02350.png" + }, + { + "t": 2400, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02400.png" + }, + { + "t": 2450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02450.png" + }, + { + "t": 2500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02500.png" + }, + { + "t": 2550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02550.png" + }, + { + "t": 2600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02600.png" + }, + { + "t": 2650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02650.png" + }, + { + "t": 2700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02700.png" + }, + { + "t": 2750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02750.png" + }, + { + "t": 2800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p6-linocut\\preview\\qa\\frames\\viseme-scan-t02800.png" + } +] \ No newline at end of file diff --git a/docs/avatar-art/p6-linocut/preview/v2/brow-centerline.jpg b/docs/avatar-art/p6-linocut/preview/v2/brow-centerline.jpg new file mode 100644 index 0000000..a8d026a Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/v2/brow-centerline.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/v2/brow-sprite.jpg b/docs/avatar-art/p6-linocut/preview/v2/brow-sprite.jpg new file mode 100644 index 0000000..dc8a786 Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/v2/brow-sprite.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/v2/export-rig-report.json b/docs/avatar-art/p6-linocut/preview/v2/export-rig-report.json new file mode 100644 index 0000000..697e888 --- /dev/null +++ b/docs/avatar-art/p6-linocut/preview/v2/export-rig-report.json @@ -0,0 +1,676 @@ +{ + "faceOvalBBox": [ + 260.0, + 397.6, + 717.9, + 941.0 + ], + "cropsFace": [ + 184.6, + 365.0, + 608.6, + 608.6 + ], + "mouthCenter": [ + 499.8, + 803.5 + ], + "palette": { + "ink": "#242322", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#A27659", + "lipLower": "#A47459", + "mouthLine": "#2C2625", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "paletteSamples": { + "eyeLeft": { + "sclera": "#B28C67", + "iris": "#312B25", + "irisRing": "#544234", + "n": { + "sclera": 745, + "iris": 193, + "irisRing": 386 + } + }, + "eyeRight": { + "sclera": "#BA926C", + "iris": "#342D26", + "irisRing": "#6B523F", + "n": { + "sclera": 807, + "iris": 195, + "irisRing": 398 + } + }, + "scleraIrisIrisRingFixedOverride": { + "reason": "persona.json paletteSamples.eyeOverride(고정 설계값)", + "measured": { + "sclera": "#B68F6A", + "iris": "#322C26", + "irisRing": "#5F4A39" + }, + "fixed": { + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F" + } + }, + "ink": { + "box": [ + 300, + 150, + 650, + 300 + ], + "lumThreshold": 55.0, + "n": 40816, + "hex": "#242322" + }, + "lipUpper": { + "box": [ + 418, + 775, + 580, + 801 + ], + "hex": "#A27659" + }, + "lipLower": { + "box": [ + 418, + 805, + 580, + 844 + ], + "hex": "#A47459" + }, + "mouthLine": { + "box": [ + 438, + 801, + 560, + 806 + ], + "hex": "#2C2625" + }, + "motifPetal": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "sun": { + "box": [ + 1230, + 10, + 1536, + 210 + ], + "n": 20570, + "hex": "#D3A661" + }, + "tulip": { + "box": [ + 1030, + 280, + 1170, + 560 + ], + "n": 4314, + "hex": "#CCA063" + } + }, + "hex": "#D0A362" + }, + "motifLeaf": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "cloudLeft": { + "box": [ + 20, + 20, + 380, + 190 + ], + "n": 21312, + "hex": "#636D76" + }, + "raincloud": { + "box": [ + 520, + 10, + 930, + 230 + ], + "n": 27607, + "hex": "#586B76" + }, + "wiltedFlowerLeaf": { + "box": [ + 520, + 280, + 650, + 580 + ], + "n": 5818, + "hex": "#495961" + }, + "closedBudLeaf": { + "box": [ + 10, + 290, + 110, + 570 + ], + "n": 6589, + "hex": "#495961" + } + }, + "hex": "#53626C" + } + }, + "publish": { + "fileSizes": { + "body": 171266, + "head": 170650, + "hair-front": 20596, + "face-detail": 45114, + "paper-grain": 1816 + }, + "encodeMeta": { + "quality": 80, + "scale": 1.0, + "totalBytes": 409442 + }, + "totalBytes": 409442 + }, + "grain": { + "href": "/avatar/v3/p6/paper-grain.webp", + "size": 256 + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 14714, + "lip-lower": 15166, + "lip-shadow": 15138 + }, + "totalBytes": 45018, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 31190, + "jaw-detail": 24094 + }, + "totalBytes": 55284, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 3.533, + "maxAbsDiffPremultipliedRgb": 52.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.784, + "maxAbsDiffPremultipliedRgb": 40.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 6056, + "brow-right": 6426 + }, + "totalBytes": 12482, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "rig": { + "schemaVersion": "vignette.avatar.v3.rig.v1", + "persona": "P6", + "canvas": { + "w": 1005, + "h": 1566 + }, + "layers": { + "body": { + "href": "/avatar/v3/p6/body.webp", + "x": 0, + "y": 844, + "w": 1005, + "h": 722 + }, + "head": { + "href": "/avatar/v3/p6/head.webp", + "x": 37, + "y": 83, + "w": 887, + "h": 1063 + }, + "hairFront": { + "href": "/avatar/v3/p6/hair-front.webp", + "x": 257, + "y": 399, + "w": 463, + "h": 529 + }, + "faceDetail": { + "href": "/avatar/v3/p6/face-detail.webp", + "x": 272, + "y": 404, + "w": 439, + "h": 529 + } + }, + "grain": { + "href": "/avatar/v3/p6/paper-grain.webp", + "size": 256 + }, + "lipTexture": { + "upper": { + "href": "/avatar/v3/p6/lip-upper.webp", + "x": 420, + "y": 765, + "w": 158, + "h": 49 + }, + "lower": { + "href": "/avatar/v3/p6/lip-lower.webp", + "x": 419, + "y": 804, + "w": 160, + "h": 48 + }, + "shadow": { + "href": "/avatar/v3/p6/lip-shadow.webp", + "x": 429, + "y": 807, + "w": 140, + "h": 53 + } + }, + "jaw": { + "head": { + "href": "/avatar/v3/p6/jaw-head.webp", + "x": 251, + "y": 656, + "w": 482, + "h": 315 + }, + "detail": { + "href": "/avatar/v3/p6/jaw-detail.webp", + "x": 251, + "y": 656, + "w": 482, + "h": 315 + } + }, + "motif": null, + "pivots": { + "neck": [ + 506, + 1001 + ], + "body": [ + 502, + 1566 + ], + "face": [ + 488, + 661 + ] + }, + "crops": { + "portrait": [ + 0, + 0, + 1005, + 1566 + ], + "bust": [ + 0.0, + 40.0, + 1005.0, + 1005.0 + ], + "face": [ + 184.62152092794975, + 365.04152293910977, + 608.5970685722352, + 608.5970685722352 + ] + }, + "faceOval": [ + [ + 480.8, + 398.4 + ], + [ + 546.8, + 397.6 + ], + [ + 602.0, + 404.4 + ], + [ + 651.9, + 421.0 + ], + [ + 683.6, + 447.7 + ], + [ + 702.8, + 483.5 + ], + [ + 713.5, + 522.5 + ], + [ + 717.9, + 570.3 + ], + [ + 717.0, + 615.8 + ], + [ + 714.2, + 663.3 + ], + [ + 706.6, + 713.5 + ], + [ + 692.8, + 766.8 + ], + [ + 673.8, + 811.4 + ], + [ + 651.7, + 845.0 + ], + [ + 623.5, + 875.2 + ], + [ + 600.1, + 897.0 + ], + [ + 575.1, + 917.5 + ], + [ + 545.4, + 934.4 + ], + [ + 506.6, + 941.0 + ], + [ + 467.6, + 937.9 + ], + [ + 437.3, + 924.0 + ], + [ + 410.8, + 905.8 + ], + [ + 385.5, + 886.6 + ], + [ + 354.0, + 859.0 + ], + [ + 328.2, + 826.9 + ], + [ + 304.3, + 783.8 + ], + [ + 285.2, + 730.7 + ], + [ + 272.8, + 680.6 + ], + [ + 265.7, + 633.6 + ], + [ + 260.0, + 588.5 + ], + [ + 260.0, + 540.9 + ], + [ + 267.4, + 500.8 + ], + [ + 283.6, + 463.8 + ], + [ + 312.3, + 434.4 + ], + [ + 359.6, + 413.5 + ], + [ + 414.2, + 402.7 + ] + ], + "landmarks": { + "eyeLeft": { + "inner": [ + 432.4, + 593.7 + ], + "outer": [ + 341.4, + 583.9 + ], + "upperLidTop": [ + 378.1, + 566.0 + ], + "lowerLidBottom": [ + 383.4, + 600.1 + ], + "iris": { + "center": [ + 386.5, + 577.5 + ], + "radius": 20.5 + }, + "lineScale": 1.0 + }, + "eyeRight": { + "inner": [ + 548.9, + 589.6 + ], + "outer": [ + 639.8, + 570.8 + ], + "upperLidTop": [ + 601.4, + 555.9 + ], + "lowerLidBottom": [ + 598.4, + 591.8 + ], + "iris": { + "center": [ + 595.0, + 568.0 + ], + "radius": 20.0 + }, + "lineScale": 1.0 + }, + "browLeft": { + "inner": [ + 451.9, + 530.3 + ], + "peak": [ + 367.6, + 517.4 + ], + "outer": [ + 324.1, + 521.5 + ], + "halfWidth": [ + 15.73, + 11.0, + 7.88 + ], + "sprite": { + "href": "/avatar/v3/p6/brow-left.webp", + "x": 323.0, + "y": 504.0, + "w": 134, + "h": 49 + } + }, + "browRight": { + "inner": [ + 518.3, + 525.4 + ], + "peak": [ + 607.0, + 510.3 + ], + "outer": [ + 652.7, + 515.6 + ], + "halfWidth": [ + 5.65, + 25.5, + 4.89 + ], + "sprite": { + "href": "/avatar/v3/p6/brow-right.webp", + "x": 514.0, + "y": 492.0, + "w": 137, + "h": 57 + } + }, + "noseTip": [ + 495.6, + 716.5 + ], + "mouthCornerLeft": [ + 423.8, + 811.0 + ], + "mouthCornerRight": [ + 575.1, + 805.1 + ], + "upperLipTop": [ + 498.5, + 778.0 + ], + "lowerLipBottom": [ + 501.5, + 841.2 + ], + "mouthCenter": [ + 499.8, + 803.5 + ], + "chinTip": [ + 506.1, + 930.6 + ] + }, + "palette": { + "ink": "#242322", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#A27659", + "lipLower": "#A47459", + "mouthLine": "#2C2625", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "backdrop": { + "cognitive": "#ECE3D1", + "positive": "#F1DEC2", + "negative": "#DCE0E2", + "defensive": "#E6DAD3", + "energy": "#E2E0D0" + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p6-linocut/preview/v2/ghost-check.jpg b/docs/avatar-art/p6-linocut/preview/v2/ghost-check.jpg new file mode 100644 index 0000000..6b289df Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/v2/ghost-check.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/v2/holes-texture.jpg b/docs/avatar-art/p6-linocut/preview/v2/holes-texture.jpg new file mode 100644 index 0000000..a98dee3 Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/v2/holes-texture.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/v2/jaw-pieces.jpg b/docs/avatar-art/p6-linocut/preview/v2/jaw-pieces.jpg new file mode 100644 index 0000000..0bb36a3 Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/v2/jaw-pieces.jpg differ diff --git a/docs/avatar-art/p6-linocut/preview/v2/lip-texture.jpg b/docs/avatar-art/p6-linocut/preview/v2/lip-texture.jpg new file mode 100644 index 0000000..4e85525 Binary files /dev/null and b/docs/avatar-art/p6-linocut/preview/v2/lip-texture.jpg differ diff --git a/docs/avatar-art/p6-linocut/prompts/base-faceless.txt b/docs/avatar-art/p6-linocut/prompts/base-faceless.txt new file mode 100644 index 0000000..1f5627f --- /dev/null +++ b/docs/avatar-art/p6-linocut/prompts/base-faceless.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as faceless.png: + +Redraw exactly the same girl, same frontal pose, same framing and same linocut relief-print style as the reference, but leave the face blank: remove the eyes, eyebrows and mouth completely and fill those areas with plain skin in the same flat skin color, keeping the nose, the face outline, the ears, the hair, the neck, the claw clip in her hair, the striped shirt and the off-white cable-knit cardigan with its small charcoal smudge exactly as they are. Do not move, resize or redraw anything else. Plain flat cream background, nothing else, no text. diff --git a/docs/avatar-art/p6-linocut/prompts/body.txt b/docs/avatar-art/p6-linocut/prompts/body.txt new file mode 100644 index 0000000..1558232 --- /dev/null +++ b/docs/avatar-art/p6-linocut/prompts/body.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as body.png: + +Keep only the neck, the striped shirt and the off-white cable-knit cardigan, including the small charcoal smudge exactly as they are in the reference: same shapes, same position, same linocut relief-print style, same ink colors and texture. Remove the head, the face, the ears and all of the hair completely. Where the hair or the chin previously covered the neck or the clothes, continue them naturally in the same style so there are no holes. Place the result on a plain flat pure green background (#00ff00) with nothing else, no text. diff --git a/docs/avatar-art/p6-linocut/raw/body.png b/docs/avatar-art/p6-linocut/raw/body.png new file mode 100644 index 0000000..f852dd9 Binary files /dev/null and b/docs/avatar-art/p6-linocut/raw/body.png differ diff --git a/docs/avatar-art/p7-linocut/base/base-faceless.png b/docs/avatar-art/p7-linocut/base/base-faceless.png new file mode 100644 index 0000000..695d472 Binary files /dev/null and b/docs/avatar-art/p7-linocut/base/base-faceless.png differ diff --git a/docs/avatar-art/p7-linocut/base/base-front.png b/docs/avatar-art/p7-linocut/base/base-front.png new file mode 100644 index 0000000..62b1d26 Binary files /dev/null and b/docs/avatar-art/p7-linocut/base/base-front.png differ diff --git a/docs/avatar-art/p7-linocut/base/edits/aligned-body-1.json b/docs/avatar-art/p7-linocut/base/edits/aligned-body-1.json new file mode 100644 index 0000000..11f5a2f --- /dev/null +++ b/docs/avatar-art/p7-linocut/base/edits/aligned-body-1.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\body-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\aligned-body-1.png", + "refSize": [ + 1142, + 1377 + ], + "editedOriginalSize": [ + 1142, + 1377 + ], + "eccCorrelation": 0.99627, + "transform": { + "scaleSqrtDet": 0.99995, + "rotationDeg": 0.002, + "translateX": -0.097, + "translateY": -0.462, + "matrix": [ + [ + 0.999783, + 4.7e-05, + -0.097108 + ], + [ + 3.6e-05, + 1.000121, + -0.46182 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 531858, + "chamferInMask": { + "median": 0.0, + "p90": 1.414, + "nSamples": 84981 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/base/edits/aligned-body-2.json b/docs/avatar-art/p7-linocut/base/edits/aligned-body-2.json new file mode 100644 index 0000000..0919306 --- /dev/null +++ b/docs/avatar-art/p7-linocut/base/edits/aligned-body-2.json @@ -0,0 +1,40 @@ +{ + "mode": "body", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\body-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\aligned-body-2.png", + "refSize": [ + 1142, + 1377 + ], + "editedOriginalSize": [ + 1142, + 1377 + ], + "eccCorrelation": 0.99308, + "transform": { + "scaleSqrtDet": 0.99996, + "rotationDeg": 0.003, + "translateX": -0.473, + "translateY": -0.775, + "matrix": [ + [ + 0.9999, + 0.000127, + -0.472568 + ], + [ + 5.4e-05, + 1.000025, + -0.775239 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 532046, + "chamferInMask": { + "median": 0.0, + "p90": 1.414, + "nSamples": 86334 + } +} \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/base/edits/aligned-faceless-1.json b/docs/avatar-art/p7-linocut/base/edits/aligned-faceless-1.json new file mode 100644 index 0000000..facd2df --- /dev/null +++ b/docs/avatar-art/p7-linocut/base/edits/aligned-faceless-1.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\faceless-1.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\aligned-faceless-1.png", + "refSize": [ + 1142, + 1377 + ], + "editedOriginalSize": [ + 1142, + 1377 + ], + "eccCorrelation": 0.99353, + "transform": { + "scaleSqrtDet": 0.99995, + "rotationDeg": 0.005, + "translateX": -0.285, + "translateY": -0.603, + "matrix": [ + [ + 0.999806, + -7.3e-05, + -0.284832 + ], + [ + 8.4e-05, + 1.000089, + -0.603197 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 772884, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 114122 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 5875 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 396, + 410, + 536, + 489 + ], + "refInkRatio": 0.1821, + "editedInkRatio": 0.0059 + }, + "eyeB": { + "box": [ + 607, + 408, + 748, + 488 + ], + "refInkRatio": 0.1543, + "editedInkRatio": 0.0025 + }, + "browA": { + "box": [ + 354, + 351, + 553, + 438 + ], + "refInkRatio": 0.4338, + "editedInkRatio": 0.303 + }, + "browB": { + "box": [ + 590, + 350, + 787, + 437 + ], + "refInkRatio": 0.2923, + "editedInkRatio": 0.1698 + }, + "mouth": { + "box": [ + 472, + 623, + 667, + 740 + ], + "refInkRatio": 0.064, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 396, + 410, + 536, + 489 + ], + "eyeB": [ + 607, + 408, + 748, + 488 + ], + "browA": [ + 354, + 351, + 553, + 438 + ], + "browB": [ + 590, + 350, + 787, + 437 + ], + "mouth": [ + 472, + 623, + 667, + 740 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/base/edits/aligned-faceless-2.json b/docs/avatar-art/p7-linocut/base/edits/aligned-faceless-2.json new file mode 100644 index 0000000..8993351 --- /dev/null +++ b/docs/avatar-art/p7-linocut/base/edits/aligned-faceless-2.json @@ -0,0 +1,129 @@ +{ + "mode": "faceless", + "ref": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\source-front.png", + "edited": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\faceless-2.png", + "out": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\aligned-faceless-2.png", + "refSize": [ + 1142, + 1377 + ], + "editedOriginalSize": [ + 1142, + 1377 + ], + "eccCorrelation": 0.99416, + "transform": { + "scaleSqrtDet": 1.00019, + "rotationDeg": 0.001, + "translateX": -0.214, + "translateY": -0.564, + "matrix": [ + [ + 1.000019, + -2.9e-05, + -0.21414 + ], + [ + 2.2e-05, + 1.000368, + -0.563871 + ] + ], + "direction": "ref(template) 좌표 -> edited(resized, input) 좌표. 정렬된 출력은 이 행렬의 역변환(WARP_INVERSE_MAP)으로 만든다." + }, + "eccIncludeMaskPixels": 772884, + "chamferInMask": { + "median": 0.0, + "p90": 1.0, + "nSamples": 117889 + }, + "faceOvalBandChamfer": { + "median": 0.0, + "p90": 1.0, + "nSamples": 5975 + }, + "inkRatioByBox": { + "eyeA": { + "box": [ + 396, + 410, + 536, + 489 + ], + "refInkRatio": 0.1821, + "editedInkRatio": 0.0078 + }, + "eyeB": { + "box": [ + 607, + 408, + 748, + 488 + ], + "refInkRatio": 0.1543, + "editedInkRatio": 0.0032 + }, + "browA": { + "box": [ + 354, + 351, + 553, + 438 + ], + "refInkRatio": 0.4338, + "editedInkRatio": 0.3066 + }, + "browB": { + "box": [ + 590, + 350, + 787, + 437 + ], + "refInkRatio": 0.2923, + "editedInkRatio": 0.1743 + }, + "mouth": { + "box": [ + 472, + 623, + 667, + 740 + ], + "refInkRatio": 0.064, + "editedInkRatio": 0.0 + } + }, + "eccExcludeBoxes": { + "eyeA": [ + 396, + 410, + 536, + 489 + ], + "eyeB": [ + 607, + 408, + 748, + 488 + ], + "browA": [ + 354, + 351, + 553, + 438 + ], + "browB": [ + 590, + 350, + 787, + 437 + ], + "mouth": [ + 472, + 623, + 667, + 740 + ] + } +} \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/base/edits/sheet.jpg b/docs/avatar-art/p7-linocut/base/edits/sheet.jpg new file mode 100644 index 0000000..d3b7cd2 Binary files /dev/null and b/docs/avatar-art/p7-linocut/base/edits/sheet.jpg differ diff --git a/docs/avatar-art/p7-linocut/base/normalize.json b/docs/avatar-art/p7-linocut/base/normalize.json new file mode 100644 index 0000000..660f604 --- /dev/null +++ b/docs/avatar-art/p7-linocut/base/normalize.json @@ -0,0 +1,66 @@ +{ + "canvas": { + "w": 1005, + "h": 1566 + }, + "reference": { + "image": "docs\\avatar-art\\p1-linocut\\base\\base-front.png", + "eyesCenter": [ + 492.69, + 584.33 + ], + "chin": [ + 500.61, + 919.55 + ], + "eyeDistance": 215.427, + "eyeChinDistance": 335.308 + }, + "input": { + "front": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\source-front.png", + "faceless": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\aligned-faceless-1.png", + "body": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\base\\edits\\aligned-body-1.png", + "frontSize": [ + 1142, + 1377 + ], + "eyesCenter": [ + 571.8, + 453.19 + ], + "chin": [ + 569.6, + 816.89 + ], + "eyeDistance": 211.724, + "eyeChinDistance": 363.704 + }, + "transform": { + "sHead": 0.969707, + "sWidth": 0.880035, + "s": 0.969707, + "rotationDeg": 0.0, + "offsetXNatural": -61.793, + "offsetXClampRange": [ + -102.406, + 0.0 + ], + "offsetX": -61.793, + "offsetY": 144.868 + }, + "coveredRange": { + "x": [ + 0.0, + 1005 + ], + "y": [ + 144.9, + 1480.2 + ] + }, + "inputSha256": { + "front": "e92955a4a5bbb0dc7a0b133368344c5d4acf2cd424b62f675c9206054973e124", + "faceless": "213a6566071f8c7e80cf539625d23eb709ed1d5e88a9ef177f2e223ff1164b13", + "body": "cb2091bf50aaead7b1a9569c4922aa06cfab7c101a0a0a0701982c4433f36e36" + } +} \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/manifest.json b/docs/avatar-art/p7-linocut/manifest.json new file mode 100644 index 0000000..9ef8b7e --- /dev/null +++ b/docs/avatar-art/p7-linocut/manifest.json @@ -0,0 +1,1920 @@ +{ + "landmarks": { + "coordSystem": "screen (image pixel: x=0 좌측, y=0 상단; left=작은 x, right=큰 x; 인물 해부학적 좌우 아님)", + "eyeLeft": { + "innerCorner": [ + 433.39, + 588.66 + ], + "outerCorner": [ + 345.62, + 578.8 + ], + "upperLidTop": [ + 381.33, + 566.28 + ], + "lowerLidBottom": [ + 387.83, + 592.8 + ], + "iris": { + "center": [ + 387.31, + 576.96 + ], + "radius": 19.17 + } + }, + "eyeRight": { + "innerCorner": [ + 550.71, + 589.88 + ], + "outerCorner": [ + 637.67, + 578.54 + ], + "upperLidTop": [ + 601.55, + 566.13 + ], + "lowerLidBottom": [ + 596.27, + 593.19 + ], + "iris": { + "center": [ + 595.07, + 576.86 + ], + "radius": 19.41 + } + }, + "eyebrowLeft": { + "inner": [ + 455.8, + 526.95 + ], + "peak": [ + 369.0, + 521.19 + ], + "outer": [ + 324.2, + 527.5 + ] + }, + "eyebrowRight": { + "inner": [ + 526.5, + 526.84 + ], + "peak": [ + 619.5, + 519.78 + ], + "outer": [ + 667.5, + 526.96 + ] + }, + "noseTip": [ + 493.52, + 712.47 + ], + "mouthCornerLeft": [ + 422.65, + 806.53 + ], + "mouthCornerRight": [ + 558.88, + 808.4 + ], + "upperLipTopCenter": [ + 493.82, + 774.04 + ], + "lowerLipBottomCenter": [ + 492.31, + 834.98 + ], + "chinTip": [ + 491.82, + 932.41 + ], + "faceWidthAtEyeLevelLeft": [ + 273.76, + 630.72 + ], + "faceWidthAtEyeLevelRight": [ + 704.05, + 629.99 + ] + }, + "landmarkDetector": "mediapipe FaceLandmarker (tasks) 1.0.1, model=face_landmarker(float16, v1)", + "browCenterline": { + "method": "Otsu(front lum in bbox) AND diff(F-front)>=25, morphological closing to merge hatching, single global degree-2 polyfit on column-weighted centroid with one-pass outlier removal", + "diffThresh": 25.0, + "bboxPad": { + "x": 25.0, + "yUp": 42.0, + "yDown": 14.0 + }, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "outlierStdMult": 2.0, + "edgeInsetFrac": 0.03, + "peakWindow": [ + 0.25, + 0.6 + ], + "peakFallbackFrac": 0.35, + "peakFlatHeightPx": 3.0, + "peakFailEdgeFrac": 0.2, + "oldPoints": { + "browLeft": { + "inner": [ + 449.0, + 543.74 + ], + "peak": [ + 352.93, + 508.38 + ], + "outer": [ + 304.12, + 533.83 + ] + }, + "browRight": { + "inner": [ + 534.98, + 542.72 + ], + "peak": [ + 628.43, + 506.85 + ], + "outer": [ + 676.51, + 532.35 + ] + } + }, + "newPoints": { + "browLeft": { + "name": "browLeft", + "bbox": [ + 279, + 466, + 474, + 558 + ], + "otsuThresh": 99.0, + "colRange": [ + 320, + 460 + ], + "width": 140.0, + "nColumns": 129, + "nOutliersRemoved": 7, + "fitCoeffs": [ + 0.00157525, + -1.23283377, + 761.61565189 + ], + "inner": [ + 455.8, + 526.95 + ], + "peak": [ + 369.0, + 521.19 + ], + "outer": [ + 324.2, + 527.5 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.8992, + "checkA_pass": true, + "halfWidthInner": 5.39, + "halfWidthPeak": 7.98, + "halfWidthOuter": 3.424, + "bandX0": 279, + "bandY0": 466, + "colMin": 320, + "colMax": 460 + }, + "browRight": { + "name": "browRight", + "bbox": [ + 510, + 465, + 702, + 557 + ], + "otsuThresh": 108.0, + "colRange": [ + 522, + 672 + ], + "width": 150.0, + "nColumns": 147, + "nOutliersRemoved": 4, + "fitCoeffs": [ + 0.00160062, + -1.91032372, + 1088.9327895 + ], + "inner": [ + 526.5, + 526.84 + ], + "peak": [ + 619.5, + 519.78 + ], + "outer": [ + 667.5, + 526.96 + ], + "peakMethod": "fallback35", + "peakFracFromOuterEdge": 0.35, + "peakFail": false, + "checkA_fracColumnsFitWithinMask": 0.966, + "checkA_pass": true, + "halfWidthInner": 6.342, + "halfWidthPeak": 7.979, + "halfWidthOuter": 2.926, + "bandX0": 510, + "bandY0": 465, + "colMin": 522, + "colMax": 672 + } + }, + "halfWidthLeft": [ + 5.39, + 7.98, + 3.424 + ], + "halfWidthRight": [ + 6.342, + 7.979, + 2.926 + ], + "halfWidthNote": "원화 눈썹 잉크 띠 반두께[inner,peak,outer](px, 중심선 법선 방향). export_rig.py가 persona.json browHalfWidthFromArt!=false(기본)면 RigBrow.halfWidth로 내보낸다.", + "checkB_innerMinusPeakY": { + "browLeft": 5.76, + "browRight": 7.06 + }, + "checkD_symmetry": { + "innerYDiff": 0.11, + "peakYDiff": 1.41 + }, + "evidenceImage": "preview/v2/brow-centerline.jpg" + }, + "schemaVersion": "vignette.avatar.v3.layers.v1", + "persona": "P7", + "canvas": { + "w": 1005, + "h": 1566 + }, + "base": { + "front": "base/base-front.png", + "faceless": "base/base-faceless.png", + "facelessPadded": "base/base-faceless-padded.png", + "facelessSize": [ + 1005, + 1566 + ], + "padNote": "base-faceless.png 마지막 행을 0번 복제해 1005x1566(base-front.png 크기)으로 패딩한 것이 F다." + }, + "segmenter": { + "model": "selfie_multiclass_256x256.tflite (mediapipe ImageSegmenter, storage.googleapis.com)", + "categories": { + "0": "background", + "1": "hair", + "2": "bodySkin", + "3": "faceSkin", + "4": "clothes", + "5": "others" + }, + "categoryPixelCounts": { + "0": 659577, + "1": 157948, + "2": 76012, + "3": 183814, + "4": 494322, + "5": 2157 + }, + "hairEdgeRefine": { + "dilatePx": 6, + "lumThreshold": 110, + "addedPixels": 7398 + } + }, + "chinLine": { + "landmarkIndex": 152, + "xy": [ + 491.82, + 932.41 + ], + "marginPx": 8, + "cutY": 940.41 + }, + "faceOval": { + "landmarkLoop": [ + 10, + 338, + 297, + 332, + 284, + 251, + 389, + 356, + 454, + 323, + 361, + 288, + 397, + 365, + 379, + 378, + 400, + 377, + 152, + 148, + 176, + 149, + 150, + 136, + 172, + 58, + 132, + 93, + 234, + 127, + 162, + 21, + 54, + 103, + 67, + 109 + ], + "scale": 1.04, + "sourceImage": "base/base-front.png" + }, + "layers": [ + { + "id": "body", + "file": "layers/body.png", + "source": "base-faceless-masked+regenerated-fill", + "alphaBBox": [ + 0, + 725, + 1005, + 1566 + ], + "opaquePixels": 574074, + "greenResidue": 0, + "fillTargetPixels": 17280, + "fillSourceRaw": "raw/body.png (rejected 재생성이 아니라 수용된 body.png의 크로마키 결과; head/hairFront와 달리 body 재생성은 승인됨)" + }, + { + "id": "head", + "file": "layers/head.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 184, + 184, + 806, + 1043 + ], + "opaquePixels": 345799, + "greenResidue": 0 + }, + { + "id": "hairFront", + "file": "layers/hairFront.png", + "source": "base-faceless-masked", + "alphaBBox": [ + 258, + 413, + 719, + 802 + ], + "opaquePixels": 28325, + "greenResidue": 0 + } + ], + "rejectedRawEdits": { + "body": { + "file": "raw/body.png", + "status": "accepted-as-fill-source", + "reason": "정렬 (0,0), 형태 변형 없음 — head_mask 채움 전용 소스로 재사용" + } + }, + "composite": { + "meanAbsDiff": { + "full": 2.085797280095902, + "face": 0.3415553669119034, + "hairOutline": 7.633911850659033 + }, + "target": { + "full": 3.0, + "pass": true + }, + "backgroundNote": "카테고리0(배경)은 종이결 텍스처 노이즈(표준편차 ~29/채널)를 포함해 평탄한 크림(#EEE5D3)과 자체적으로 평균절대차 ~7 차이가 난다." + }, + "layersV2": { + "chinBandFix": { + "targetRegionPixels": 13086, + "sourceBandHeight": 150, + "rowJitterRange": [ + -2.0, + 2.0 + ], + "rngSeed": 20260930 + }, + "hairEdgeFix": { + "bandOuterPx": 40, + "bandInnerPx": 6, + "lumSmoothstep": [ + 205.0, + 150.0 + ], + "minFragmentAreaPx": 60, + "head": { + "bandOuterPixels": 72201, + "bandInnerPixels": 26037, + "componentsBefore": 80, + "removed": 77, + "removedPixels": 684 + }, + "hairFront": { + "bandOuterPixels": 6035, + "bandInnerPixels": 15130, + "componentsBefore": 129, + "removed": 125, + "removedPixels": 353 + } + }, + "hairPaperGapFix": { + "regionDilatePx": 6, + "paperColorDistThreshold": 40.0, + "paperLumThreshold": 195.0, + "paperSatThreshold": 40.0, + "opaqueAlphaThreshold": 0.95, + "regionPixels": 169288, + "head": { + "targetPixels": 1261, + "componentsBefore": 3, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + }, + "hairFront": { + "targetPixels": 11, + "componentsBefore": 4, + "removed": 0, + "removedPixels": 0, + "faceSkinAlphaDiff": 0.0 + } + }, + "jawInkFix": { + "mouthCenterY": 800.29, + "distThresholdPx": 14.0, + "mergePx": 3, + "aspectThreshold": 1.0, + "removedGroups": [], + "keptGroups": [ + { + "pixels": 42, + "bbox": [ + 299, + 801, + 304, + 814 + ], + "width": 5, + "height": 13, + "aspect": 0.385 + }, + { + "pixels": 34, + "bbox": [ + 662, + 801, + 680, + 836 + ], + "width": 18, + "height": 35, + "aspect": 0.514 + }, + { + "pixels": 2, + "bbox": [ + 310, + 825, + 312, + 828 + ], + "width": 2, + "height": 3, + "aspect": 0.667 + } + ], + "removedPixels": 0, + "strayFragmentCleanup": { + "componentsBefore": 4, + "removed": 0, + "removedPixels": 0 + } + }, + "metrics": { + "body": { + "haloPct": 0.502293077091068 + }, + "head": { + "haloPct": 0.8726695755652519, + "bgLeakAlphaMean": 4.8724556565942635e-05, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + }, + "hairFront": { + "haloPct": 0.0, + "bgLeakAlphaMean": 0.0, + "hairPaperOpaquePct": 0.0, + "disconnectedFragmentsUnder60px": 0 + } + }, + "layers": [ + { + "id": "body", + "bbox": [ + 0, + 725, + 1005, + 1566 + ], + "opaque": 558776, + "greenResidue": 1 + }, + { + "id": "head", + "bbox": [ + 174, + 151, + 822, + 1043 + ], + "opaque": 348927, + "greenResidue": 0 + }, + { + "id": "hairFront", + "bbox": [ + 220, + 413, + 755, + 836 + ], + "opaque": 33451, + "greenResidue": 0 + } + ], + "faceDetail": { + "browLandmarksSource": "manifest.landmarks.eyebrowLeft/Right", + "region": "face", + "faceInsetPx": 24.0, + "matchFacelessColor": true, + "matchFacelessColorDeltaRgb": { + "eyeLeft": [ + -16.69, + -16.87, + -17.95 + ], + "eyeRight": [ + -13.76, + -14.61, + -16.21 + ], + "browLeft": [ + 1.81, + 0.25, + -4.16 + ], + "browRight": [ + 0.58, + -0.04, + -3.37 + ], + "mouth": [ + -0.72, + -0.94, + -4.42 + ] + }, + "regions": { + "eyeLeft": [ + 315.6, + 511.2, + 458.4, + 662.8 + ], + "eyeRight": [ + 525.7, + 509.8, + 667.7, + 663.2 + ], + "mouth": [ + 377.6, + 737.5, + 603.9, + 917.4 + ], + "moles": [] + }, + "exclusionPixels": { + "eyeLeft": 11350, + "eyeRight": 10802, + "browLeft": 12463, + "browRight": 11270, + "mouth": 16631, + "union": 54127 + }, + "hairMaskPixels": 177726, + "bbox": [ + 276, + 423, + 701, + 936 + ], + "textureCloneStamp": { + "cloneTargetThreshold": 65.0, + "avoidThreshold": 110.0, + "lineOpeningIterations": 3, + "featherPx": 4.0, + "badTexturePixels": 217, + "preservedShadowPixels": 0, + "components": [ + { + "componentId": 1, + "pixels": 3, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 2, + "pixels": 2, + "offset": [ + 0, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 3, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 4, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 5, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 6, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 7, + "pixels": 1, + "offset": [ + -60, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 8, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 9, + "pixels": 4, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 10, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 11, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 12, + "pixels": 2, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 13, + "pixels": 26, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 14, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 15, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 16, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 17, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 18, + "pixels": 1, + "offset": [ + -80, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 19, + "pixels": 1, + "offset": [ + -40, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 20, + "pixels": 4, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 21, + "pixels": 1, + "offset": [ + -100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 22, + "pixels": 1, + "offset": [ + -40, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 23, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 24, + "pixels": 1, + "offset": [ + -60, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 25, + "pixels": 1, + "offset": [ + -40, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 26, + "pixels": 2, + "offset": [ + 40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 27, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 28, + "pixels": 5, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 29, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 30, + "pixels": 1, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 31, + "pixels": 7, + "offset": [ + 100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 32, + "pixels": 1, + "offset": [ + -100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 33, + "pixels": 1, + "offset": [ + 100, + 0 + ], + "method": "clone-stamp" + }, + { + "componentId": 34, + "pixels": 1, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 35, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 36, + "pixels": 1, + "offset": [ + 0, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 37, + "pixels": 2, + "offset": [ + 0, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 38, + "pixels": 1, + "offset": [ + -40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 39, + "pixels": 15, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 40, + "pixels": 2, + "offset": [ + 0, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 41, + "pixels": 2, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 42, + "pixels": 1, + "offset": [ + 0, + 60 + ], + "method": "clone-stamp" + }, + { + "componentId": 43, + "pixels": 8, + "offset": [ + 60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 44, + "pixels": 7, + "offset": [ + -40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 45, + "pixels": 8, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 46, + "pixels": 4, + "offset": [ + 40, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 47, + "pixels": 1, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 48, + "pixels": 2, + "offset": [ + -40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 49, + "pixels": 10, + "offset": [ + -120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 50, + "pixels": 1, + "offset": [ + -40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 51, + "pixels": 2, + "offset": [ + 120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 52, + "pixels": 4, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 53, + "pixels": 2, + "offset": [ + 120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 54, + "pixels": 2, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 55, + "pixels": 1, + "offset": [ + 0, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 56, + "pixels": 4, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 57, + "pixels": 3, + "offset": [ + -40, + 40 + ], + "method": "clone-stamp" + }, + { + "componentId": 58, + "pixels": 1, + "offset": [ + 0, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 59, + "pixels": 4, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 60, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 61, + "pixels": 1, + "offset": [ + 120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 62, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 63, + "pixels": 3, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 64, + "pixels": 1, + "offset": [ + -120, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 65, + "pixels": 1, + "offset": [ + 0, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 66, + "pixels": 1, + "offset": [ + 0, + -180 + ], + "method": "clone-stamp" + }, + { + "componentId": 67, + "pixels": 1, + "offset": [ + 0, + 60 + ], + "method": "clone-stamp" + }, + { + "componentId": 68, + "pixels": 1, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 69, + "pixels": 6, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 70, + "pixels": 1, + "offset": [ + 0, + 60 + ], + "method": "clone-stamp" + }, + { + "componentId": 71, + "pixels": 3, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 72, + "pixels": 2, + "offset": [ + 0, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 73, + "pixels": 1, + "offset": [ + 0, + -80 + ], + "method": "clone-stamp" + }, + { + "componentId": 74, + "pixels": 9, + "offset": [ + 0, + -150 + ], + "method": "clone-stamp" + }, + { + "componentId": 75, + "pixels": 2, + "offset": [ + 0, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 76, + "pixels": 5, + "offset": [ + -60, + -100 + ], + "method": "clone-stamp" + }, + { + "componentId": 77, + "pixels": 1, + "offset": [ + -40, + -40 + ], + "method": "clone-stamp" + }, + { + "componentId": 78, + "pixels": 2, + "offset": [ + 0, + -120 + ], + "method": "clone-stamp" + }, + { + "componentId": 79, + "pixels": 2, + "offset": [ + 0, + -60 + ], + "method": "clone-stamp" + }, + { + "componentId": 80, + "pixels": 3, + "offset": [ + 120, + -60 + ], + "method": "clone-stamp" + } + ] + }, + "genericPatches": { + "forehead": [ + 530, + 419, + 578, + 467 + ], + "cheekLeft": [ + 338, + 640, + 386, + 688 + ], + "cheekRight": [ + 513, + 641, + 561, + 689 + ] + }, + "genericPatchBaseline": { + "highFreqEnergy": 9.080476197978074, + "lineEnergy": 4.482899101781223 + }, + "checkA_meanAbsDiff": 0.551403778535253, + "checkB_seamLumDiff": 4.8619307927367, + "checkC_holeDarkResiduePct": 0.33517397699597307, + "checkC_violationPixels": 139, + "checkD_texturePreservation": { + "eyeLeft": { + "insideEnergy": 11.728178068836447, + "baselineEnergy": 9.080476197978074, + "ratio": 1.2915818304163311, + "pass": true + }, + "eyeRight": { + "insideEnergy": 9.141842269631741, + "baselineEnergy": 9.080476197978074, + "ratio": 1.0067580235128342, + "pass": true + }, + "browLeft": { + "insideEnergy": 17.537053096939957, + "baselineEnergy": 9.080476197978074, + "ratio": 1.9312922268156913, + "pass": true + }, + "browRight": { + "insideEnergy": 13.608813222720961, + "baselineEnergy": 9.080476197978074, + "ratio": 1.498689377738934, + "pass": true + }, + "mouth": { + "insideEnergy": 6.004906204634735, + "baselineEnergy": 9.080476197978074, + "ratio": 0.6612986008345941, + "pass": false + } + }, + "checkD_allPass": false, + "checkE_ghostOutline": { + "eyeLeft": { + "bandLineEnergy": 10.536511919699906, + "baselineLineEnergy": 4.482899101781223, + "ratio": 2.350379002622066, + "pass": false + }, + "eyeRight": { + "bandLineEnergy": 8.918524608958212, + "baselineLineEnergy": 4.482899101781223, + "ratio": 1.9894546824430086, + "pass": false + }, + "browLeft": { + "bandLineEnergy": 14.994533403406946, + "baselineLineEnergy": 4.482899101781223, + "ratio": 3.3448295540377115, + "pass": false + }, + "browRight": { + "bandLineEnergy": 4.481198714945496, + "baselineLineEnergy": 4.482899101781223, + "ratio": 0.999620694823345, + "pass": true + }, + "mouth": { + "bandLineEnergy": 4.588176972223662, + "baselineLineEnergy": 4.482899101781223, + "ratio": 1.023484327452431, + "pass": true + } + }, + "checkE_allPass": false, + "checkDarkCircle": { + "eyeLeft": { + "compositeMean": 142.89866666666666, + "frontMean": 142.80361904761904, + "diff": 0.09504761904761949, + "pass": true + }, + "eyeRight": { + "compositeMean": 141.6638095238095, + "frontMean": 141.38838095238094, + "diff": 0.2754285714285629, + "pass": true + } + }, + "checkDarkCircle_allPass": true + }, + "paperGrain": { + "sourceImage": "base/base-front.png", + "sourceOrigin": [ + 10, + 10 + ], + "tileSize": 256, + "personMarginPx": 20, + "cleanFraction": 0.9999847412109375, + "contaminatedPixelsFilled": 1, + "chromaKeep": 0.3, + "targetLumRange": [ + 245.0, + 250.0 + ], + "lumShift": 23.471405029296875, + "finalMeanLum": 247.49236309765936, + "finalLumStd": 2.192897744732887, + "seamContinuity": { + "leftRightDiff": 0.15942372250082334, + "topBottomDiff": 0.01046539273550214 + } + } + }, + "lipTexture": { + "designVersion": "A5(아랫입술 그늘 띠를 lip-shadow 조각으로 분리)", + "landmarks": { + "mouthCornerLeft": [ + 422.65, + 806.53 + ], + "mouthCornerRight": [ + 558.88, + 808.4 + ], + "upperLipTop": [ + 493.82, + 774.04 + ], + "lowerLipBottom": [ + 492.31, + 834.98 + ], + "mouthCenter": [ + 493.23816396296024, + 800.2905101180077 + ] + }, + "capBBox": [ + 409.76, + 769.51, + 571.76, + 839.51 + ], + "otsuThreshLabA": 135.0, + "diffThresh": 20.0, + "dilatePx": 10.0, + "alphaRampPx": 4.0, + "splitOverlapPx": 2.0, + "shadowBandPx": 18.0, + "shadowTopOverlapPx": 6.0, + "shadowSideRampPx": 6.0, + "shadowTopRampPx": 4.0, + "checks": { + "lip-upper": { + "regionPixelCount": 5345, + "fullOpacityPixelCount": 4579, + "rampPixelCount": 766, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 36, + 33, + 170, + 50 + ] + }, + "lip-lower": { + "regionPixelCount": 5690, + "fullOpacityPixelCount": 4980, + "rampPixelCount": 710, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 38, + 71, + 164, + 49 + ] + }, + "lip-shadow": { + "regionPixelCount": 3024, + "fullOpacityPixelCount": 1512, + "rampPixelCount": 1512, + "preserveMaxDiffFullOpacity": 0, + "check1Preserve": true, + "spriteBBoxWorkingLocal": [ + 58, + 77, + 126, + 51 + ] + }, + "splitOverlapPixelCount": 327, + "splitOverlapBandOk": true, + "splitOverlapAlphaMaxDiff": 0, + "splitOverlapConsistentOk": true, + "splitCoverageMismatchPixelCount": 0, + "splitCheckOk": true, + "shadowLowerOverlapPixelCount": 2256, + "shadowLowerOverlapMaxDiff": 25.3765628604383, + "shadowLowerOverlapDiffGt1PixelCount": 106, + "shadowLowerOverlapOk": false + }, + "check3NeutralComposite": { + "fullOpacityMaxDiff": 0.0, + "rampMeanAbsDiff": 3.033, + "mouthBBoxMeanAbsDiff": 1.48 + }, + "pngFileSizes": { + "lip-upper": 23136, + "lip-lower": 21665, + "lip-shadow": 18046 + }, + "canvasOrigin": { + "upper": [ + 406, + 763 + ], + "lower": [ + 408, + 801 + ], + "shadow": [ + 428, + 807 + ] + }, + "evidenceImage": "preview/v2/lip-texture.jpg", + "check4WebpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jaw": { + "designVersion": "A5(결정문 §8.4 하관 띠 변형 — 턱 조각 원본)", + "noseTip": [ + 493.52, + 712.47 + ], + "chinTip": [ + 491.82, + 932.41 + ], + "yFormula": "noseTip.y - 50 - 10 .. chinTip.y + 40", + "noseToTopPx": 60.0, + "chinToBottomPx": 40.0, + "ovalOutsetPx": 18.0, + "faceOvalSource": "export_rig.detect_face_landmarks + compute_face_oval(base-front.png, 결정적)", + "bboxCanvas": [ + 251, + 652, + 729, + 973 + ], + "naiveXRangeForComparison": [ + 251, + 729 + ], + "checks": { + "head": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 308210 + }, + "detail": { + "pngRoundTripMaxDiff": 0, + "pngRoundTripOk": true, + "pngFileSize": 356378 + } + }, + "evidenceImage": "preview/v2/jaw-pieces.jpg", + "check1VsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.673, + "maxAbsDiffPremultipliedRgb": 34.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.819, + "maxAbsDiffPremultipliedRgb": 38.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "pipelineRun": { + "persona": "P7", + "timestamp": "2026-10-01T21:42:40", + "completed": true, + "stages": [ + { + "stage": "brow_sprite", + "ok": true, + "elapsedSec": 2.84 + }, + { + "stage": "paper_grain", + "ok": true, + "elapsedSec": 2.47 + }, + { + "stage": "lip_texture", + "ok": true, + "elapsedSec": 2.27 + }, + { + "stage": "jaw_pieces", + "ok": true, + "elapsedSec": 2.2 + }, + { + "stage": "export_rig", + "ok": true, + "elapsedSec": 17.28 + }, + { + "stage": "final_previews", + "ok": true, + "elapsedSec": 19.7 + } + ] + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 15948, + "lip-lower": 15146, + "lip-shadow": 13252 + }, + "totalBytes": 44346, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 24328, + "jaw-detail": 23986 + }, + "totalBytes": 48314, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.673, + "maxAbsDiffPremultipliedRgb": 34.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.819, + "maxAbsDiffPremultipliedRgb": 38.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSprite": { + "enabled": true, + "bandExtraHalfHeightPx": 8.0, + "bandEndExtendPx": 6.0, + "diffThresh": 25.0, + "closingKernel": [ + 7, + 11 + ], + "minComponentAreaPx": 30.0, + "hairSource": "layers/v2/hairFront.png alpha(게시되는 레이어 그 자체, 분할 카테고리 아님)", + "hairAlphaThresh": 128.0, + "hairDilateIterations": 1, + "rampPx": 1.5, + "inkLumMethod": "median(ink-classified pixels in band, region after hair removal)", + "minAlphaForUnmix": 0.05, + "hairMaskPixelCount": 37836, + "left": { + "bboxCanvas": [ + 324, + 509, + 137, + 29 + ], + "halfHeightPx": 15.98, + "otsuThresh": 102.0, + "lSkin": 171.333, + "lInk": 39.667, + "regionPixelCount": 1362, + "hairOverlapPixelCount": 402, + "neutralCompositeMeanAbsDiffAlphaRegion": 7.827, + "pngFileSizeBytes": 5345 + }, + "right": { + "bboxCanvas": [ + 521, + 509, + 150, + 28 + ], + "halfHeightPx": 15.979, + "otsuThresh": 109.0, + "lSkin": 179.0, + "lInk": 44.667, + "regionPixelCount": 2054, + "hairOverlapPixelCount": 67, + "neutralCompositeMeanAbsDiffAlphaRegion": 4.989, + "pngFileSizeBytes": 7329 + }, + "canvasOrigin": { + "left": [ + 324.0, + 509.0 + ], + "right": [ + 521.0, + 509.0 + ] + }, + "evidenceImage": "preview/v2/brow-sprite.jpg", + "checkWebpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "eyeLineScale": { + "enabled": true, + "method": "눈 폭 가운데 60% 열마다 upperLidTop.y-12 ~ 홍채중심y 사이 첫 연속 어두운(lum<80) 구간 길이의 중앙값", + "windowAbovePx": 12.0, + "darkLumThresh": 80.0, + "columnMiddleFrac": 0.6, + "p1BaselinePx": 2.0, + "lineScaleClampRange": [ + 1.0, + 2.5 + ], + "left": { + "measuredPx": 10.0, + "nColumns": 54, + "ratio": 5.0, + "lineScale": 2.5 + }, + "right": { + "measuredPx": 11.0, + "nColumns": 53, + "ratio": 5.5, + "lineScale": 2.5 + } + }, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 3510, + "brow-right": 4848 + }, + "totalBytes": 8358, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "iris": { + "method": "가로: 중심 y 부근 상하 각 4행에서 중심 x를 포함하는 연속 어두운(lum<100) 구간의 중앙값으로 반지름·중심x. 세로: 중심 x 부근 좌우 각 4열에서 중심 y를 포함하는 연속 어두운 구간의 아래쪽 끝 중앙값에서 가로 반지름을 빼 중심y(세로축은 윗눈꺼풀 잉크와 홍채가 같은 톤으로 이어져 위쪽 경계를 가를 수 없다).", + "darkLumThresh": 100.0, + "scanBandPx": 4, + "left": { + "measuredCenter": [ + 387.5, + 574.5 + ], + "measuredRadius": 16.5, + "rigCenter": [ + 387.31, + 576.96 + ], + "rigRadius": 19.17, + "nRowsHorizontal": 9, + "nColsVertical": 9 + }, + "right": { + "measuredCenter": [ + 593.5, + 572.5 + ], + "measuredRadius": 16.5, + "rigCenter": [ + 595.07, + 576.86 + ], + "rigRadius": 19.41, + "nRowsHorizontal": 9, + "nColsVertical": 9 + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/persona.json b/docs/avatar-art/p7-linocut/persona.json new file mode 100644 index 0000000..db2974c --- /dev/null +++ b/docs/avatar-art/p7-linocut/persona.json @@ -0,0 +1,37 @@ +{ + "code": "P7", + "publicSlug": "p7", + "rigFileName": "p7Rig.ts", + "rigExportName": "P7_LINOCUT_RIG", + "styleFrame": "../art-direction-v3/p1/r2-b-linocut.png", + "paletteSamples": { + "ink": { + "box": [347, 244, 507, 404], + "lumThreshold": 55 + }, + "motifPetalBoxes": [ + { "label": "sun", "kind": "ochre", "box": [1230, 10, 1536, 210] }, + { "label": "tulip", "kind": "ochre", "box": [1030, 280, 1170, 560] } + ], + "motifLeafBoxes": [ + { "label": "cloudLeft", "kind": "blue", "box": [20, 20, 380, 190] }, + { "label": "raincloud", "kind": "blue", "box": [520, 10, 930, 230] }, + { "label": "wiltedFlowerLeaf", "kind": "blue", "box": [520, 280, 650, 580] }, + { "label": "closedBudLeaf", "kind": "blue", "box": [10, 290, 110, 570] } + ] + }, + "faceDetail": { + "moles": [], + "region": "face", + "faceInsetPx": 24, + "matchFacelessColor": true + }, + "pivots": { + "neck": [492, 1002], + "body": [502, 1566], + "face": [489, 660] + }, + "crops": { + "bustYOffset": 40 + } +} diff --git a/docs/avatar-art/p7-linocut/preview/qa-brow/face-zoom.jpg b/docs/avatar-art/p7-linocut/preview/qa-brow/face-zoom.jpg new file mode 100644 index 0000000..a884096 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa-brow/face-zoom.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa-brow/neutral-vs-art.jpg b/docs/avatar-art/p7-linocut/preview/qa-brow/neutral-vs-art.jpg new file mode 100644 index 0000000..69a7397 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa-brow/neutral-vs-art.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-expr-bust.jpg b/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-expr-bust.jpg new file mode 100644 index 0000000..b60a098 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-expr-bust.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-expr-face.jpg b/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-expr-face.jpg new file mode 100644 index 0000000..0f95101 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-expr-face.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-viseme.jpg b/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-viseme.jpg new file mode 100644 index 0000000..681ba02 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa-brow/sheet-viseme.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa-brow/viseme-timeline.json b/docs/avatar-art/p7-linocut/preview/qa-brow/viseme-timeline.json new file mode 100644 index 0000000..b962dc1 --- /dev/null +++ b/docs/avatar-art/p7-linocut/preview/qa-brow/viseme-timeline.json @@ -0,0 +1,287 @@ +[ + { + "t": 0, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00000.png" + }, + { + "t": 50, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00050.png" + }, + { + "t": 100, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00100.png" + }, + { + "t": 150, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00150.png" + }, + { + "t": 200, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00200.png" + }, + { + "t": 250, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00250.png" + }, + { + "t": 300, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00300.png" + }, + { + "t": 350, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00350.png" + }, + { + "t": 400, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00400.png" + }, + { + "t": 450, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00450.png" + }, + { + "t": 500, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00500.png" + }, + { + "t": 550, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00550.png" + }, + { + "t": 600, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00600.png" + }, + { + "t": 650, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00650.png" + }, + { + "t": 700, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00700.png" + }, + { + "t": 750, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00750.png" + }, + { + "t": 800, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00800.png" + }, + { + "t": 850, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00850.png" + }, + { + "t": 900, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00900.png" + }, + { + "t": 950, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t00950.png" + }, + { + "t": 1000, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01000.png" + }, + { + "t": 1050, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01050.png" + }, + { + "t": 1100, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01100.png" + }, + { + "t": 1150, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01150.png" + }, + { + "t": 1200, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01200.png" + }, + { + "t": 1250, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01250.png" + }, + { + "t": 1300, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01300.png" + }, + { + "t": 1350, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01350.png" + }, + { + "t": 1400, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01400.png" + }, + { + "t": 1450, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01450.png" + }, + { + "t": 1500, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01500.png" + }, + { + "t": 1550, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01550.png" + }, + { + "t": 1600, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01600.png" + }, + { + "t": 1650, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01650.png" + }, + { + "t": 1700, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01700.png" + }, + { + "t": 1750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01750.png" + }, + { + "t": 1800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01800.png" + }, + { + "t": 1850, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01850.png" + }, + { + "t": 1900, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01900.png" + }, + { + "t": 1950, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t01950.png" + }, + { + "t": 2000, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02000.png" + }, + { + "t": 2050, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02050.png" + }, + { + "t": 2100, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02100.png" + }, + { + "t": 2150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02150.png" + }, + { + "t": 2200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02200.png" + }, + { + "t": 2250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02250.png" + }, + { + "t": 2300, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02300.png" + }, + { + "t": 2350, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02350.png" + }, + { + "t": 2400, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02400.png" + }, + { + "t": 2450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02450.png" + }, + { + "t": 2500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02500.png" + }, + { + "t": 2550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02550.png" + }, + { + "t": 2600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02600.png" + }, + { + "t": 2650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02650.png" + }, + { + "t": 2700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02700.png" + }, + { + "t": 2750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02750.png" + }, + { + "t": 2800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa-brow\\frames\\viseme-scan-t02800.png" + } +] \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/preview/qa/face-zoom.jpg b/docs/avatar-art/p7-linocut/preview/qa/face-zoom.jpg new file mode 100644 index 0000000..05cf174 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa/face-zoom.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa/neutral-vs-art.jpg b/docs/avatar-art/p7-linocut/preview/qa/neutral-vs-art.jpg new file mode 100644 index 0000000..3420819 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa/neutral-vs-art.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa/sheet-expr-bust.jpg b/docs/avatar-art/p7-linocut/preview/qa/sheet-expr-bust.jpg new file mode 100644 index 0000000..953771f Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa/sheet-expr-bust.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa/sheet-expr-face.jpg b/docs/avatar-art/p7-linocut/preview/qa/sheet-expr-face.jpg new file mode 100644 index 0000000..9fd0afc Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa/sheet-expr-face.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa/sheet-viseme.jpg b/docs/avatar-art/p7-linocut/preview/qa/sheet-viseme.jpg new file mode 100644 index 0000000..50be32b Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/qa/sheet-viseme.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/qa/viseme-timeline.json b/docs/avatar-art/p7-linocut/preview/qa/viseme-timeline.json new file mode 100644 index 0000000..27a9d23 --- /dev/null +++ b/docs/avatar-art/p7-linocut/preview/qa/viseme-timeline.json @@ -0,0 +1,287 @@ +[ + { + "t": 0, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00000.png" + }, + { + "t": 50, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00050.png" + }, + { + "t": 100, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00100.png" + }, + { + "t": 150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00150.png" + }, + { + "t": 200, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00200.png" + }, + { + "t": 250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00250.png" + }, + { + "t": 300, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00300.png" + }, + { + "t": 350, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00350.png" + }, + { + "t": 400, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00400.png" + }, + { + "t": 450, + "viseme": "A", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00450.png" + }, + { + "t": 500, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00500.png" + }, + { + "t": 550, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00550.png" + }, + { + "t": 600, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00600.png" + }, + { + "t": 650, + "viseme": "EO", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00650.png" + }, + { + "t": 700, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00700.png" + }, + { + "t": 750, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00750.png" + }, + { + "t": 800, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00800.png" + }, + { + "t": 850, + "viseme": "O", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00850.png" + }, + { + "t": 900, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00900.png" + }, + { + "t": 950, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t00950.png" + }, + { + "t": 1000, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01000.png" + }, + { + "t": 1050, + "viseme": "U", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01050.png" + }, + { + "t": 1100, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01100.png" + }, + { + "t": 1150, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01150.png" + }, + { + "t": 1200, + "viseme": "EU", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01200.png" + }, + { + "t": 1250, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01250.png" + }, + { + "t": 1300, + "viseme": "M", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01300.png" + }, + { + "t": 1350, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01350.png" + }, + { + "t": 1400, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01400.png" + }, + { + "t": 1450, + "viseme": "I", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01450.png" + }, + { + "t": 1500, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01500.png" + }, + { + "t": 1550, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01550.png" + }, + { + "t": 1600, + "viseme": "E", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01600.png" + }, + { + "t": 1650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01650.png" + }, + { + "t": 1700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01700.png" + }, + { + "t": 1750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01750.png" + }, + { + "t": 1800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01800.png" + }, + { + "t": 1850, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01850.png" + }, + { + "t": 1900, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01900.png" + }, + { + "t": 1950, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t01950.png" + }, + { + "t": 2000, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02000.png" + }, + { + "t": 2050, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02050.png" + }, + { + "t": 2100, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02100.png" + }, + { + "t": 2150, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02150.png" + }, + { + "t": 2200, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02200.png" + }, + { + "t": 2250, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02250.png" + }, + { + "t": 2300, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02300.png" + }, + { + "t": 2350, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02350.png" + }, + { + "t": 2400, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02400.png" + }, + { + "t": 2450, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02450.png" + }, + { + "t": 2500, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02500.png" + }, + { + "t": 2550, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02550.png" + }, + { + "t": 2600, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02600.png" + }, + { + "t": 2650, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02650.png" + }, + { + "t": 2700, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02700.png" + }, + { + "t": 2750, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02750.png" + }, + { + "t": 2800, + "viseme": "X", + "shotPath": "D:\\workspace\\vignette\\docs\\avatar-art\\p7-linocut\\preview\\qa\\frames\\viseme-scan-t02800.png" + } +] \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/preview/v2/brow-centerline.jpg b/docs/avatar-art/p7-linocut/preview/v2/brow-centerline.jpg new file mode 100644 index 0000000..7ab17b2 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/v2/brow-centerline.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/v2/brow-sprite.jpg b/docs/avatar-art/p7-linocut/preview/v2/brow-sprite.jpg new file mode 100644 index 0000000..05ea9cb Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/v2/brow-sprite.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/v2/export-rig-report.json b/docs/avatar-art/p7-linocut/preview/v2/export-rig-report.json new file mode 100644 index 0000000..69698b4 --- /dev/null +++ b/docs/avatar-art/p7-linocut/preview/v2/export-rig-report.json @@ -0,0 +1,676 @@ +{ + "faceOvalBBox": [ + 260.4, + 415.8, + 716.2, + 942.6 + ], + "cropsFace": [ + 193.3, + 384.2, + 590.0, + 590.0 + ], + "mouthCenter": [ + 493.2, + 800.3 + ], + "palette": { + "ink": "#202122", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#BA9069", + "lipLower": "#C4936D", + "mouthLine": "#322F2B", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "paletteSamples": { + "eyeLeft": { + "sclera": "#D5AB81", + "iris": "#31302F", + "irisRing": "#D5AA81", + "n": { + "sclera": 1104, + "iris": 167, + "irisRing": 340 + } + }, + "eyeRight": { + "sclera": "#D5AA7F", + "iris": "#393632", + "irisRing": "#D0A67E", + "n": { + "sclera": 1130, + "iris": 171, + "irisRing": 348 + } + }, + "scleraIrisIrisRingFixedOverride": { + "reason": "persona.json paletteSamples.eyeOverride(고정 설계값)", + "measured": { + "sclera": "#D5AA80", + "iris": "#353330", + "irisRing": "#D3A880" + }, + "fixed": { + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F" + } + }, + "ink": { + "box": [ + 347, + 244, + 507, + 404 + ], + "lumThreshold": 55.0, + "n": 20938, + "hex": "#202122" + }, + "lipUpper": { + "box": [ + 417, + 771, + 563, + 798 + ], + "hex": "#BA9069" + }, + "lipLower": { + "box": [ + 417, + 802, + 563, + 837 + ], + "hex": "#C4936D" + }, + "mouthLine": { + "box": [ + 437, + 798, + 543, + 803 + ], + "hex": "#322F2B" + }, + "motifPetal": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "sun": { + "box": [ + 1230, + 10, + 1536, + 210 + ], + "n": 20570, + "hex": "#D3A661" + }, + "tulip": { + "box": [ + 1030, + 280, + 1170, + 560 + ], + "n": 4314, + "hex": "#CCA063" + } + }, + "hex": "#D0A362" + }, + "motifLeaf": { + "sourceImage": "docs\\avatar-art\\art-direction-v3\\p1\\r2-b-linocut.png", + "samples": { + "cloudLeft": { + "box": [ + 20, + 20, + 380, + 190 + ], + "n": 21312, + "hex": "#636D76" + }, + "raincloud": { + "box": [ + 520, + 10, + 930, + 230 + ], + "n": 27607, + "hex": "#586B76" + }, + "wiltedFlowerLeaf": { + "box": [ + 520, + 280, + 650, + 580 + ], + "n": 5818, + "hex": "#495961" + }, + "closedBudLeaf": { + "box": [ + 10, + 290, + 110, + 570 + ], + "n": 6589, + "hex": "#495961" + } + }, + "hex": "#53626C" + } + }, + "publish": { + "fileSizes": { + "body": 143004, + "head": 92712, + "hair-front": 25592, + "face-detail": 41908, + "paper-grain": 980 + }, + "encodeMeta": { + "quality": 80, + "scale": 1.0, + "totalBytes": 304196 + }, + "totalBytes": 304196 + }, + "grain": { + "href": "/avatar/v3/p7/paper-grain.webp", + "size": 256 + }, + "lipTexturePublish": { + "quality": "lossless", + "fileSizes": { + "lip-upper": 15948, + "lip-lower": 15146, + "lip-shadow": 13252 + }, + "totalBytes": 44346, + "budgetBytes": 81920, + "webpVsPngMeanAbsDiff": { + "upper": 0.0, + "lower": 0.0, + "shadow": 0.0 + } + }, + "jawPublish": { + "quality": 80, + "scale": 1.0, + "fileSizes": { + "jaw-head": 24328, + "jaw-detail": 23986 + }, + "totalBytes": 48314, + "budgetBytes": 204800, + "vsPublishedLayerAbsDiff": { + "head": { + "comparedAgainstPublishedLayer": "head.webp", + "meanAbsDiffPremultipliedRgb": 2.673, + "maxAbsDiffPremultipliedRgb": 34.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": false + }, + "detail": { + "comparedAgainstPublishedLayer": "face-detail.webp", + "meanAbsDiffPremultipliedRgb": 1.819, + "maxAbsDiffPremultipliedRgb": 38.0, + "meanAbsDiffAlpha": 0.0, + "maxAbsDiffAlpha": 0.0, + "meetsTarget": true + } + } + }, + "motifPublish": null, + "browSpritePublish": { + "quality": "lossless", + "fileSizes": { + "brow-left": 3510, + "brow-right": 4848 + }, + "totalBytes": 8358, + "budgetBytes": 61440, + "webpVsPngMeanAbsDiff": { + "left": 0.0, + "right": 0.0 + } + }, + "rig": { + "schemaVersion": "vignette.avatar.v3.rig.v1", + "persona": "P7", + "canvas": { + "w": 1005, + "h": 1566 + }, + "layers": { + "body": { + "href": "/avatar/v3/p7/body.webp", + "x": 0, + "y": 725, + "w": 1005, + "h": 841 + }, + "head": { + "href": "/avatar/v3/p7/head.webp", + "x": 174, + "y": 151, + "w": 648, + "h": 892 + }, + "hairFront": { + "href": "/avatar/v3/p7/hair-front.webp", + "x": 220, + "y": 413, + "w": 535, + "h": 423 + }, + "faceDetail": { + "href": "/avatar/v3/p7/face-detail.webp", + "x": 276, + "y": 423, + "w": 425, + "h": 513 + } + }, + "grain": { + "href": "/avatar/v3/p7/paper-grain.webp", + "size": 256 + }, + "lipTexture": { + "upper": { + "href": "/avatar/v3/p7/lip-upper.webp", + "x": 406, + "y": 763, + "w": 170, + "h": 50 + }, + "lower": { + "href": "/avatar/v3/p7/lip-lower.webp", + "x": 408, + "y": 801, + "w": 164, + "h": 49 + }, + "shadow": { + "href": "/avatar/v3/p7/lip-shadow.webp", + "x": 428, + "y": 807, + "w": 126, + "h": 51 + } + }, + "jaw": { + "head": { + "href": "/avatar/v3/p7/jaw-head.webp", + "x": 251, + "y": 652, + "w": 478, + "h": 321 + }, + "detail": { + "href": "/avatar/v3/p7/jaw-detail.webp", + "x": 251, + "y": 652, + "w": 478, + "h": 321 + } + }, + "motif": null, + "pivots": { + "neck": [ + 492, + 1002 + ], + "body": [ + 502, + 1566 + ], + "face": [ + 489, + 660 + ] + }, + "crops": { + "portrait": [ + 0, + 0, + 1005, + 1566 + ], + "bust": [ + 0.0, + 40.0, + 1005.0, + 1005.0 + ], + "face": [ + 193.25256299848155, + 384.20437934582236, + 590.0381387924195, + 590.0381387924195 + ] + }, + "faceOval": [ + [ + 490.5, + 415.8 + ], + [ + 555.3, + 417.3 + ], + [ + 609.5, + 425.4 + ], + [ + 658.6, + 442.5 + ], + [ + 688.8, + 469.0 + ], + [ + 706.0, + 502.9 + ], + [ + 714.3, + 539.4 + ], + [ + 716.2, + 584.5 + ], + [ + 712.6, + 628.1 + ], + [ + 706.8, + 673.7 + ], + [ + 696.8, + 722.2 + ], + [ + 681.3, + 774.6 + ], + [ + 662.0, + 818.1 + ], + [ + 641.5, + 850.8 + ], + [ + 615.8, + 880.4 + ], + [ + 592.8, + 902.0 + ], + [ + 566.9, + 921.9 + ], + [ + 534.8, + 937.4 + ], + [ + 491.9, + 942.6 + ], + [ + 449.0, + 938.5 + ], + [ + 416.4, + 923.9 + ], + [ + 389.5, + 904.8 + ], + [ + 365.4, + 883.9 + ], + [ + 338.9, + 854.2 + ], + [ + 317.7, + 821.0 + ], + [ + 298.0, + 777.0 + ], + [ + 282.2, + 723.6 + ], + [ + 271.5, + 674.4 + ], + [ + 265.1, + 628.9 + ], + [ + 260.4, + 585.3 + ], + [ + 262.1, + 540.3 + ], + [ + 270.9, + 503.5 + ], + [ + 289.1, + 469.4 + ], + [ + 320.3, + 442.7 + ], + [ + 369.9, + 425.3 + ], + [ + 425.0, + 417.4 + ] + ], + "landmarks": { + "eyeLeft": { + "inner": [ + 433.4, + 588.7 + ], + "outer": [ + 345.6, + 578.8 + ], + "upperLidTop": [ + 381.3, + 566.3 + ], + "lowerLidBottom": [ + 387.8, + 592.8 + ], + "iris": { + "center": [ + 387.5, + 574.5 + ], + "radius": 16.5 + }, + "lineScale": 2.5 + }, + "eyeRight": { + "inner": [ + 550.7, + 589.9 + ], + "outer": [ + 637.7, + 578.5 + ], + "upperLidTop": [ + 601.5, + 566.1 + ], + "lowerLidBottom": [ + 596.3, + 593.2 + ], + "iris": { + "center": [ + 593.5, + 572.5 + ], + "radius": 16.5 + }, + "lineScale": 2.5 + }, + "browLeft": { + "inner": [ + 455.8, + 527.0 + ], + "peak": [ + 369.0, + 521.2 + ], + "outer": [ + 324.2, + 527.5 + ], + "halfWidth": [ + 5.39, + 7.98, + 3.42 + ], + "sprite": { + "href": "/avatar/v3/p7/brow-left.webp", + "x": 324.0, + "y": 509.0, + "w": 137, + "h": 29 + } + }, + "browRight": { + "inner": [ + 526.5, + 526.8 + ], + "peak": [ + 619.5, + 519.8 + ], + "outer": [ + 667.5, + 527.0 + ], + "halfWidth": [ + 6.34, + 7.98, + 2.93 + ], + "sprite": { + "href": "/avatar/v3/p7/brow-right.webp", + "x": 521.0, + "y": 509.0, + "w": 150, + "h": 28 + } + }, + "noseTip": [ + 493.5, + 712.5 + ], + "mouthCornerLeft": [ + 422.6, + 806.5 + ], + "mouthCornerRight": [ + 558.9, + 808.4 + ], + "upperLipTop": [ + 493.8, + 774.0 + ], + "lowerLipBottom": [ + 492.3, + 835.0 + ], + "mouthCenter": [ + 493.2, + 800.3 + ], + "chinTip": [ + 491.8, + 932.4 + ] + }, + "palette": { + "ink": "#202122", + "sclera": "#D8CEBD", + "iris": "#4F3B2C", + "irisRing": "#1E1F1F", + "lipUpper": "#BA9069", + "lipLower": "#C4936D", + "mouthLine": "#322F2B", + "mouthInner": "#3B201B", + "teeth": "#E9E0CF", + "blush": "#C0624A", + "tear": "#EEE5D3", + "pallor": "#9AA3A6", + "paper": "#EEE5D3", + "motifPetal": "#D0A362", + "motifLeaf": "#53626C" + }, + "backdrop": { + "cognitive": "#ECE3D1", + "positive": "#F1DEC2", + "negative": "#DCE0E2", + "defensive": "#E6DAD3", + "energy": "#E2E0D0" + } + } +} \ No newline at end of file diff --git a/docs/avatar-art/p7-linocut/preview/v2/ghost-check.jpg b/docs/avatar-art/p7-linocut/preview/v2/ghost-check.jpg new file mode 100644 index 0000000..d72099f Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/v2/ghost-check.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/v2/holes-texture.jpg b/docs/avatar-art/p7-linocut/preview/v2/holes-texture.jpg new file mode 100644 index 0000000..47db1e9 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/v2/holes-texture.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/v2/jaw-pieces.jpg b/docs/avatar-art/p7-linocut/preview/v2/jaw-pieces.jpg new file mode 100644 index 0000000..8ebd6b7 Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/v2/jaw-pieces.jpg differ diff --git a/docs/avatar-art/p7-linocut/preview/v2/lip-texture.jpg b/docs/avatar-art/p7-linocut/preview/v2/lip-texture.jpg new file mode 100644 index 0000000..2a3eb7e Binary files /dev/null and b/docs/avatar-art/p7-linocut/preview/v2/lip-texture.jpg differ diff --git a/docs/avatar-art/p7-linocut/prompts/base-faceless.txt b/docs/avatar-art/p7-linocut/prompts/base-faceless.txt new file mode 100644 index 0000000..6f1dca4 --- /dev/null +++ b/docs/avatar-art/p7-linocut/prompts/base-faceless.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as faceless.png: + +Redraw exactly the same boy, same frontal pose, same framing and same linocut relief-print style as the reference, but leave the face blank: remove the eyes, eyebrows and mouth completely and fill those areas with plain skin in the same flat skin color, keeping the nose, the face outline, the ears, the hair, the neck, the white shirt collar and the charcoal sweatshirt exactly as they are. Do not move, resize or redraw anything else. Plain flat cream background, nothing else, no text. diff --git a/docs/avatar-art/p7-linocut/prompts/body.txt b/docs/avatar-art/p7-linocut/prompts/body.txt new file mode 100644 index 0000000..b9f6117 --- /dev/null +++ b/docs/avatar-art/p7-linocut/prompts/body.txt @@ -0,0 +1,3 @@ +Call the built-in image_gen tool immediately, using the attached image as the reference to edit. Do not read any files, do not use any skill, do not ask questions. Invoke the image_gen tool once in high quality, keeping the output image the same size and aspect ratio as the reference image, using exactly this prompt, then save the resulting image into the current directory as body.png: + +Keep only the neck, the white shirt collar and the charcoal sweatshirt exactly as they are in the reference: same shapes, same position, same linocut relief-print style, same ink colors and texture. Remove the head, the face, the ears and all of the hair completely. Where the hair or the chin previously covered the neck or the clothes, continue them naturally in the same style so there are no holes. Place the result on a plain flat pure green background (#00ff00) with nothing else, no text. diff --git a/docs/avatar-art/p7-linocut/raw/body.png b/docs/avatar-art/p7-linocut/raw/body.png new file mode 100644 index 0000000..974b644 Binary files /dev/null and b/docs/avatar-art/p7-linocut/raw/body.png differ