VFX Material Parameters
VFX particle systems in League of Legends can attach meshes to bones and apply material effects through VfxEmitterDefinitionData. These parameters are extracted alongside standard StaticMaterialDef data.
Overview
When a VFX emitter renders an attached mesh (via VfxPrimitiveAttachedMesh), it can specify:
- Texture: The diffuse texture for the mesh
- UV Scroll: Animated texture offset for scrolling effects (e.g., flowing noodles, energy streams)
- UV Scale: Texture tiling/repeat for the mesh
These parameters override StaticMaterial shader parameters when present, allowing particle effects to animate mesh textures independently.
Extracted Parameters
birthUvScrollRate
Maps to uvScrollSpeed in GLTF material extras.
Structure in bin data:
"birthUvScrollRate": {
"constantValue": [0.0, 1.0],
"__type": "ValueVector2"
}Export format:
uvScrollSpeed: [number, number]- UV offset delta per second [x, y]
Frontend behavior:
- Applied each frame:
offset += speed * deltaTime * animationTimeScale - Respects animation pause state
- Requires
RepeatWrappingtexture mode
uvScale
Maps to uvTile in GLTF material extras.
Structure in bin data:
"uvScale": {
"constantValue": [1.0, 0.5],
"__type": "ValueVector2"
}Export format:
uvTile: [number, number]- Texture repeat/scale [x, y]
Frontend behavior:
- Sets
texture.repeaton load - Values < 1.0 shrink the texture (e.g., 0.5 shows half)
- Values > 1.0 tile the texture (e.g., 2.0 repeats twice)
Priority and Applicability
IMPORTANT: VFX parameters are ONLY applied to meshes that are initially hidden (in initialSubmeshToHide).
Meshes visible by default (Hair, Body, etc.) do NOT get VFX UV scroll applied to their base material, even if VFX emitters reference them. This is because:
- Visible meshes have their own base material with shader-defined parameters
- VFX parameters for visible meshes are for temporary animation effects only
- Applying VFX params to visible meshes would cause incorrect base rendering
When both VFX and StaticMaterial define scroll/tile parameters:
- VFX parameters (from
VfxEmitterDefinitionData) - highest priority, ONLY for initially hidden meshes - StaticMaterial parameters (from shader) - used for all visible meshes, fallback for hidden meshes
This ensures VFX-only meshes (like NoodleVfx) get their animation from particle data, while regular meshes use their shader parameters.
Example: Noodle VFX
Chibi Akali Joke Animation (Skin1)
The NoodleVfx submesh shows animated ramen noodles during the joke emote:
- Mesh:
NoodleVfx(attached to character skeleton) - Initially Hidden: YES (in
initialSubmeshToHide) ✓ VFX params applied - VFX System:
PetChibiAkali_Skin1_Emote_JokeSubMesh - Texture:
PetChibiAkali_Base_Noodlevfx_TX_CM.tex - UV Scroll:
[0.0, 1.0]- scrolls vertically at 1 UV/sec - UV Scale:
[1.0, 0.5]- shrinks texture to 50% height
This creates the illusion of noodles being slurped into the mouth as the texture scrolls upward.
Counter-example: Hair, Body, Bag (Chibi Akali Dance Animation)
These meshes are referenced by a Dance VFX emitter with UV scroll [0.2, 0.1]:
- Meshes:
Hair,Body,Bag(visible parts of character) - Initially Hidden: NO ✗ VFX params NOT applied to base material
- VFX System:
PetChibiAkali_Skin1_Emote_Dance_SubmeshLoop - UV Scroll:
[0.2, 0.1]- applies ONLY during Dance animation VFX
The VFX scroll is a temporary visual effect during the dance, not a permanent property of these meshes.
Implementation Notes
Extractor (Skin.cs)
ExtractMeshAndTextureFromEmitter()- parses VFX emitter properties_vfxMeshMaterialParams- maps mesh name → VFX paramsGetVfxMaterialParams()- accessor for export
Export (SkinExtensions.cs)
- Checks
isHiddenSubmesh(frominitialSubmeshToHide) before applying VFX params - Only calls
skin.GetVfxMaterialParams()for initially hidden meshes - Uses null-coalescing:
vfxParams?.UvScrollSpeed ?? staticMaterial?.GetUvScrollSpeed() - Prevents VFX params from overriding visible mesh base materials
Frontend (engine/index.ts)
handleUvScroll()- registers materials for animationhandleUvTile()- applies texture repeat- Animation loop updates offsets synced to skeletal animation time
Hash Values
Property hashes (FNV1a lowercase):
birthUvScrollRate:4132956430(0xf66b780e)uvScale:4071848866(0xf2c5e8a2)constantValue:3916664084(0xe984e394)