svg: rasterization moves below the exporter; the water preset declares its absorption - #108
Conversation
… can reach it Rasterization shipped as a pre-export pass, which is the right shape for rewriting a SceneGraph's texture paths and is unchanged here. What was in the wrong place was the renderer underneath it. Every consumer holding a Material and a path sits *beside* the exporter rather than after it. Studio's live viewport already reached back into mogen-export for is_svg/render_svg/resolve_svg_size, and an engine that consumes the lowered SceneGraph and decodes textures itself could not reach them at all without linking the whole exporter — oxipng, fbxcel and meshopt included — for three pure functions over `(bytes, size, wrap)`. So the policy moves to a new `mogen-svg`: mogen-core plus resvg/usvg, both pure Rust, and it cross-compiles to wasm32-unknown-unknown (checked). The pass stays in mogen-export, which re-exports the four public items so `mogen_export::is_svg` and friends keep resolving and Studio needs no edit. `textures-svg` becomes `dep:mogen-svg`. There is still exactly one implementation of "what pixels does this SVG produce", which was the point of the original split; it is simply reachable now. Verified: -p mogen-svg (12), -p mogen-export (5 svg unit + 27 svg_textures), -p mogen-core, -p mogen-dsl (663), cargo check --workspace --all-targets, and cargo check -p mogen-svg --target wasm32-unknown-unknown. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`shader="water"` was a bare on/off switch. The preset was seeded with an empty param list, so an author had no way to say *how* absorbing the water is, and a consumer reading the lowered Material had nothing to read — the shader name and nothing else. Declaring `absorption` (float, default 1.5) fixes both ends through the ordinary machinery: `shader_params (absorption=2.5)` overrides it and `ShaderDecl::resolve_param` resolves it, exactly as for a user-declared shader. The built-in stays the first client of the general system rather than acquiring a special case. The default is deliberately not zero. Zero is the "behaves exactly like clear glass" case, so defaulting to it would make `shader="water"` a no-op that reports success. The test asserts the override wins, that a silent material gets the default, and — the control — that the default is not the disabled value. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The lowering-level test added in this PR only checks that ShaderDecl::resolve_param resolves the right value on the SceneGraph; nothing exercised the actual deliverable — a downstream engine reading node.extras.shader.params off the exported GLB. Mirrors the existing `declared_shader_params_merge_defaults_with_overrides` coverage for user-declared shaders, but for the built-in water preset's default and an authored override. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lbcid9DKhPVDy6eGeJi5na
|
Reviewed this PR against code quality, file structure, test coverage, and a visual check of the rendering path it touches. One real gap found and fixed; everything else checks out. Findings (ranked by severity)1. Low — missing integration test for the new The PR's new lowering test ( Fixed in // node.extras for shader_params (absorption=2.5)
{ "shader": { "name": "water", "params": { "absorption": 2.5 } } }2. Informational, no action needed — Studio's live preview doesn't consume the new param yet
Verification performed
Nice PR — the crate split is clean and the doc comments carry real signal. Generated by Claude Code |
Two changes an engine consuming the lowered
SceneGraphneeds, both of whichalso remove a reach-around Studio was already doing.
Requested by a downstream consumer (moggy, krazyjakee/moggy#457), but neither
change is engine-specific — both are about the built-in surfaces being
reachable and self-describing on their own terms.
1.
mogen-svg: the rasterizer moves below the exporterRasterization shipped as a pre-export pass (#106). That is still the right
shape for rewriting a
SceneGraph's texture paths and layering bytes over aTextureSource, and it is unchanged here. What was in the wrong place was therenderer underneath it.
Every consumer holding a
Materialand a path sits beside the exporter, notafter it.
svg.rs's own module docs already named the problem — "the consumerthis pass cannot reach" — and Studio's viewport solved it by reaching back into
mogen-exportforis_svg/render_svg/resolve_svg_size. An engine thatreads the lowered
SceneGraphand decodes textures itself cannot do even thatwithout linking the whole exporter,
oxipng/fbxcel/meshoptincluded,for three pure functions over
(bytes, size, wrap).So the policy moves into a new
mogen-svgcrate —mogen-coreplusresvg/usvg, both pure Rust — and the pass stays inmogen-export, whichre-exports the four public items.
mogen_export::is_svgand friends stillresolve, so Studio needs no edit.
textures-svgbecomesdep:mogen-svg.There is still exactly one implementation of "what pixels does this SVG
produce", which was the point of the original decision; it is simply reachable
now. Verified to cross-compile to
wasm32-unknown-unknown, as the old moduleclaimed for itself.
2. The built-in
waterpreset declaresabsorptionshader="water"was a bare on/off switch: the preset was seeded with an emptyparam list, so an author could not say how absorbing the water is, and a
consumer reading the lowered
Materialfound a shader name and nothing else.It now declares
absorption(float, default1.5), resolved through theordinary
ShaderDecl::resolve_parampath —shader_params (absorption=2.5)overrides it exactly as for a user-declared shader. The built-in stays the
first client of the general system rather than acquiring a special case, which
is the property #107 is heading toward anyway.
The default is deliberately not zero: zero is the "behaves exactly like clear
glass" case, so defaulting to it would make
shader="water"a no-op thatreports success. The test asserts the override wins, that a silent material
gets the default, and — the control — that the default is not the disabled
value.
docs/dsl.mddocuments the parameter in both places water is described.Verification
cargo test --locked -p mogen-svg -p mogen-export -p mogen-dsl -p mogen-core— 18 suites, all green (664 inmogen-dsl, 27 insvg_textures)cargo check --workspace --all-targets— cleancargo check -p mogen-svg --target wasm32-unknown-unknown— cleanNot run: the Studio GL paths, which need a display seat this machine may not
have. Studio is untouched by construction — it compiles against the same
re-exported names — but that is an argument, not an observed run.
🤖 Generated with Claude Code