Expand description
Per-preset user-texture binding plan + the tex2D rewriter that
consumes it.
Built by the renderer at preset load time:
scan_user_samplersextractssampler sampler_X;declarations from the preset’s HLSL.- The renderer resolves each name to a
TextureSlotvia its texture pool.sampler_rand0Xbecomes a deterministic pick; literal names become a pool lookup. - The slots are passed to
crate::translate_shader_with_planand the wrapper so the emitted WGSL points at the right binding.
Structs§
- Texture
Binding Plan - Per-preset mapping from HLSL sampler names to the comp pass’s user-texture slots.
- Texture
Slot - One slot in a
TextureBindingPlan. Carries the resolved pool texture name (orNonewhen the renderer should fall back to the 1×1 white fallback) and the texture’svec4<f32>(w, h, 1/w, 1/h)for thetexsize_<NAME>constant the wrapper emits. - User
Sampler Ref - One parsed
sampler sampler_X;declaration. The renderer consumes this to populate aTextureBindingPlan.
Constants§
- MAX_
USER_ TEXTURE_ SLOTS - Maximum simultaneously-bound user textures per preset. Sized to cover
the in-the-wild distribution: a typical preset survey shows ≤ 4
distinct
sampler sampler_X;declarations per shader; 8 leaves headroom without blowing past the comp pipeline’s bind-group budget. Presets that exceed this cap are translated with the first 8 slots used and the rest falling through to the standard fallback path (sampler_main).
Functions§
- decompose_
sampler_ 🔒name - Decompose an HLSL user-sampler name into
(logical_name, sampler_kind). The logical name is what the renderer looks up in the texture pool; the sampler kind is the WGSL sampler binding used at thetextureSamplecall site. - is_
builtin_ 🔒sampler_ name truefor sampler names the codegen wrapper already binds. Filtering these out keeps the user-texture plan focused on disk-loaded textures.- noise_
sampler_ 🔒for - For a noise sampler name embedded in one of the 4 MD2 variants,
pick the sampler binding. Plain
sampler_noise_lq(no prefix) defaults to the point+wrap variant — that’s how MD2 samples noise pixel-by-pixel when the author wants the raw value. - replace_
texture_ 🔒sampling_ with_ plan - Rewrite
tex2D(<sampler>, <uv>)to a WGSLtextureSamplecall against the(texture, sampler)pair resolved from the MD2 sampler name. Paren-balanced because the uv expression often contains nested calls (tex2D(s, uv + offset(t))). - resolve_
tex2d_ 🔒sampler - Resolve an MD2 sampler name to the
(texture_binding, sampler_binding, recognised)triple the WGSL wrapper actually exposes.recognised = truesuppresses the/*was: …*/debug comment for bindings we routed deliberately (vs. the fallback case). - scan_
user_ samplers - Extract every
sampler sampler_X;declaration from a MilkDrop comp shader HLSL and return the logical name (the part aftersampler_) for each occurrence that isn’t already a built-in. - user_
texture_ binding_ name - WGSL binding name for user-texture slot
slot. The codegen wrapper declaresvar sampler_user_<n>_texture: texture_2d<f32>for each slot0..MAX_USER_TEXTURE_SLOTS, and this is what the translator emits intextureSample(...)calls for plan-routed samplers.