Repository navigation
CC5 avatar editor, cc5-shape crate and CC5 shader materials - #1
Open
matbeedotcom wants to merge 59 commits into
Open
matbeedotcom wants to merge 59 commits into
matbeedotcom wants to merge 59 commits into
Conversation
The avatar editor's studio key light uses PCSS (percentage-closer soft shadows) to match Character Creator 5's soft shadowing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- crates/cc5-shape: Character Creator 5 shaping sliders outside CC5 (Rust + CPython module): slider pack evaluation, shaped GLB writing, CPU facial expressions (all ~480 CC5 morphs + ARKit mapping), and HD (subdivided) character support via a level-0 -> HD stencil map (SubdivMap, shape_glb_hd); Python fitting helpers in cc5_shape.fit. - examples/avatar_editor.rs: live CC5 slider editor in Bevy with recipes, style layers, expressions, --hd for CC5's HD mesh, snapshot mode, and a studio look calibrated against CC5's viewport. - examples/shape_avatar.rs: headless weights JSON -> shaped GLB. - src/cc_render/cc5_materials: Cc5MaterialsPlugin builds Bevy extended materials for CC5's RLHead/RLSkin, RLHair, RLEye, eye occlusion/tearline and teeth/tongue shaders from the maps and parameters glb_cc5_materials.py records in glTF material extras. - docs/design/avatar-editor.md: pipeline, pack format and accuracy notes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Smart-Hair-style hair parts (`--hair-lib`): strand parts converted from
CC5's Smart Hair groups, chosen per slot or by style, re-bound to our
skeleton and moved with the body on every shape / expression change.
- cc5-shape: `Conform` binds an uncaptured mesh to body anchor vertices
(modes scalp / skin / head_box, calibrated against CC5's own placement
on reshaped heads); Python binding.
- avatar_editor/hair.rs: catalog / styles / regions, per-mesh `follow`
("head_box" for layers CC5 moves rigidly, "bone:<joint>@x,y,z" for
layers CC5 attaches to a bone, using per-slider bone rotation / scale
from `bone_xf.json`), `bald` styles, own hair / brows hidden when replaced.
- avatar_editor: head view aims at our rig's eye joints only (hair parts'
skeletons used to drag the camera).
- cc5_materials: mip chains for hair textures and a negative opacity mip
bias for scalp hair, so strands stay resolved instead of aliasing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conform::bind compared every asset vertex with every anchor: 4.7 M hair vertices x 4754 head anchors took 12-63 s per part in the avatar editor. Anchors now sit in a uniform grid searched in cubic shells (exact k nearest, ties by index) and vertices bind in parallel with rayon: 0.2 s. A test checks the result against the brute force on random points inside and far outside the anchor cloud. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
crates/cc5-hair ports hair_build.py's CC5 conversion out of Blender: Smart Hair cards -> strands (clumps, acceptance, start at the texture's hairline, depth shading), shape edits (length, comb, gravity, curl, frizz), kept CC5 card layers (brows, scalps), follow detection (head box / bone, from CC5's shape OBJs and bone dumps) and part GLBs with quantized attributes. The `cc5-hair` CLI bakes one spec or every Smart Hair group (smart_hair.json): the whole library in ~15 s instead of ~25 min in Blender, matching the Python build against CC5 within noise. avatar_editor: - `--hair-src/--hair-head/--hair-config`: a live hair panel (group, look, shape, colour); changes rebuild the part in the background (~1 s) and swap it in; colour edits only rebuild materials; Save writes the library part, catalog, style and settings. `--hair-edit` applies settings at start. - `--snapshot-batch jobs.json`: many snapshots (style, recipe, hair edit, camera) in one process (~6 s each instead of a process per image). - hair.rs: shared conform / bone-follow helpers; parts built in memory. - cc5_materials: Cc5MapBase gives in-memory meshes the asset path their extras.cc5 maps resolve against. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…reads FBX cc5-fbx reads a CC5 FBX export with ufbx and writes the GLB the avatar editor loads (what Blender's import + glTF export made via fbx_to_glb.py): meshes per material with _CCIDX, the skin in bind pose (FBX joint orientations, metres, Y up), diffuse + opacity merged into the base colour, normal maps, roughness from shininess. --dump writes fbx_to_glb.py's joints/weights/rest-position dump; --cc5-json adds CC5's tints/opacity and extras.cc5 with its maps (TGA decoded in-crate so the image crate's features, shared with Bevy, stay unchanged). Against Blender on the beautiful reference and HD exports: positions within 2.4e-7 m, identical weights (and group order), joints, UVs, materials and images; the dump builds the same editor pack (6.5e-7 m); editor renders match. 0.5 s per character instead of a Blender run. cc5-hair's Source::load takes an FBX directly (converted in memory, CC5 settings from the sidecar JSON); an FBX head supplies its own CC5 material settings. Smart Hair groups may hold character.glb or character.fbx. The own hair baked from the raw FBX matches the GLB bake (117,860 vs 117,861 strands, identical materials and follow modes). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n the vertex shader cc5-hair writes strands as glTF LINES (one vertex per point: position, (ID, t) UV, colour, half-width in TEXCOORD_1, skin) and flags their materials extras.cc5.ribbons; `--ribbons` keeps the old triangle ribbons for comparison. The library shrinks from 1044 to 437 MB. The editor turns each LINES mesh (loaded or built live) into two vertices per point at the point, TANGENT = (strand direction, -/+ half-width), and the conform moves only the points (Ribbon::write expands them in parallel). Cc5Hair gets a `ribbons` pipeline key: its specialize swaps in hair_vertex.wgsl (forward + prepass, adding normal and tangent to the prepass layout), which skins the centre like Bevy's mesh shader and offsets it across the strand facing the view; the width follows the strand's facing halfway (FACING 0.5) and is scaled by 2/pi in shadow maps, calibrated against CC5. Card hair keeps Bevy's shaders. Lighting normals point out from the head (what fixed ribbons showed through their back faces). Parts stay hidden until bound. Parity vs CC5 (14 groups x alika / extreme): diff 12.00 vs 12.07 for triangle ribbons, detail 6.04 vs 6.13 (CC5 6.62). Shape update 29 ms vs 34-47 ms. Conform::apply runs in parallel. Also strips a UTF-8 BOM from cc5-fbx/src/glb.rs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…editor - `cc5-hair regions <character.fbx | dump.json> --lib`: the library's regions.json (port of hair_regions.py; identical output, also read straight from the FBX). - `cc5-hair check --src <dir> <group>...`: the conform against CC5's own reshaped hair (port of check_conform_cc5.py; identical numbers, 8x faster). - `bake --style <name>`: a style of the baked part (the own-hair "CC5 Converted"). - A library without atlas/<atlas>/atlas.json uses built-in RLHair defaults. - Editor: `--snapshot-batch` jobs take `save: true` (the panel's Save, for scripted save -> restart -> load checks); hair-edit build failures are logged; a scripted edit's "group" key no longer lands in the saved settings. - Docs point to cc5-fbx / cc5-hair instead of the removed Python scripts. Verified: a library built only with cc5-fbx / cc5-hair from raw CC5 FBX exports (no Blender on PATH) in 11 s, 34 gallery renders clean; live edit of a group that is only a raw character.fbx; saved edit reloads as rendered live (blurred diff 0.24 vs 1.20 to the unedited part). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nel-like scripted edits - `cc5-fbx expressions <ref.fbx> <pack dir> <out dir>` writes expressions.json + .bin from the FBX's morph targets (ufbx blend shapes), replacing Blender's build_expression_pack.py: on the reference character the same 480 expressions, same vertices, deltas within 3.7e-9 m, in 0.2 s. - Snapshot-batch edits behave as the Hair -> Edit panel: settings add to the group being edited, colour variables alone recolour without a rebuild, a job with an edit keeps the edited part; build and recolour timings are logged. Side part wavy (largest): open 1.6 s, density 0.8 s, gravity 0.8 s, root colour 24 ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ettings; opt-in input log Driving the Hair -> Edit panel with real clicks and drags (group pick, density, gravity, root colour, Reset to saved) showed settings the config leaves out displayed at the slider's start (gravity -0.05 instead of 0): they now show cc5-hair's own defaults. CC_DEBUG_INPUT=1 logs the window's pointer input for scripted UI checks. Panel timings on Side part wavy: open 1.4 s, density 0.4 s, gravity 0.5 s, root colour without a rebuild, reset 1.3 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A synthetic character (two joints, a skinned CC_Base_Body quad) checks that Body::skin_at returns normalised top-4 weights, and that a strand part written as LINES (and with --ribbons as triangles) reads back with the gltf crate: the head's skeleton by name, one vertex per point and consecutive segments, half-widths in TEXCOORD_1, extras.cc5.ribbons, normalised weights. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A CC5 Smart Hair group (Viking) and an accessory (the earring) each bring a joint named CC_Base_Pivot; Blender names the later one CC_Base_Pivot.001. cc5-fbx kept both names, which collapsed them in the name-keyed dump and would confuse rebinding by name. On a fresh Viking group export cc5-fbx now matches Blender's fbx_to_glb.py: 107 joints by name within 7e-7 m, all 19 meshes within 3.6e-7 m, identical weights, UVs, materials and dump; the part built from the raw FBX equals the library's (77,512 strands, same bone follow). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dragging expression sliders in the editor (checking the cc5-fbx expression pack) showed two layout bugs: the section's id came from its label, whose "N active" count changes on the first move, so it collapsed under the pointer; and the Neutral button appeared above the sliders once one was active, shifting every row mid-drag. The header has a stable id now and the button is always shown (disabled at neutral). With the cc5-fbx pack, Eye_Blink_L/R at 1 close both eyes; V_Open reaches 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`--base none | neutral_f | neutral_m | <slider> | <recipe.json>` sets the body
the editor starts from and "Reset all" / per-slider reset return to. Without
it, a pack with CC5's neutral bases (pack_xl: avatar_neutral_f / _m) starts on
the neutral female; other packs on the captured character as before. The panel
shows the base, and changed sliders are counted against it.
Recipes keep the base apart from the changes: cc5-shape's recipe_on() writes
{"base": {...}, "sliders": {...}} and weights_from_recipe() applies both, so a
saved recipe gives the same body anywhere (plain recipes read as before).
Checked in the editor on pack_xl: starts as the neutral female with 0 sliders
changed; one change, Save, Reset all (back to 0) and Load (1 again) work.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without `character.glb pack_dir` the editor opens $CC5_EDITOR_DIR (default D:\cc5_editor\beautiful_e2e, build_cc5_editor_pack.ps1's output): its character.glb and pack_xl, else pack. With pack_xl's neutral bases that starts on CC5's neutral female; the environment map already defaults to the character's env folder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ers), CC5 camera/lights/IBL for comparisons - Cc5Skin keeps the CC5 settings it was built from; set_vars rebuilds the uniform - skin.rs: CC5's RLHead/RLSkin settings edited live, skin recipes (--skin), skin packs (--skin-pack, default <character dir>/skin): whole skins and SkinGen layers composited over the diffuse in the background; --hide-hair - cc5_scene.rs / ibl.rs: --cc5-scene views (cc5:face) at CC5's camera, --cc5-lights with CC5's spot lights and its IBL HDR prefiltered in memory - crates/cc5-skin: pack format, compositor, builder from CC5 captures Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- skin.wgsl: subsurface wrap and transmission for point and spot lights too; shader constants as SkinTune (Cc5Materials::skin_tune, CC5_SKIN_TUNE), new defaults from CC5 renders (full normal detail in the diffuse, specular 0.6) - RLHead/RLSkin normal maps are DirectX-style: flip_normal_map_y (fixes lighting steps at UV seams: philtrum, nose) - --cc5-lights: CC5's rect lights without inverse-square falloff, tube radii, calibrated intensities, tint, Top gain, saturation 1.6 (flat grey: dE 3.5) - editor camera: contrast-adaptive sharpening 0.5 (CC5's crisp viewport detail) - skin: flat albedo kept every frame; --hide-hair keeps brows (as CC5) - cc5-skin: layer solve test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uration Fitted to CC5's baked exports (human colour: per-channel sRGB gains per _Red/_Yellow/_Black/_Range, cc5_materials/human_color.rs; blend map: linear lerp) and its renders (saturation about the max channel x(1+2s), brightness exp(8b) on the linear albedo); against CC5's render changes: 2-9 dE on changes of 5-50. cc5-skin build: flat-image second base, held-out check base. Design doc: Skin section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…within 1%); hide_brows for CC5 comparisons Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ted into the metallic-roughness texture Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d normal maps, blended and renormalized Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tick, blush, eyeshadow, contour, highlight, freckles, stubble), any colour, in recipes and the Skin panel Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tubble, lipstick keeps the lips' shading (Apply::detail) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd normal strength; generator pattern controls (dot size, density, variation); all in recipes and the Skin panel Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… where the character's own mole is, it lands on the same spot Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CC5's SkinGen bake composites onto its own base skin, so a flat diffuse set with LoadImageToTexture never reaches the bake; the two bakes match and the opacity solve degenerates to alpha 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… of the welded smooth normal (shape_glb and the editor, expressions too) A reshape moved positions only, so a large one kept the capture's shading: the neutral male base on a female capture rendered breasts on a flat chest (old normals 24 deg off the surface across the chest, median). On CC5's own neutral_m geometry the turned normals match CC5's exported normals to p99 0.05 deg; unmoved vertices keep their normals bit for bit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SkinGen layers are not all normal blends: fitted on two baked skin bases, tattoos, contour, tans, beards and freckles multiply and highlights screen (errors 3-4 levels as normal, 0.2-0.6 with the right mode). The build solves each mode and keeps the best per layer map; LayerImage carries the mode and compose applies it, so strength and tint work for all modes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A SkinGen preset can hold layers in several modes (full makeup: the lipstick multiplies, the rest is normal): the build keeps, per texel, another mode where it explains the texel clearly better, as parts of the layer map sharing its rect; compose lays the parts after the map. Full makeup: 0.97 -> 0.47 levels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CC5's response to colour changes (makeup, beards, foundation) matches ACES far better than AgX with a saturation boost. Swept against CC5's renders: ACES +0.9 EV, saturation 1.0, sharpening 0.15. Over 8 skins and 25 SkinGen layers: mean dE 4.4 (layers 5.14 -> 4.30), error in the layers' change from the base 0.89 -> 0.61, detail 1.00. Docs: the dark second base and blend modes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er-layer second base Blush, eyeshadow, contour, highlight, freckles and stubble take their shape from a weighted sum of region-mask features (blurred, bands, moved down / away from the face's centre line) fitted to CC5's preset layers (soft IoU against them: 0.38->0.59, 0.57->0.77, 0.19->0.47, 0.13->0.28, 0.22->0.68, 0.39->0.54); lipstick and spots keep their hand-made shapes. 'cc5-skin generate' exports each generator for fitting; 'alt_for' in the build spec solves a layer on another second base (redness, over CC5's 15-layer cap on the first). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ge, finish, decals) As SkinGen's Layer Advanced Settings, on every layer: Adjust Color (hue, saturation, brightness, contrast) and a Layer Mask (a head region and / or a greyscale image, invertible). Generated layers: blend mode, Range (expansion, blur, contrast), roughness finish, any number of each kind. Decals: an image placed on a material (place, size, rotation, blend, strength, adjust, mask). All in the recipe. Generator defaults (colour, strength, blend, stubble density) fitted through their shapes to CC5's presets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ertical) The editor's 25-degree lens (~53 mm) showed faces with more perspective than CC5's viewport; distances scale with the FOV, so framing stays the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CC5's renders scale uniformly from ours (fitted silhouettes: 0.881 x, 0.881 y), so CC5 fits the 36 x 24 mm gate's height to the image rather than stretching the gate: the vertical angle is the gate's (17.06 deg at 80 mm) whatever the image's aspect. Render at CC5's size (1651x961) and compare directly; the old 1651x1101 + resize made faces ~14% too wide. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…inst CC5 CC5's eye map paints the pupil at 0.375 of the iris; its render of Ariana shows 0.31 = 0.375 x Pupil Scale 0.96 / Iris UV Scale 1.161, with the iris edge in place: Iris UV Scale now shrinks the pupil too (we ignored it: pupils ~45% too big). IRIS_LIGHT 1.9 -> 6.5: the iris was 3.5x too dark against CC5 (L 7.5 vs 20, sclera matching), now L 21.5 vs 21.3. Snapshots ignore mouse camera input (the window opens on the user's desktop; a stray scroll had zoomed two batch frames). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aps, CC5-mode hair gain - CC5's SSS map is centred on mid grey (0.5 = full strength, as without a map): HD skins' ~0.5 maps halved the subsurface light (pale, grey 'ghost' faces). HD Neutral F dE 5.70 -> 4.97, HD Aaron 4.70 -> 3.83. - Mip chains for every skin texture (and the composited diffuse): 2K-8K maps seen a few hundred pixels across aliased into blotches and harsh creases. Old skin dE 5.08 -> 4.69, detail 1.16 -> 1.04. - cc5-skin build downscales skin maps to the pack's size (CC5 exports HD skins at 8192 from their 2K presets). - Hair: diffuse / specular gains for scalp hair in CC5 mode (CC5_HAIR_GAIN, default 2, 1 with CC5's lights): hair regions' dE 11.8 -> 7.9. - SkinTune: normal map strength and diffuse normal blur (off by default). - Editor: compositing bases and region masks read the top mip level. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Blend::Overlay and SoftLight for generated layers and decals (captured layers keep the normal / multiply / screen they solve to). - Generated layers and decals reorder (lay before the one above). - CC5 mode: ambient 80 -> 140 and the skin's extra wrap 0.08 -> 0.16, fitted at CC5's framing over the bare skin and three skins: mean patch dE 5.04 -> 4.77. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(1, 0.92, 1.15) -> (1, 0.94, 1.10): patch dE bare skin 4.58 -> 4.23, HD Neutral F 4.68 -> 3.88, HD Aaron 4.02 -> 3.29. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erials An occasional frame showed the character's own diffuse after a skin preset; the snapshot now waits until every skin material shows its composite (and warns when it had to). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e too Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scene.json records no rect size, so they cast hard shadows; fitted against CC5's renders: patch dE bare skin 4.24 -> 4.12, HD Neutral F 3.88 -> 3.80, HD Aaron 3.29 -> 3.18. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…terial extras) Every layer (captured, generated, decal) can lay a metallic value (into the metallic-roughness map's B), an occlusion (into the AO map) and a glow (an emissive colour at a strength, composited into an emissive map), each through its opacity; in the recipe as "extras". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CC5's stubble layer is ~0.1 opaque between hairs and ~0.45 on them; ours was dots only (sub-pixel at a face view, averaged away). Against CC5's preset in render: change error 1.26 -> 1.12 (CC5's change 1.6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dots a fifth of a pixel across at a face view averaged into nothing: the hairs are now short soft strokes (down the face, +-35 deg) in the hair colour over a pale grey-beige haze (a part of the layer), as CC5's stubble looks. Default hair colour (80, 68, 58) at 0.7. Against CC5's preset: visibly stubble, detail 0.62 -> 0.70. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Key Light - Up 1.15, Left_Rim 1.3, Top 1.6 (was 2.5), Key Light - Down 1.3: mean patch dE over the bare skin and three skins 4.09 -> 3.76. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Snapshot jobs take "cc5": {tint, ambient, ibl, exposure, sat, gains,
skin_tune}; Cc5Live applies them live (grading, IBL re-prefiltered on a tint
change, lights, ambient, skin materials' SkinTune) and the shot waits until
they are on. A whole calibration sweep is one launch (~3 s a shot) instead of
one launch (~40 s start-up) per setting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ap / SSS / ambient - Hair: a colour multiplier (Cc5Materials::hair_tint, CC5_HAIR_TINT), in CC5 mode the light tint's inverse: neutral hair no longer reads pink-mauve (bangs a/b 10.9/7.1 -> 9.7/8.8; CC5 7.9/6.8). - Skin wrap 0.16 -> 0.09, SSS falloff desaturation 0.35 -> 0.41, ambient 140 -> 110: refitted on the whole face over five faces in batched launches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Flipped, the large-scale relief in SkinGen's full skins (cheeks, nasolabial folds) shaded as dark blotches that CC5 doesn't have. Unflipped is better or equal on all five check faces: patch dE 3.50 -> 2.79, face dE 7.53 -> 7.27. CC5_NORMAL_FLIP_Y=1 restores the flip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bevy's PCSS sizes the penumbra from the blocker / receiver gap, so a nose or eyelid shadowing skin about a centimetre away stays hard-edged at any light radius. That gave a lighting step down the philtrum and dark crescents under the eyes. In CC5 mode, Bevy's shadow sampling is replaced by a vendored copy with a minimum blur of 25 (Bevy: 0.5), fitted on five faces: face dE 7.27 -> 7.10, patches 2.79 -> 2.73. Also: diagnostic knobs CC5_SHADOWS, CC5_SHADOW_OFF (light names) and CC5_RADIUS_SCALE; the eye occlusion / tearline films are explicitly not shadow casters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n CC5 mode The hair shader's anisotropic strand lobes (primary, TRT, transmission) only looped over directional lights. CC5's lights are all spot lights, so CC5-mode hair had no strand highlights at all. Clustered lights now get them too, through the same walk as the skin shader. The root occlusion is now a Cc5Materials setting (hair_root_occlusion, in the hair params' tint.w): studio 0.55, CC5 mode 0.3 (cc5_scene::HAIR_ROOT_OCCLUSION, knob CC5_HAIR_ROOT_OCC). Five faces: face dE 7.10 -> 6.91; hair region (hair_metric.py) dE 10.33 -> 9.55, L* -7.8 -> -5.2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CC5's renders have a fixed screen-space backdrop (identical in face and body framings): a grey-blue radial falloff. With `backdrop.png` next to the CC5 scene file (fitted from CC5's renders, RMS 1.4 levels), the camera's skybox becomes that image: - a view-space cubemap at FOV_DEG and the image's aspect; - texels pre-inverted through Bevy's ACES fitted tone mapping and the CC5 grading exposure; - turned with the camera every frame (cc5_backdrop_follow). Renders match CC5's backdrop within about 2 levels (was up to 25 darker), and hair edges blend over the same backdrop: five-face dE 5.18 -> 5.14 (character-masked). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r, blush, freckles New fitted-shape feature a*b.p<r>: the product of two region masks, each blurred by r, which is 1 where both are 0.5. That is their shared border: the jaw line between neck and chin / cheek, the sideburns between ear and cheek. Linear sums of single-region blurs could not express a band there. Refit against CC5's presets (gen_shape_fit.py), soft IoU: - stubble 0.545 -> 0.631 - contour 0.475 -> 0.543 - freckles 0.682 -> 0.721 - blush 0.591 -> 0.601 Rendered against CC5 (gen_validate.py change error): stubble 1.28 -> 0.96 of 1.60, contour 0.75 -> 0.72. Eyeshadow and highlight fitted closer but rendered worse (0.61 -> 0.67, 0.93 -> 0.97), so they keep their earlier shapes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tubble refit New fitted-shape feature g<u>,<v>,<sigma>: a Gaussian blob at (u, v) / 64 of the head texture, mirrored across the face's centre line. It places patches the region masks have no feature for: the forehead centre and the cheekbones of CC5's highlight, the beard band of its stubble. All CC5 heads share this UV layout. Fit with blobs (gen_shape_fit.py GEN_FIT_BLOBS=1), soft IoU: - contour 0.54 -> 0.88 - highlight 0.28 -> 0.56 - stubble 0.63 -> 0.93 Per kind, the fit that renders closest to CC5 is kept (gen_validate.py change error): - contour 0.72 -> 0.60 - highlight 0.93 -> 0.72 - stubble 0.96 -> 0.88 - blush, eyeshadow and freckles keep their fits (blobs rendered worse there) Mean over the seven kinds: 0.75 -> 0.64. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CC5's beard_stubble is fine, dense, pale hairs. The stubble default is now colour (105, 92, 80) (was (80, 68, 58)), density 3 (was 2), size 0.7 (was 1). Change error against CC5 (gen_validate.py) 0.88 -> 0.70 of 1.60. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…over time (weight gain)
A "Timelapse" section interpolates every slider weight linearly from a start
(the sliders when the editor opened, or the current sliders) to a target: a
preset ("Heavy (female)" = Female Heavy Full-body 1 + Face Heavy 0.5, "Heavy
(male)"), the current sliders, or a recipe. Time slider, Play / Pause,
duration, back-and-forth. `--timelapse heavy-female|heavy-male|recipe.json`
opens with it playing; a --snapshot-batch job's "time" renders a point of it.
Each frame is a plain slider mix, so Save GLB / recipe save what is shown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
crates/cc5-shape(Rust + CPythoncc5_shape): apply Character Creator 5 shaping sliders outside CC5.SubdivMap+shape_glb_hddrive CC5's level-1/2 mesh from the level-0 pack.cc5_shape.fit.examples/avatar_editor.rs: live CC5-style slider editor in Bevy.--hd, and--snapshotfor offscreen renders.examples/shape_avatar.rs: headless shaping, weights JSON in, shaped GLB out.src/cc_render/cc5_materials:Cc5MaterialsPluginbuilds Bevy extended materials for CC5's shaders: RLHead/RLSkin, RLHair, RLEye, eye occlusion/tearline and teeth/tongue. It reads the shader maps and parameters the pipeline records in glTF material extras.Cargo.toml: Bevy'sexperimental_pbr_pcssfor soft key-light shadows.docs/design/avatar-editor.md: pipeline, pack format and accuracy notes.Inputs are built by RemoteMedia-SDK/remotemedia-sdk#36 (same branch name,
feat/cc5-avatar-editor):scripts/avatars/cc5_editor/build_cc5_editor_pack.ps1.Accuracy
Test plan
cargo test -p cc5-shape: 11 pass.maturin build --release; Python checks against CC5 exports.cargo build --example avatar_editor.--snapshot, for the base and--hdcharacters, with and without recipes.build_cc5_editor_pack.ps1 -HdLevel 1from a fresh CC5 session.🤖 Generated with Claude Code