diff --git a/card-back.png b/card-back.png deleted file mode 100644 index caa4df8..0000000 Binary files a/card-back.png and /dev/null differ diff --git a/common.png b/common.png deleted file mode 100644 index a6e3b95..0000000 Binary files a/common.png and /dev/null differ diff --git a/docs/art-direction.md b/docs/art-direction.md index 3ad7690..be56af3 100644 --- a/docs/art-direction.md +++ b/docs/art-direction.md @@ -37,6 +37,17 @@ Across the whole product, the artwork should generally follow these ideas: - Prefer symbolic clarity over excessive detail. - Every card should feel like it belongs to the same product, even when different sets or traditions have their own visual flavor. +### Shared Card Typography and Text Palette + +Cards should share a stable typographic and text-panel identity across the rarity ladder. + +- Use one approved font family for all card lettering: names, excerpts, references, and any approved descriptor. Do not change the production font by tier, category, or printing. The current proof baseline uses Noto Serif; a font comparison may select a replacement, but the selected family becomes a product-wide decision. +- Use the same text color on every non-Legendary card: deep teal `#263f50`. +- Use the same text-backing base color on every non-Legendary card: cream `#f4ead4`. +- Keep those two colors stable across Common, Uncommon, Rare, and Extraordinary. Tier distinction may come from texture, inset linework, and restrained lozenge or ornament details layered over the shared cream backing. +- Texture and ornament must preserve text contrast and must not turn the backing into a new tier color. Record any tonal treatment as an overlay or material detail around the canonical base color. +- Legendary may use a bespoke text color and backing treatment when its art direction requires it, provided the lettering remains readable and the exception is documented in its template. + A good way to think about the stained-glass direction is that the cards should feel inspired by sacred windows and devotional art without needing to literally reproduce any specific historical style. --- @@ -122,7 +133,7 @@ Example: > Shepherd King > > “The LORD is my shepherd...” -> Psalm 23:1 +> Psalm 23:1 • KJV The front content priority should generally be: @@ -141,7 +152,7 @@ The full content can appear in the inspection panel. - Name: one line where practical, with an approved two-line layout for long names. - Subtitle: optional; include it only when it adds useful information. - Main excerpt or fact: initially target about 15-25 words, then validate actual typeset fit. -- Reference: a short, readable attribution. Full citations and supporting sources belong in the inspection panel. +- Reference: always use the compact format "Book chapter:verse • Translation" for Scripture, such as "Matthew 4:19 • NKJV". Use the analogous short source format for non-Scripture quotations or facts. Full citations and supporting sources belong in the inspection panel. - Use fixed text boxes, approved fonts, line spacing, alignment, and a minimum readable size for each template. - Measure actual rendered text. If it overflows, edit the wording, select a shorter faithful excerpt, or use an approved alternate layout. Do not silently shrink or clip it. - Typeset all lettering separately from generated imagery. Textless and Boundless contain no lettering, including the name and category. @@ -283,6 +294,8 @@ Generation supplies imagery and decoration; a versioned template supplies exact Create frame and backing masks from shared vector paths. Extend their joining regions underneath one another so separately antialiased edges cannot expose a seam. For Normal, export the assembled overlay as one image. Derive the other overlays from the same geometry. +The Timothy Borderless proof is trialing small rounded backing corners, a narrow softened perimeter, and no dark divider rules. The cream field stays fully opaque beneath the text. This is a printing-specific treatment of the shared panel bounds, not a change to Normal's frame joins: Normal retains its square backing and frame overlap. Do not soften a framed join into a gap. Check the combined overlay at master and delivery sizes, and derive Borderless finish protection from its actual softened backing alpha. Avoid drop shadows, heavily torn parchment, and scroll ornament for this restrained Common treatment; visual approval is pending. + Transparency masks and finish masks serve different purposes. Transparency determines visible composition; finish masks determine where surface treatment responds to light. Assemble finish coverage for each printing from its active components, with text protection derived from that printing's actual text regions. Removing a text backing also removes its associated protection. Keep an editable layered master and export the composed card face plus aligned finish maps. Three.js continues to supply materials, finish response, and interaction. Changing finish or substrate should not require regenerating the illustration. diff --git a/legendary.png b/legendary.png deleted file mode 100644 index 9eb7cd0..0000000 Binary files a/legendary.png and /dev/null differ diff --git a/spikes/card-back-concepts/README.md b/spikes/card-back-concepts/README.md new file mode 100644 index 0000000..277a9c9 --- /dev/null +++ b/spikes/card-back-concepts/README.md @@ -0,0 +1,14 @@ +# Card-back concept comparison + +Four independent concepts generated with the built-in image generation tool. The existing card-back.png and harness assets are unchanged. + +| Concept | Direction | Review note | +| --- | --- | --- | +| 01 Cathedral Rose | Teal rose window, cream/sage panes, small central cross | Closest to existing stained-glass identity; still relatively ornamental. | +| 02 Woven Burgundy | Burgundy, cream medallion, vine geometry | Warm devotional book-cover direction; densest of the set. | +| 03 Cream Seal | Cream field, teal seal, quiet rose geometry | Calmest and clearest digital silhouette; strongest minimalist direction. | +| 04 Sacred Arches | Dark slate/teal architectural glass | Strong dark alternative; geometric framing and fewer floral motifs. | + +Review all four in review/comparison.png. Originals are in source/, with exact generation prompts in source/prompts.json. No lettering was requested; any eventual wordmark should be typeset separately with the selected product font. + +These are concept assets, not approved production backs. Requested two-way rotational symmetry is approximate in generated images and has not been established as exact. The fourth concept includes a shaded perimeter that should be flattened for the runtime texture. Before promotion, refine geometry/symmetry, verify thumbnail recognition, prepare delivery sizes, preserve opaque rectangular textures, and evaluate the back in the card harness. Use one approved reverse across the rarity ladder so it does not reveal card identity or rarity. diff --git a/spikes/card-back-concepts/review/comparison.png b/spikes/card-back-concepts/review/comparison.png new file mode 100644 index 0000000..f2a0b33 Binary files /dev/null and b/spikes/card-back-concepts/review/comparison.png differ diff --git a/spikes/card-back-concepts/source/01-cathedral-rose.png b/spikes/card-back-concepts/source/01-cathedral-rose.png new file mode 100644 index 0000000..713322b Binary files /dev/null and b/spikes/card-back-concepts/source/01-cathedral-rose.png differ diff --git a/spikes/card-back-concepts/source/02-woven-burgundy.png b/spikes/card-back-concepts/source/02-woven-burgundy.png new file mode 100644 index 0000000..e65091d Binary files /dev/null and b/spikes/card-back-concepts/source/02-woven-burgundy.png differ diff --git a/spikes/card-back-concepts/source/03-cream-seal.png b/spikes/card-back-concepts/source/03-cream-seal.png new file mode 100644 index 0000000..3b3c9c4 Binary files /dev/null and b/spikes/card-back-concepts/source/03-cream-seal.png differ diff --git a/spikes/card-back-concepts/source/04-sacred-arches.png b/spikes/card-back-concepts/source/04-sacred-arches.png new file mode 100644 index 0000000..559d999 Binary files /dev/null and b/spikes/card-back-concepts/source/04-sacred-arches.png differ diff --git a/spikes/card-back-concepts/source/prompts.json b/spikes/card-back-concepts/source/prompts.json new file mode 100644 index 0000000..ade93cc --- /dev/null +++ b/spikes/card-back-concepts/source/prompts.json @@ -0,0 +1,22 @@ +[ + { + "key": "01-cathedral-rose", + "prompt": "Use case: stylized-concept. Asset type: full-face reverse artwork for a digital Christian collectible card game, Sanctification. Create ONE standalone portrait card-back design, aspect ratio 5:7, artwork flush to all four edges of an opaque rectangular canvas. Flat straight-on artwork, no mockup, no surroundings, no perspective, no cast shadow, no rounded transparent corners. Sacred, beautiful, stylized; stained-glass influence primary, tapestry and illuminated manuscript ornament secondary. Restrained high-quality devotional visual identity that remains readable at small digital binder size. No lettering, letters, numbers, wordmark, rarity, badges, watermark, glow, neon, photorealism, wear, torn paper or imperfections. This is a shared reverse across every rarity. Prefer balanced 180-degree rotational symmetry; use an equal-armed Christian cross if a cross is present, no directional symbols. Gold if used is a restrained matte antique-gold accent, never shiny casino filigree. Concept A \u2014 Cathedral Rose. A deep midnight teal field with generous quiet space. At the center, one beautifully constructed circular cathedral rose window, medium scale rather than occupying the entire card, made of large cream and muted sage panes, with a very small equal-armed cross structurally integrated into the middle. Dark lead segmentation and a few fine matte antique-gold lines. A subtle single inset architectural border with gently arched corner geometry. Strong circular silhouette, elegant restrained ornament, glass-like color depth without sparkling surface effects. No red ring, no heavy bright gold frame, no giant cross. Visually sophisticated and contemplative.", + "source": "/home/dkzver/.codex/generated_images/01a09262-4692-7342-ac44-be6af0e68cbf/exec-fbf523b0-2007-4ac3-945f-26376e382837.png" + }, + { + "key": "02-woven-burgundy", + "prompt": "Use case: stylized-concept. Asset type: full-face reverse artwork for a digital Christian collectible card game, Sanctification. Create ONE standalone portrait card-back design, aspect ratio 5:7, artwork flush to all four edges of an opaque rectangular canvas. Flat straight-on artwork, no mockup, no surroundings, no perspective, no cast shadow, no rounded transparent corners. Sacred, beautiful, stylized; stained-glass influence primary, tapestry and illuminated manuscript ornament secondary. Restrained high-quality devotional visual identity that remains readable at small digital binder size. No lettering, letters, numbers, wordmark, rarity, badges, watermark, glow, neon, photorealism, wear, torn paper or imperfections. This is a shared reverse across every rarity. Prefer balanced 180-degree rotational symmetry; use an equal-armed Christian cross if a cross is present, no directional symbols. Gold if used is a restrained matte antique-gold accent, never shiny casino filigree. Concept B \u2014 Woven Devotion. Muted deep burgundy and aubergine with a cream central cruciform lozenge medallion. The outer field is a restrained tapestry-inspired geometric weave translated into stained-glass pane shapes: interwoven vines and small diamond forms at low contrast, not literal fabric photography. A modest cream equal-armed cross appears within the central medallion, drawn with dark lead lines, flanked symmetrically by simple olive-leaf geometry. Fine antique-gold accent stitches only. Flat perimeter is dark burgundy, no thick gold outer frame. Rich and warm but calm, sacred book-cover character, restrained ornament hierarchy.", + "source": "/home/dkzver/.codex/generated_images/01a09262-4692-7342-ac44-be6af0e68cbf/exec-5d8dae8c-8d06-4857-a83a-50acea28d1fc.png" + }, + { + "key": "03-cream-seal", + "prompt": "Use case: stylized-concept. Asset type: full-face reverse artwork for a digital Christian collectible card game, Sanctification. Create ONE standalone portrait card-back design, aspect ratio 5:7, artwork flush to all four edges of an opaque rectangular canvas. Flat straight-on artwork, no mockup, no surroundings, no perspective, no cast shadow, no rounded transparent corners. Sacred, beautiful, stylized; stained-glass influence primary, tapestry and illuminated manuscript ornament secondary. Restrained high-quality devotional visual identity that remains readable at small digital binder size. No lettering, letters, numbers, wordmark, rarity, badges, watermark, glow, neon, photorealism, wear, torn paper or imperfections. This is a shared reverse across every rarity. Prefer balanced 180-degree rotational symmetry; use an equal-armed Christian cross if a cross is present, no directional symbols. Gold if used is a restrained matte antique-gold accent, never shiny casino filigree. Concept C \u2014 Quiet Cream Seal. Majority cream field, warm cream approximately #f4ead4, deep teal approximately #263f50 linework. Minimal spacious devotional design with one small-to-medium central dark teal circular seal containing a cream equal-armed Christian cross. Surround the seal with a subtle geometric rose-window halo drawn in fine dark teal lead lines, plenty of blank cream space. Thin double inset border, beautifully balanced tiny diamond motifs at the midpoint of each edge, and only a hint of muted sage within the central window. No gold except at most a tiny central accent; no text panels, decorative lettering, distressed parchment, embossed photography or busy background. Digital-first, striking, calm and timeless.", + "source": "/home/dkzver/.codex/generated_images/01a09262-4692-7342-ac44-be6af0e68cbf/exec-9af4cbbb-d6cc-4a24-8014-2f807f3af858.png" + }, + { + "key": "04-sacred-arches", + "prompt": "Use case: stylized-concept. Asset type: full-face reverse artwork for a digital Christian collectible card game, Sanctification. Create ONE standalone portrait card-back design, aspect ratio 5:7, artwork flush to all four edges of an opaque rectangular canvas. Flat straight-on artwork, no mockup, no surroundings, no perspective, no cast shadow, no rounded transparent corners. Sacred, beautiful, stylized; stained-glass influence primary, tapestry and illuminated manuscript ornament secondary. Restrained high-quality devotional visual identity that remains readable at small digital binder size. No lettering, letters, numbers, wordmark, rarity, badges, watermark, glow, neon, photorealism, wear, torn paper or imperfections. This is a shared reverse across every rarity. Prefer balanced 180-degree rotational symmetry; use an equal-armed Christian cross if a cross is present, no directional symbols. Gold if used is a restrained matte antique-gold accent, never shiny casino filigree. Concept D \u2014 Sacred Arches. An architectural all-over pattern of interlocking cathedral-window arches in desaturated midnight blue, teal, and dark slate, built from stylized leaded glass geometry. The pattern is shallow and low contrast, with a strong central cream diamond-window opening holding a simple dark teal equal-armed Christian cross. Central opening occupies about one third of card width. A few muted sage panes and very spare antique-gold joints add depth. Two-way rotational symmetry through mirrored arch geometry top and bottom. A thin dark perimeter, without a bright gold border. More architectural than floral, modern sacred visual identity with generous pane shapes and quiet supporting detail.", + "source": "/home/dkzver/.codex/generated_images/01a09262-4692-7342-ac44-be6af0e68cbf/exec-8a041d78-bdaf-4cf4-86ad-37448154237c.png" + } +] diff --git a/spikes/card-back.png b/spikes/card-back.png index caa4df8..713322b 100644 Binary files a/spikes/card-back.png and b/spikes/card-back.png differ diff --git a/spikes/card-harness/CURRENT-DEFAULTS.md b/spikes/card-harness/CURRENT-DEFAULTS.md index 0cd3af2..d2fd0a2 100644 --- a/spikes/card-harness/CURRENT-DEFAULTS.md +++ b/spikes/card-harness/CURRENT-DEFAULTS.md @@ -112,8 +112,8 @@ Changing a light type, color, position, intensity, environment contribution, or | Control | Default | Available range | |---|---:|---:| -| Finish | Holographic | Printed ink / Foil / Holographic | -| Material | Paper | Paper / Linen / Metal / Wood | +| Finish | Holographic | Printed ink / Foil / Holographic / Gold leaf / Frosted glass | +| Material | Paper | Paper / Linen / Metal / Wood / Leather | | Finish strength | 0.60 | 0-1 | | Roughness | 0.23 | 0.05-0.8 | | Surface detail | 0.14 | 0-0.45 | @@ -123,6 +123,16 @@ Changing a light type, color, position, intensity, environment contribution, or Finish and material are independent concepts, but combinations should exist only when they have an intentional visual interpretation. +Leather, Gold leaf, and Frosted glass are experimental +September 11 additions awaiting visual review. They do not change the existing +default selection or approved recipes. Leather applies generic substrate +relief and edge treatments with grain suppressed over mask-protected ink; the two +new coatings follow each card's finish mask. Vellum and Pearlescent were removed +after visual review; Leather's initial aggressive grain was replaced with shallow, +softly filtered grain pending further approval. +Frosted glass is an opaque etched coating, not a transparent card material. See the +[experimental treatment descriptions](README.md#experimental-materials-and-finishes). + ## Substrate Recipes ### Paper diff --git a/spikes/card-harness/README.md b/spikes/card-harness/README.md index 5dd3ff2..facd699 100644 --- a/spikes/card-harness/README.md +++ b/spikes/card-harness/README.md @@ -27,6 +27,32 @@ Transform gizmos and a general timeline are intentionally deferred. The separate ## Tear-open foil pack prototype +### Experimental materials and finishes + +The toolbar, Lab controls, saved experiments, and random pack pool share the same +available choices. The following treatments are visual trials, not approved defaults: + +- **Leather material:** shallow, softly rounded grain, restrained warm ink absorption, + and a brown edge. Mask-protected ink stays smooth; artwork and lettering stay anchored. + The original dense, deeply recessed grain was rejected for poor readability. + The current trial uses moderate soft-grain relief (0.0032 scene units at default + detail), between the original harsh treatment and the overly faint first revision. +- **Gold leaf finish:** warm metallic gilding with fine irregular folds and mottling, + rather than ordinary foil's mostly color-preserving sheen. + Its gold range and highlights are compressed, with more original ink retained, + to reduce contrast without removing the folded texture. +- **Frosted glass finish:** cool satin haze and fine etched microrelief, without + transparency or blurring the underlying artwork. + +Vellum and Pearlescent were removed after visual review because they were not +sufficiently distinct. Older experiments using either report an unsupported format. + +All finishes follow the supplied finish mask, including text protection. Leather also +uses the mask to suppress grain over protected ink. Other material textures cover the +substrate independently of that mask. Finish strength controls +the new coatings; Surface detail controls the material relief. No card-specific +regions, artwork generation, or additional texture files are required. + Choose **Pack** in the Mode selector (expand **Controls** first on mobile). Use **Pack style** in the same toolbar to compare three wrapper-only design studies: diff --git a/spikes/card-harness/src/cardMaterial.ts b/spikes/card-harness/src/cardMaterial.ts index 086dd7e..ef398c1 100644 --- a/spikes/card-harness/src/cardMaterial.ts +++ b/spikes/card-harness/src/cardMaterial.ts @@ -1,8 +1,10 @@ import * as THREE from 'three' import { cardSceneDimensions } from './cardGeometry' -export type FinishName = 'Printed ink' | 'Foil' | 'Holographic' -export type SubstrateName = 'Paper' | 'Linen' | 'Plastic' | 'Metal' | 'Wood' +export const finishNames = ['Printed ink', 'Foil', 'Holographic', 'Gold leaf', 'Frosted glass'] as const +export const substrateNames = ['Paper', 'Linen', 'Metal', 'Wood', 'Leather'] as const +export type FinishName = typeof finishNames[number] +export type SubstrateName = typeof substrateNames[number] | 'Plastic' export interface MaterialControls { finish: FinishName @@ -31,6 +33,7 @@ export function applyEdgeMaterialControls( Plastic: { color: '#d4cab0', wornColor: '#c7ccd2', roughness: 0.24, metalness: 0, clearcoat: 0.72 }, Metal: { color: '#a8adb7', wornColor: '#d0d5dc', roughness: 0.2, metalness: 0.86, clearcoat: 0.18 }, Wood: { color: '#6b3f21', wornColor: '#a87847', roughness: 0.56, metalness: 0, clearcoat: 0.08 }, + Leather: { color: '#503023', wornColor: '#976c49', roughness: 0.72, metalness: 0, clearcoat: 0.04 }, } const look = edgeLooks[controls.substrate] material.color.set(look.color) @@ -134,6 +137,13 @@ const fragmentShader = ` return sin(phase) * visibility; } + float leatherGrain(vec2 uv) { + vec2 p = uv * vec2(42.0, 58.8); + float visibility = 1.0 - smoothstep(0.2, 0.65, max(fwidth(p.x), fwidth(p.y))); + float pebbles = smoothstep(0.15, 0.85, fiberNoise(p)); + return mix(0.5, pebbles, visibility); + } + // Height and analytic UV slopes keep thread ridges lit even at oblique angles. vec3 linenRelief(vec2 uv, vec4 visibility) { vec2 frequency = vec2(52.0, 73.0) * 6.2831853; @@ -205,6 +215,7 @@ const fragmentShader = ` if (substrateMode == 2) wearColor = vec3(0.78, 0.80, 0.82); if (substrateMode == 3) wearColor = vec3(0.72, 0.75, 0.80); if (substrateMode == 4) wearColor = vec3(0.62, 0.39, 0.20); + if (substrateMode == 6) wearColor = vec3(0.59, 0.40, 0.25); float abrasion = clamp( edgeWear * 0.55 + scratchWear * 0.30 + scuffWear * 0.22, 0.0, @@ -280,6 +291,8 @@ const fragmentShader = ` float woodSurfaceGrain = 0.5; float metalEtchDepth = 0.0; float metalEtchExposure = 1.0; + float leatherPebble = 0.5; + float leatherCoverage = smoothstep(0.08, 0.65, mask); if (substrateMode == 0) { vec2 fiberUv = artworkUv * vec2(230.0, 322.0); float visible = 1.0 - smoothstep(0.4, 1.2, max(fwidth(fiberUv.x), fwidth(fiberUv.y))); @@ -328,8 +341,33 @@ const fragmentShader = ` surfaceHeight = woodSurfaceGrain * relief; surfaceShade = 0.88 + woodSurfaceGrain * 0.12; } + if (substrateMode == 6) { + vec3 view = normalize(cameraPosition - vWorldPosition); + vec2 alongSurface = vec2(dot(view, normalize(vWorldTangent)), + dot(view, normalize(vWorldBitangent))); + float relief = 0.0032 * min(detail, 1.5); + float grain = leatherGrain(artworkUv); + vec2 parallax = alongSurface / max(abs(dot(view, normalize(vWorldNormal))), 0.35) + * (grain - 0.5) * relief / cardFaceSize; + leatherPebble = leatherGrain(artworkUv + parallax); + // Treat protected ink as a smooth printed layer, not recessed leather grain. + surfaceHeight = (leatherPebble - 0.5) * relief * leatherCoverage; + surfaceShade = 1.0 - (1.0 - leatherPebble) * 0.10 * min(detail, 1.5) * leatherCoverage; + } + // Only coating microrelief follows the finish mask; protected text stays flat. + if (finishMode == 3) { + float leafFold = filteredWave(artworkUv.x * 270.0 + + fiberNoise(artworkUv * vec2(28.0, 39.2)) * 16.0); + surfaceHeight += leafFold * 0.0012 * mask * finishStrength; + } + if (finishMode == 5) { + vec2 frostUv = artworkUv * vec2(190.0, 266.0); + float visible = 1.0 - smoothstep(0.4, 1.2, max(fwidth(frostUv.x), fwidth(frostUv.y))); + surfaceHeight += (fiberNoise(frostUv) - 0.5) * visible * 0.0025 * mask * finishStrength; + } surfaceHeight -= scratchWear * 0.0018 + scuffWear * 0.0007; float substrateNormalScale = substrateMode == 3 ? 0.06 : 0.12; + if (substrateMode == 6) substrateNormalScale = 0.0; vec3 normal = normalize( vWorldNormal + vWorldTangent * normalSample.x * normalStrength * substrateNormalScale + @@ -369,6 +407,7 @@ const fragmentShader = ` if (substrateMode == 2) substrateRoughness = min(roughness, 0.25); if (substrateMode == 3) substrateRoughness = min(roughness, 0.20); if (substrateMode == 4) substrateRoughness = max(roughness, 0.48); + if (substrateMode == 6) substrateRoughness = max(roughness, 0.62); float nDotV = max(dot(normal, viewDirection), 0.0); float dielectricFresnel = 0.04 + 0.96 * pow(1.0 - nDotV, 5.0); @@ -420,6 +459,10 @@ const fragmentShader = ` vec3 woodTint = mix(vec3(0.72, 0.40, 0.18), vec3(1.0, 0.86, 0.65), woodSurfaceGrain); printedInk *= mix(vec3(1.0), woodTint, 0.25); } + if (substrateMode == 6) { + printedInk *= mix(vec3(1.0), vec3(0.98, 0.94, 0.88), leatherCoverage); + printedInk += lightColor * substrateSpecular * leatherPebble * 0.12 * leatherCoverage; + } if (finishMode == 0) { vec3 wornInk = applyWearColor(printedInk, edgeWear, scratchWear, scuffWear); gl_FragColor = vec4(wornInk, artworkSample.a); @@ -434,6 +477,32 @@ const fragmentShader = ` float specularPower = mix(96.0, 10.0, substrateRoughness); float directSpecular = pow(max(dot(normal, halfVector), 0.0), specularPower); float environmentBrightness = dot(environment, vec3(0.2126, 0.7152, 0.0722)); + if (finishMode >= 3) { + vec3 treatment = printedInk; + if (finishMode == 3) { + float leafMottle = fiberNoise(artworkUv * vec2(38.0, 53.2)); + vec3 gold = mix(vec3(0.76, 0.51, 0.19), vec3(0.92, 0.71, 0.34), leafMottle); + float inkLuma = dot(artworkSample.rgb, vec3(0.2126, 0.7152, 0.0722)); + vec3 gilding = gold * (0.42 + direct * 0.30 + inkLuma * 0.28); + gilding += gold * environment * environmentIntensity * (0.30 + fresnel * 0.35); + gilding += lightColor * vec3(1.0, 0.85, 0.46) + * min(directSpecular * lightIntensity * attenuation * 0.40, 0.28); + treatment = mix(printedInk, gilding, 0.48); + } + if (finishMode == 5) { + float satin = pow(max(dot(normal, halfVector), 0.0), 8.0) + * diffuse * lightIntensity * attenuation; + vec3 coolFrost = vec3(0.79, 0.90, 0.95); + treatment = mix(printedInk, coolFrost * (0.38 + direct * 0.32), 0.32); + treatment += coolFrost * (satin * 0.22 + fresnel * environmentIntensity * 0.32); + } + vec3 coated = mix(printedInk, treatment, clamp(mask * finishStrength, 0.0, 1.0)); + coated = applyWearColor(coated, edgeWear, scratchWear, scuffWear); + gl_FragColor = vec4(coated, artworkSample.a); + #include + #include + return; + } if (substrateMode == 3 && finishMode == 1) { float plateSpecular = pow(max(dot(normal, halfVector), 0.0), 150.0); float plateEdge = smoothstep(0.003, 0.055, fwidth(mask)); @@ -555,6 +624,8 @@ export function applyMaterialControls( 'Printed ink': 0, Foil: 1, Holographic: 2, + 'Gold leaf': 3, + 'Frosted glass': 5, } const substrateModes: Record = { Paper: 0, @@ -562,6 +633,7 @@ export function applyMaterialControls( Plastic: 2, Metal: 3, Wood: 4, + Leather: 6, } material.uniforms.finishMode.value = finishModes[controls.finish] material.uniforms.substrateMode.value = substrateModes[controls.substrate] diff --git a/spikes/card-harness/src/main.ts b/spikes/card-harness/src/main.ts index 63a2743..c9f88e0 100644 --- a/spikes/card-harness/src/main.ts +++ b/spikes/card-harness/src/main.ts @@ -7,6 +7,8 @@ import { applyMaterialControls, createCardMaterial, createStudioCubeTexture, + finishNames, + substrateNames, type FinishName, type MaterialControls, type SubstrateName, @@ -101,17 +103,12 @@ document.querySelector('#app')!.innerHTML = `