# VRM to Spritesheet - https://www.youtube.com/watch?v=z_oDpQ4vzNA - https://hackmd.io/@XR/avatarlod#Webaverse-Pipeline Sprites can help with optimization, like generating imposters that improve concurrent user count with assets that look like the original custom avatar. ![image](https://hackmd.io/_uploads/r16YVtMja.png) ## Character Studio Pipeline - https://github.com/m3-org/CharacterStudio using character studio to generate the sprites, example animation / manifest file ![joy2](https://hackmd.io/_uploads/S1yM4Kzia.gif) ![image](https://hackmd.io/_uploads/HJqMEtzsp.png) ![walk](https://hackmd.io/_uploads/BybivYGj6.gif) It works with different sized models as well ![walk2](https://hackmd.io/_uploads/rJH9TKfi6.gif) --- ### r3f-sprite-animator - https://codesandbox.io/p/sandbox/r3f-sprite-animator-s12ijv?file=%2Fpublic%2Fboy_hash.json%3A1%2C1-204%2C2 ```json! {"frames": { "Celebration_000": { "frame": {"x":1,"y":1,"w":560,"h":440}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":560,"h":440}, "sourceSize": {"w":560,"h":440} }, "Celebration_001": { "frame": {"x":1,"y":443,"w":560,"h":440}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":560,"h":440}, "sourceSize": {"w":560,"h":440} }, "Celebration_002": { "frame": {"x":1,"y":885,"w":560,"h":440}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":560,"h":440}, "sourceSize": {"w":560,"h":440} }, "Celebration_003": { "frame": {"x":1,"y":1327,"w":560,"h":440}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":560,"h":440}, "sourceSize": {"w":560,"h":440} }, ``` https://twitter.com/antpb/status/1752868882291790262 > The biggest thing we need is a list of standard animations. My current implementation is > - idle > - idleBackward > - walk > - walkBackward > >For jumps you could use the walk animation clamped to a frame where the leg is forward. These are all very old problems though so I’m sure there’s some very standard way that is a one file sheet. The names matter most because the implementations could just not care what the animations do and play on the state associated like walk --- ## Notes - https://community.khronos.org/t/adding-billboard-sprites-to-gltf/106664 - https://x.com/UX3DGpuSoftware/status/1461706770309689348?s=20 - https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#morph-targets ![image](https://hackmd.io/_uploads/Bkr6LtGjT.png) ```json! { "Apple": { "frame": {"x":292,"y":304,"w":60,"h":61}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":23,"y":29,"w":60,"h":61}, "sourceSize": {"w":90,"h":90}, "pivot": {"x":0.5,"y":0.5} }, ... } ``` snippet from Eidur in Webgamedev discord > I'm implementing vanilla three and threlte components and utilities at the same time. ```javascript! export type SpritesheetFormat = { frames: [x: number, y: number, w: number, h: number][]; animations: Record<string, [frameId: number, duration: number][]>; sheetSize: [w: number, h: number]; animationLengths: number[]; }; ``` --- ## glTF extension notes rough sketch by lasershark ```json! { "extensionsUsed": ["m3_spritesheet_animations"], "images": [ { "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." } ], "extensions": { "m3_spritesheet_animations": { "spritesheets": [ { "image": 0, "name": "Sprite Animations", "dimensions": { "width": 1024, "height": 1024, "framesH": 4, "framesV": 4 }, "frameRate": 12, "animations": [ { "name": "walking", "startFrame": 0, "endFrame": 3, "loop": true }, { "name": "jumping", "startFrame": 4, "endFrame": 7, "loop": false } ] } ] } } } ```