[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"guide-nav":3,"doc-\u002Fdocs\u002Fprimitives\u002Fsim-fluids":145},[4,10,16,20,24,28,32,36,40,44,48,52,56,60,64,69,73,78,82,86,90,94,98,102,106,110,114,117,120,124,127,131,134,138,141],{"path":5,"title":6,"description":7,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide","Getting started","Shaders is a library of GPU effect components for Vue, React, Svelte, Solid, JavaScript and Framer, with a design editor for building with them.","code",null,{"path":11,"title":12,"description":13,"category":8,"exclude":14,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fquickstart","Quickstart","Install Shaders, render your first effect, and drive a prop from state.",[15],"js",{"path":17,"title":18,"description":19,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fcomposing-effects","Composing effects","Stack components as layers and nest them to control which layers an effect touches.",{"path":21,"title":22,"description":23,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fblending-masking","Blending and masking","Control how a layer mixes with the layers below it, and reveal one layer through another.",{"path":25,"title":26,"description":27,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fprops-reactivity","Props and reactivity","Bind props to your framework's state so effects update when it changes, and animate props with an animation library.",{"path":29,"title":30,"description":31,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fdynamic-props","Dynamic props","Drive any numeric or position prop from time, the cursor, or another layer, without writing animation code.",{"path":33,"title":34,"description":35,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Flayout-positioning","Layout and positioning","Size and place a shader in your page with CSS, as a background, a fill, or an inline block.",{"path":37,"title":38,"description":39,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Ftransforms","Transforms","Position, size, and rotate any layer inside the canvas with a bounding box, in % or px units.",{"path":41,"title":42,"description":43,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fshape-effects","Shape effects","Pick the 2D, 3D or custom SVG shape that Glass, Neon, Emboss and other shape effects draw inside.",{"path":45,"title":46,"description":47,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fcolor-space","Color space","Match colors to your design tool with the output color space, and keep bright layers from clipping with tone mapping.",{"path":49,"title":50,"description":51,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fhooks-events","Hooks and events","Run code when an effect is ready to show, and show a fallback when the GPU can't run it.",{"path":53,"title":54,"description":55,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fperformance","Performance","Learn what makes an effect expensive on the GPU and how to keep it inside the frame budget.",{"path":57,"title":58,"description":59,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fcustom-shaders","Custom components","Write your own component in TypeScript, use it like any component in the library, and write WGSL by hand when you need to.",{"path":61,"title":62,"description":63,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Ftelemetry","Telemetry","The `\u003CShader>` component occasionally sends an anonymous performance report to help us improve the engine over time.",{"path":65,"title":66,"description":67,"category":68,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fmcp","Shaders MCP","Connect your AI coding agent to Shaders so it can find, install and edit effects in your codebase.","workflows",{"path":70,"title":71,"description":72,"category":68,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fcli","Shaders CLI","Install shaders and presets into your codebase as component files, and keep them in sync with the design editor.",{"path":74,"title":75,"description":76,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fquick-tour-of-the-design-editor","Quick tour of the design editor","A short walkthrough of the full Shaders workflow, from designing on the infinite canvas to exporting code.","editor",{"path":79,"title":80,"description":81,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fintro-to-the-interface","Intro to the interface","A tour of the design editor interface: the canvas, layers, the Properties panel, and the ways to share and export.",{"path":83,"title":84,"description":85,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fcomposing-your-first-shader-effect","Composing your first shader effect","Building a first shader effect in the design editor by stacking and nesting components as layers.",{"path":87,"title":88,"description":89,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fmasking-and-blending","Masking and blending","How blend modes and masks combine components in the design editor.",{"path":91,"title":92,"description":93,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fdynamic-prop-mapping","Dynamic prop mapping","Turning static props into dynamic ones in the design editor: mapping one layer's output into another's prop, following the cursor, or animating automatically.",{"path":95,"title":96,"description":97,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fcustom-media-and-transformations","Custom media and transformations","Uploading images, videos, and SVG files to the media gallery, adding them to a composition, and placing them with transformations.",{"path":99,"title":100,"description":101,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Finstalling-a-shader-via-mcp","Installing a shader via MCP","Installing a shader from the design editor into a hero section with the Shaders MCP.",{"path":103,"title":104,"description":105,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fexploring-shape-effects","Exploring shape effects","Applying shape effects such as liquid glass, liquid metal, and glowing edges to built-in shapes and your own SVG.",{"path":107,"title":108,"description":109,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fglass-component-spotlight","Component spotlight: Glass","A short look at the Glass component and the liquid-glass look it creates.",{"path":111,"title":112,"description":113,"category":77,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fdigital-looks-component-spotlight","Component spotlight: Digital looks","A look at the digital stylization components for glitchy, futuristic, or technical effects.",{"path":115,"title":12,"description":116,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fjs\u002Fquickstart","Install Shaders without a framework, render your first effect on a canvas, and update props at runtime.",{"path":118,"title":12,"description":119,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Freact\u002Fquickstart","Install Shaders in a React app, render your first effect, and drive a prop from state.",{"path":121,"title":122,"description":123,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Freact\u002Fssr","Next.js and SSR","Render Shaders in Next.js and other React SSR apps by keeping each shader on the client.",{"path":125,"title":12,"description":126,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fsolid\u002Fquickstart","Install Shaders in a Solid app, render your first effect, and drive a prop from a signal.",{"path":128,"title":129,"description":130,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fsolid\u002Fssr","SolidStart and SSR","Render Shaders in SolidStart and other Solid SSR apps by keeping each shader on the client.",{"path":132,"title":12,"description":133,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fsvelte\u002Fquickstart","Install Shaders in a Svelte app, render your first effect, and drive a prop from state.",{"path":135,"title":136,"description":137,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fsvelte\u002Fssr","SvelteKit and SSR","Render Shaders in SvelteKit and other Svelte SSR apps, where each shader already waits for the browser.",{"path":139,"title":12,"description":140,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fvue\u002Fquickstart","Install Shaders in a Vue app, render your first effect, and drive a prop from a ref.",{"path":142,"title":143,"description":144,"category":8,"exclude":9,"forceFramework":9},"\u002Fdocs\u002Fguide\u002Fvue\u002Fssr","Nuxt and SSR","Render Shaders in Nuxt and other Vue SSR apps by keeping each shader on the client.",{"id":146,"title":147,"body":148,"categoryId":2146,"categorySlug":2147,"categoryTitle":9,"curated":428,"description":2148,"editUrl":2149,"extension":2150,"group":2151,"groupTitle":2152,"kind":9,"meta":2153,"navigation":428,"path":2154,"seo":2155,"sourceUrl":2156,"stem":2157,"wordCount":432,"__hash__":2158},"primitives\u002Fdocs\u002Fprimitives\u002F38.sim-fluids\u002Findex.md","Fluids",{"type":149,"value":150,"toc":2140},"minimark",[151,155,172,225,232,261,266,362,366,1931,1935,2078,2082,2136],[152,153,147],"h1",{"id":154},"fluids",[156,157,158,159,163,164,171],"p",{},"Smoke, ink and fog that flow. A fluid is a square grid of velocity plus a ",[160,161,162],"strong",{},"dye"," (a density\nand an age, or a color) that the engine advances with a full fluid solve every frame:\nswirl, pressure, advection. ",[165,166,168],"a",{"href":167},"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Ffluidsim",[8,169,170],{},"fluidSim"," owns the state buffers, the output texture, the solve\nchain, the pointer tracker, the clock and the idle gate that sleeps a settled field. You bring\nthe parts that make the look and declare them by role.",[156,173,174,177,178,184,185,191,192,195,196,202,203,209,210,213,214,220,221,224],{},[160,175,176],{},"Emitters"," put dye and momentum in: ",[165,179,181],{"href":180},"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Fsplat",[8,182,183],{},"splat"," at a fixed source (a cone from a point),\n",[165,186,188],{"href":187},"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Fcursorribbon",[8,189,190],{},"cursorRibbon"," along the pointer's stroke as a continuous ribbon of stamps. ",[160,193,194],{},"Solve stages","\nwrap every solve: ",[165,197,199],{"href":198},"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Fambientforce",[8,200,201],{},"ambientForce"," before it (a turbulence field), ",[165,204,206],{"href":205},"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Frestoretoward",[8,207,208],{},"restoreToward"," after it (a\ncolor the solve would otherwise blur away). ",[160,211,212],{},"Init"," decides how the field starts:\n",[165,215,217],{"href":216},"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Fseededfieldinit",[8,218,219],{},"seededFieldInit"," seeds it and runs silent warm-up solves so the first visible frame already\nflows. The ",[8,222,223],{},"values"," function turns props, the clock and the pointer into the numbers every pass\nreads; positions and radii in it are in grid cells.",[156,226,227,228,231],{},"The fragment samples the output texture under the key you named and colors it however you\nlike. When an effect only needs a wave field or a displacement, ",[8,229,230],{},"simulate.grid"," says it with no\nGPU code.",[233,234,239],"pre",{"className":235,"code":236,"language":237,"meta":238,"style":238},"language-ts shiki shiki-themes github-dark","import {sim} from 'shaders\u002Fstd'\n","ts","",[8,240,241],{"__ignoreMap":238},[242,243,246,250,254,257],"span",{"class":244,"line":245},"line",1,[242,247,249],{"class":248},"snl16","import",[242,251,253],{"class":252},"s95oV"," {sim} ",[242,255,256],{"class":248},"from",[242,258,260],{"class":259},"sU2Wk"," 'shaders\u002Fstd'\n",[262,263,265],"h2",{"id":264},"reach-for-it-when","Reach for it when",[267,268,269,282],"table",{},[270,271,272],"thead",{},[273,274,275,279],"tr",{},[276,277,278],"th",{},"When you need",[276,280,281],{},"Use",[283,284,285,302,317,328,339,350],"tbody",{},[273,286,287,291],{},[288,289,290],"td",{},"smoke rising from a point, stirred by the cursor",[288,292,293,297,298],{},[165,294,295],{"href":167},[8,296,170],{}," with ",[165,299,300],{"href":180},[8,301,183],{},[273,303,304,307],{},[288,305,306],{},"smoke or ink painted along the pointer's stroke",[288,308,309,297,313],{},[165,310,311],{"href":167},[8,312,170],{},[165,314,315],{"href":187},[8,316,190],{},[273,318,319,322],{},[288,320,321],{},"fog that is already everywhere when the layer appears",[288,323,324],{},[165,325,326],{"href":216},[8,327,219],{},[273,329,330,333],{},[288,331,332],{},"a wind or turbulence over the whole field",[288,334,335],{},[165,336,337],{"href":198},[8,338,201],{},[273,340,341,344],{},[288,342,343],{},"a color that must not wash out over time",[288,345,346],{},[165,347,348],{"href":205},[8,349,208],{},[273,351,352,355],{},[288,353,354],{},"the simulation should sleep once the last stroke has faded",[288,356,357,358],{},"the fadeSeconds option of ",[165,359,360],{"href":187},[8,361,190],{},[262,363,365],{"id":364},"example","Example",[233,367,369],{"className":235,"code":368,"language":237,"meta":238,"style":238},"import {defineShader, p, sim, transformColor, transformPosition} from 'shaders\u002Fstd'\nimport {tgpu, d} from '@coreroot\u002Fgpu\u002Fkit'\nimport {buildStableFluidsKernels, buildEmitterSplatKernel, buildFluidOutputKernel, mixExpr, vec4, ZERO} from '@coreroot\u002Fgpu\u002Fporters'\nimport type {GpuFragmentParams, KitTexture, Expr} from '@coreroot\u002Fgpu\u002Fporters'\n\nconst {fluidSim, splat} = sim.fluids\n\nconst N = 256\nconst COUNT = N * N\n\n\u002F\u002F The values every pass reads each frame. dt, curlStrength, velFade, dyeFade and colorDecay are the\n\u002F\u002F solver's; the rest drive the emitter and the cursor shove.\nconst FluidParams = d.struct({\n  dt: d.f32, emitX: d.f32, emitY: d.f32, emitVelX: d.f32, emitVelY: d.f32,\n  perpDirX: d.f32, perpDirY: d.f32, spreadFactor: d.f32, emitRad: d.f32, emitIntensity: d.f32,\n  dyeFade: d.f32, velFade: d.f32, curlStrength: d.f32, gravity: d.f32, cursorX: d.f32, cursorY: d.f32,\n  cursorVelX: d.f32, cursorVelY: d.f32, mouseActive: d.f32, mouseRadSq: d.f32, colorDecay: d.f32,\n})\n\u002F\u002F The fluid's buffers, by the names the solver expects.\nconst fluidLayout = tgpu.bindGroupLayout({\n  velA: {storage: d.arrayOf(d.vec4f, COUNT), access: 'mutable'},\n  velB: {storage: d.arrayOf(d.vec4f, COUNT), access: 'mutable'},\n  dyeA: {storage: d.arrayOf(d.vec4f, COUNT), access: 'mutable'},\n  dyeB: {storage: d.arrayOf(d.vec4f, COUNT), access: 'mutable'},\n  pressure: {storage: d.arrayOf(d.f32, COUNT), access: 'mutable'},\n  divergence: {storage: d.arrayOf(d.f32, COUNT), access: 'mutable'},\n  params: {uniform: FluidParams},\n})\nconst outputLayout = tgpu.bindGroupLayout({\n  dyeA: {storage: d.arrayOf(d.vec4f, COUNT), access: 'readonly'},\n  outTex: {storageTexture: d.textureStorage2d('rgba16float', 'write-only')},\n})\n\n\u002F\u002F The one pass that is this shader's own: a cone emitter at a fixed source, plus the cursor shove.\nconst splatKernel = buildEmitterSplatKernel(fluidLayout, {n: N, namePrefix: 'smoke', cone: true, cursorPush: true, densityGain: 8, velocityBlendGain: 3})\n\u002F\u002F Everything else is the shared solve over a density-and-age dye.\nconst solverKernels = buildStableFluidsKernels(fluidLayout, {n: N, namePrefix: 'smoke', boundary: 'clamped', dye: 'densityAge', dyeDissipation: true, ageAdvance: true})\nconst outputKernel = buildFluidOutputKernel(outputLayout, {n: N, namePrefix: 'smoke', dye: 'densityAge'})\n\n\u002F\u002F Smoke: fresh smoke in colorA ages toward colorB as it rises and dissipates.\nexport const Smoke = defineShader({\n  name: 'Smoke',\n  usesPointer: true,\n  props: {\n    colorA: {default: '#fc83f9', transform: transformColor},\n    colorB: {default: '#c21c79', transform: transformColor},\n    emitFrom: {default: {x: 0.5, y: 1}, transform: transformPosition},\n    speed: {default: 20},\n    emitRadius: {default: 0.08},\n    dissipation: {default: 0.2},\n    detail: {default: 25},\n    mouseInfluence: {default: 0.1},\n  },\n  ...fluidSim(() => ({\n    resolution: N,\n    layout: fluidLayout, outputLayout, paramsSchema: FluidParams,\n    solver: {kernels: solverKernels, jacobiIters: 10},\n    output: {kernel: outputKernel, key: 'smokeTexture'},\n    pointer: {minDrag: 0.0005},\n    inject: [splat({kernel: splatKernel})],\n    values: (f) => {\n      const emit = f.getCpuValue('emitFrom') as {x: number; y: number} | undefined\n      const velMag = f.num('speed', 20) * N * 0.15\n      const ptr = f.ptr!\n      const mouseInf = f.num('mouseInfluence', 0.1)\n      const active = ptr.moving && mouseInf > 0\n      const mouseRadGrid = 0.1 * N\n      return {\n        dt: f.dt,\n        emitX: (emit?.x ?? 0.5) * N,\n        emitY: (1 - (emit?.y ?? 0)) * N,\n        emitVelX: 0, emitVelY: -velMag,\n        perpDirX: 1, perpDirY: 0,\n        spreadFactor: Math.tan(Math.PI \u002F 6),\n        emitRad: f.num('emitRadius', 0.08) * N,\n        emitIntensity: 1,\n        dyeFade: f.num('dissipation', 0.2),\n        velFade: 0.2,\n        curlStrength: f.num('detail', 25),\n        gravity: 0.5,\n        colorDecay: 0.4,\n        cursorX: active ? ptr.x * N : 0,\n        cursorY: active ? ptr.y * N : 0,\n        cursorVelX: active ? ptr.dx * N * 15 * mouseInf : 0,\n        cursorVelY: active ? ptr.dy * N * 15 * mouseInf : 0,\n        mouseActive: active ? 1 : 0,\n        mouseRadSq: mouseRadGrid * mouseRadGrid,\n      }\n    },\n  })),\n  gpu: {\n    fragment: ({ctx, computeOutputs, uniforms}: GpuFragmentParams): Expr => {\n      const field = computeOutputs?.smokeTexture as KitTexture | undefined\n      if (!field) return ZERO \u002F\u002F no GPU: transparent\n      const s = field.sample(ctx.uv, 'linearClamp') \u002F\u002F x = density, y = age\n      const color = mixExpr(uniforms.colorA, uniforms.colorB, s.member('y'))\n      return vec4(color.member('rgb'), color.member('a').mul(s.member('x')))\n    },\n  },\n})\n",[8,370,371,382,395,408,423,430,456,461,475,493,498,505,511,531,537,543,549,555,561,567,585,609,627,645,663,682,700,706,711,727,745,768,773,778,784,834,840,885,913,918,924,943,955,965,971,983,994,1012,1023,1034,1045,1056,1067,1073,1090,1100,1106,1117,1128,1139,1150,1171,1227,1263,1279,1305,1330,1347,1355,1361,1381,1409,1427,1442,1466,1491,1501,1520,1530,1549,1559,1570,1593,1614,1644,1673,1690,1701,1707,1713,1719,1725,1768,1791,1815,1842,1869,1916,1921,1926],{"__ignoreMap":238},[242,372,373,375,378,380],{"class":244,"line":245},[242,374,249],{"class":248},[242,376,377],{"class":252}," {defineShader, p, sim, transformColor, transformPosition} ",[242,379,256],{"class":248},[242,381,260],{"class":259},[242,383,385,387,390,392],{"class":244,"line":384},2,[242,386,249],{"class":248},[242,388,389],{"class":252}," {tgpu, d} ",[242,391,256],{"class":248},[242,393,394],{"class":259}," '@coreroot\u002Fgpu\u002Fkit'\n",[242,396,398,400,403,405],{"class":244,"line":397},3,[242,399,249],{"class":248},[242,401,402],{"class":252}," {buildStableFluidsKernels, buildEmitterSplatKernel, buildFluidOutputKernel, mixExpr, vec4, ZERO} ",[242,404,256],{"class":248},[242,406,407],{"class":259}," '@coreroot\u002Fgpu\u002Fporters'\n",[242,409,411,413,416,419,421],{"class":244,"line":410},4,[242,412,249],{"class":248},[242,414,415],{"class":248}," type",[242,417,418],{"class":252}," {GpuFragmentParams, KitTexture, Expr} ",[242,420,256],{"class":248},[242,422,407],{"class":259},[242,424,426],{"class":244,"line":425},5,[242,427,429],{"emptyLinePlaceholder":428},true,"\n",[242,431,433,436,439,442,445,447,450,453],{"class":244,"line":432},6,[242,434,435],{"class":248},"const",[242,437,438],{"class":252}," {",[242,440,170],{"class":441},"sDLfK",[242,443,444],{"class":252},", ",[242,446,183],{"class":441},[242,448,449],{"class":252},"} ",[242,451,452],{"class":248},"=",[242,454,455],{"class":252}," sim.fluids\n",[242,457,459],{"class":244,"line":458},7,[242,460,429],{"emptyLinePlaceholder":428},[242,462,464,466,469,472],{"class":244,"line":463},8,[242,465,435],{"class":248},[242,467,468],{"class":441}," N",[242,470,471],{"class":248}," =",[242,473,474],{"class":441}," 256\n",[242,476,478,480,483,485,487,490],{"class":244,"line":477},9,[242,479,435],{"class":248},[242,481,482],{"class":441}," COUNT",[242,484,471],{"class":248},[242,486,468],{"class":441},[242,488,489],{"class":248}," *",[242,491,492],{"class":441}," N\n",[242,494,496],{"class":244,"line":495},10,[242,497,429],{"emptyLinePlaceholder":428},[242,499,501],{"class":244,"line":500},11,[242,502,504],{"class":503},"sAwPA","\u002F\u002F The values every pass reads each frame. dt, curlStrength, velFade, dyeFade and colorDecay are the\n",[242,506,508],{"class":244,"line":507},12,[242,509,510],{"class":503},"\u002F\u002F solver's; the rest drive the emitter and the cursor shove.\n",[242,512,514,516,519,521,524,528],{"class":244,"line":513},13,[242,515,435],{"class":248},[242,517,518],{"class":441}," FluidParams",[242,520,471],{"class":248},[242,522,523],{"class":252}," d.",[242,525,527],{"class":526},"svObZ","struct",[242,529,530],{"class":252},"({\n",[242,532,534],{"class":244,"line":533},14,[242,535,536],{"class":252},"  dt: d.f32, emitX: d.f32, emitY: d.f32, emitVelX: d.f32, emitVelY: d.f32,\n",[242,538,540],{"class":244,"line":539},15,[242,541,542],{"class":252},"  perpDirX: d.f32, perpDirY: d.f32, spreadFactor: d.f32, emitRad: d.f32, emitIntensity: d.f32,\n",[242,544,546],{"class":244,"line":545},16,[242,547,548],{"class":252},"  dyeFade: d.f32, velFade: d.f32, curlStrength: d.f32, gravity: d.f32, cursorX: d.f32, cursorY: d.f32,\n",[242,550,552],{"class":244,"line":551},17,[242,553,554],{"class":252},"  cursorVelX: d.f32, cursorVelY: d.f32, mouseActive: d.f32, mouseRadSq: d.f32, colorDecay: d.f32,\n",[242,556,558],{"class":244,"line":557},18,[242,559,560],{"class":252},"})\n",[242,562,564],{"class":244,"line":563},19,[242,565,566],{"class":503},"\u002F\u002F The fluid's buffers, by the names the solver expects.\n",[242,568,570,572,575,577,580,583],{"class":244,"line":569},20,[242,571,435],{"class":248},[242,573,574],{"class":441}," fluidLayout",[242,576,471],{"class":248},[242,578,579],{"class":252}," tgpu.",[242,581,582],{"class":526},"bindGroupLayout",[242,584,530],{"class":252},[242,586,588,591,594,597,600,603,606],{"class":244,"line":587},21,[242,589,590],{"class":252},"  velA: {storage: d.",[242,592,593],{"class":526},"arrayOf",[242,595,596],{"class":252},"(d.vec4f, ",[242,598,599],{"class":441},"COUNT",[242,601,602],{"class":252},"), access: ",[242,604,605],{"class":259},"'mutable'",[242,607,608],{"class":252},"},\n",[242,610,612,615,617,619,621,623,625],{"class":244,"line":611},22,[242,613,614],{"class":252},"  velB: {storage: d.",[242,616,593],{"class":526},[242,618,596],{"class":252},[242,620,599],{"class":441},[242,622,602],{"class":252},[242,624,605],{"class":259},[242,626,608],{"class":252},[242,628,630,633,635,637,639,641,643],{"class":244,"line":629},23,[242,631,632],{"class":252},"  dyeA: {storage: d.",[242,634,593],{"class":526},[242,636,596],{"class":252},[242,638,599],{"class":441},[242,640,602],{"class":252},[242,642,605],{"class":259},[242,644,608],{"class":252},[242,646,648,651,653,655,657,659,661],{"class":244,"line":647},24,[242,649,650],{"class":252},"  dyeB: {storage: d.",[242,652,593],{"class":526},[242,654,596],{"class":252},[242,656,599],{"class":441},[242,658,602],{"class":252},[242,660,605],{"class":259},[242,662,608],{"class":252},[242,664,666,669,671,674,676,678,680],{"class":244,"line":665},25,[242,667,668],{"class":252},"  pressure: {storage: d.",[242,670,593],{"class":526},[242,672,673],{"class":252},"(d.f32, ",[242,675,599],{"class":441},[242,677,602],{"class":252},[242,679,605],{"class":259},[242,681,608],{"class":252},[242,683,685,688,690,692,694,696,698],{"class":244,"line":684},26,[242,686,687],{"class":252},"  divergence: {storage: d.",[242,689,593],{"class":526},[242,691,673],{"class":252},[242,693,599],{"class":441},[242,695,602],{"class":252},[242,697,605],{"class":259},[242,699,608],{"class":252},[242,701,703],{"class":244,"line":702},27,[242,704,705],{"class":252},"  params: {uniform: FluidParams},\n",[242,707,709],{"class":244,"line":708},28,[242,710,560],{"class":252},[242,712,714,716,719,721,723,725],{"class":244,"line":713},29,[242,715,435],{"class":248},[242,717,718],{"class":441}," outputLayout",[242,720,471],{"class":248},[242,722,579],{"class":252},[242,724,582],{"class":526},[242,726,530],{"class":252},[242,728,730,732,734,736,738,740,743],{"class":244,"line":729},30,[242,731,632],{"class":252},[242,733,593],{"class":526},[242,735,596],{"class":252},[242,737,599],{"class":441},[242,739,602],{"class":252},[242,741,742],{"class":259},"'readonly'",[242,744,608],{"class":252},[242,746,748,751,754,757,760,762,765],{"class":244,"line":747},31,[242,749,750],{"class":252},"  outTex: {storageTexture: d.",[242,752,753],{"class":526},"textureStorage2d",[242,755,756],{"class":252},"(",[242,758,759],{"class":259},"'rgba16float'",[242,761,444],{"class":252},[242,763,764],{"class":259},"'write-only'",[242,766,767],{"class":252},")},\n",[242,769,771],{"class":244,"line":770},32,[242,772,560],{"class":252},[242,774,776],{"class":244,"line":775},33,[242,777,429],{"emptyLinePlaceholder":428},[242,779,781],{"class":244,"line":780},34,[242,782,783],{"class":503},"\u002F\u002F The one pass that is this shader's own: a cone emitter at a fixed source, plus the cursor shove.\n",[242,785,787,789,792,794,797,800,803,806,809,812,815,818,820,823,826,829,832],{"class":244,"line":786},35,[242,788,435],{"class":248},[242,790,791],{"class":441}," splatKernel",[242,793,471],{"class":248},[242,795,796],{"class":526}," buildEmitterSplatKernel",[242,798,799],{"class":252},"(fluidLayout, {n: ",[242,801,802],{"class":441},"N",[242,804,805],{"class":252},", namePrefix: ",[242,807,808],{"class":259},"'smoke'",[242,810,811],{"class":252},", cone: ",[242,813,814],{"class":441},"true",[242,816,817],{"class":252},", cursorPush: ",[242,819,814],{"class":441},[242,821,822],{"class":252},", densityGain: ",[242,824,825],{"class":441},"8",[242,827,828],{"class":252},", velocityBlendGain: ",[242,830,831],{"class":441},"3",[242,833,560],{"class":252},[242,835,837],{"class":244,"line":836},36,[242,838,839],{"class":503},"\u002F\u002F Everything else is the shared solve over a density-and-age dye.\n",[242,841,843,845,848,850,853,855,857,859,861,864,867,870,873,876,878,881,883],{"class":244,"line":842},37,[242,844,435],{"class":248},[242,846,847],{"class":441}," solverKernels",[242,849,471],{"class":248},[242,851,852],{"class":526}," buildStableFluidsKernels",[242,854,799],{"class":252},[242,856,802],{"class":441},[242,858,805],{"class":252},[242,860,808],{"class":259},[242,862,863],{"class":252},", boundary: ",[242,865,866],{"class":259},"'clamped'",[242,868,869],{"class":252},", dye: ",[242,871,872],{"class":259},"'densityAge'",[242,874,875],{"class":252},", dyeDissipation: ",[242,877,814],{"class":441},[242,879,880],{"class":252},", ageAdvance: ",[242,882,814],{"class":441},[242,884,560],{"class":252},[242,886,888,890,893,895,898,901,903,905,907,909,911],{"class":244,"line":887},38,[242,889,435],{"class":248},[242,891,892],{"class":441}," outputKernel",[242,894,471],{"class":248},[242,896,897],{"class":526}," buildFluidOutputKernel",[242,899,900],{"class":252},"(outputLayout, {n: ",[242,902,802],{"class":441},[242,904,805],{"class":252},[242,906,808],{"class":259},[242,908,869],{"class":252},[242,910,872],{"class":259},[242,912,560],{"class":252},[242,914,916],{"class":244,"line":915},39,[242,917,429],{"emptyLinePlaceholder":428},[242,919,921],{"class":244,"line":920},40,[242,922,923],{"class":503},"\u002F\u002F Smoke: fresh smoke in colorA ages toward colorB as it rises and dissipates.\n",[242,925,927,930,933,936,938,941],{"class":244,"line":926},41,[242,928,929],{"class":248},"export",[242,931,932],{"class":248}," const",[242,934,935],{"class":441}," Smoke",[242,937,471],{"class":248},[242,939,940],{"class":526}," defineShader",[242,942,530],{"class":252},[242,944,946,949,952],{"class":244,"line":945},42,[242,947,948],{"class":252},"  name: ",[242,950,951],{"class":259},"'Smoke'",[242,953,954],{"class":252},",\n",[242,956,958,961,963],{"class":244,"line":957},43,[242,959,960],{"class":252},"  usesPointer: ",[242,962,814],{"class":441},[242,964,954],{"class":252},[242,966,968],{"class":244,"line":967},44,[242,969,970],{"class":252},"  props: {\n",[242,972,974,977,980],{"class":244,"line":973},45,[242,975,976],{"class":252},"    colorA: {default: ",[242,978,979],{"class":259},"'#fc83f9'",[242,981,982],{"class":252},", transform: transformColor},\n",[242,984,986,989,992],{"class":244,"line":985},46,[242,987,988],{"class":252},"    colorB: {default: ",[242,990,991],{"class":259},"'#c21c79'",[242,993,982],{"class":252},[242,995,997,1000,1003,1006,1009],{"class":244,"line":996},47,[242,998,999],{"class":252},"    emitFrom: {default: {x: ",[242,1001,1002],{"class":441},"0.5",[242,1004,1005],{"class":252},", y: ",[242,1007,1008],{"class":441},"1",[242,1010,1011],{"class":252},"}, transform: transformPosition},\n",[242,1013,1015,1018,1021],{"class":244,"line":1014},48,[242,1016,1017],{"class":252},"    speed: {default: ",[242,1019,1020],{"class":441},"20",[242,1022,608],{"class":252},[242,1024,1026,1029,1032],{"class":244,"line":1025},49,[242,1027,1028],{"class":252},"    emitRadius: {default: ",[242,1030,1031],{"class":441},"0.08",[242,1033,608],{"class":252},[242,1035,1037,1040,1043],{"class":244,"line":1036},50,[242,1038,1039],{"class":252},"    dissipation: {default: ",[242,1041,1042],{"class":441},"0.2",[242,1044,608],{"class":252},[242,1046,1048,1051,1054],{"class":244,"line":1047},51,[242,1049,1050],{"class":252},"    detail: {default: ",[242,1052,1053],{"class":441},"25",[242,1055,608],{"class":252},[242,1057,1059,1062,1065],{"class":244,"line":1058},52,[242,1060,1061],{"class":252},"    mouseInfluence: {default: ",[242,1063,1064],{"class":441},"0.1",[242,1066,608],{"class":252},[242,1068,1070],{"class":244,"line":1069},53,[242,1071,1072],{"class":252},"  },\n",[242,1074,1076,1079,1081,1084,1087],{"class":244,"line":1075},54,[242,1077,1078],{"class":248},"  ...",[242,1080,170],{"class":526},[242,1082,1083],{"class":252},"(() ",[242,1085,1086],{"class":248},"=>",[242,1088,1089],{"class":252}," ({\n",[242,1091,1093,1096,1098],{"class":244,"line":1092},55,[242,1094,1095],{"class":252},"    resolution: ",[242,1097,802],{"class":441},[242,1099,954],{"class":252},[242,1101,1103],{"class":244,"line":1102},56,[242,1104,1105],{"class":252},"    layout: fluidLayout, outputLayout, paramsSchema: FluidParams,\n",[242,1107,1109,1112,1115],{"class":244,"line":1108},57,[242,1110,1111],{"class":252},"    solver: {kernels: solverKernels, jacobiIters: ",[242,1113,1114],{"class":441},"10",[242,1116,608],{"class":252},[242,1118,1120,1123,1126],{"class":244,"line":1119},58,[242,1121,1122],{"class":252},"    output: {kernel: outputKernel, key: ",[242,1124,1125],{"class":259},"'smokeTexture'",[242,1127,608],{"class":252},[242,1129,1131,1134,1137],{"class":244,"line":1130},59,[242,1132,1133],{"class":252},"    pointer: {minDrag: ",[242,1135,1136],{"class":441},"0.0005",[242,1138,608],{"class":252},[242,1140,1142,1145,1147],{"class":244,"line":1141},60,[242,1143,1144],{"class":252},"    inject: [",[242,1146,183],{"class":526},[242,1148,1149],{"class":252},"({kernel: splatKernel})],\n",[242,1151,1153,1156,1159,1163,1166,1168],{"class":244,"line":1152},61,[242,1154,1155],{"class":526},"    values",[242,1157,1158],{"class":252},": (",[242,1160,1162],{"class":1161},"s9osk","f",[242,1164,1165],{"class":252},") ",[242,1167,1086],{"class":248},[242,1169,1170],{"class":252}," {\n",[242,1172,1174,1177,1180,1182,1185,1188,1190,1193,1195,1198,1200,1203,1206,1209,1212,1215,1217,1219,1221,1224],{"class":244,"line":1173},62,[242,1175,1176],{"class":248},"      const",[242,1178,1179],{"class":441}," emit",[242,1181,471],{"class":248},[242,1183,1184],{"class":252}," f.",[242,1186,1187],{"class":526},"getCpuValue",[242,1189,756],{"class":252},[242,1191,1192],{"class":259},"'emitFrom'",[242,1194,1165],{"class":252},[242,1196,1197],{"class":248},"as",[242,1199,438],{"class":252},[242,1201,1202],{"class":1161},"x",[242,1204,1205],{"class":248},":",[242,1207,1208],{"class":441}," number",[242,1210,1211],{"class":252},"; ",[242,1213,1214],{"class":1161},"y",[242,1216,1205],{"class":248},[242,1218,1208],{"class":441},[242,1220,449],{"class":252},[242,1222,1223],{"class":248},"|",[242,1225,1226],{"class":441}," undefined\n",[242,1228,1230,1232,1235,1237,1239,1242,1244,1247,1249,1251,1253,1256,1258,1260],{"class":244,"line":1229},63,[242,1231,1176],{"class":248},[242,1233,1234],{"class":441}," velMag",[242,1236,471],{"class":248},[242,1238,1184],{"class":252},[242,1240,1241],{"class":526},"num",[242,1243,756],{"class":252},[242,1245,1246],{"class":259},"'speed'",[242,1248,444],{"class":252},[242,1250,1020],{"class":441},[242,1252,1165],{"class":252},[242,1254,1255],{"class":248},"*",[242,1257,468],{"class":441},[242,1259,489],{"class":248},[242,1261,1262],{"class":441}," 0.15\n",[242,1264,1266,1268,1271,1273,1276],{"class":244,"line":1265},64,[242,1267,1176],{"class":248},[242,1269,1270],{"class":441}," ptr",[242,1272,471],{"class":248},[242,1274,1275],{"class":252}," f.ptr",[242,1277,1278],{"class":248},"!\n",[242,1280,1282,1284,1287,1289,1291,1293,1295,1298,1300,1302],{"class":244,"line":1281},65,[242,1283,1176],{"class":248},[242,1285,1286],{"class":441}," mouseInf",[242,1288,471],{"class":248},[242,1290,1184],{"class":252},[242,1292,1241],{"class":526},[242,1294,756],{"class":252},[242,1296,1297],{"class":259},"'mouseInfluence'",[242,1299,444],{"class":252},[242,1301,1064],{"class":441},[242,1303,1304],{"class":252},")\n",[242,1306,1308,1310,1313,1315,1318,1321,1324,1327],{"class":244,"line":1307},66,[242,1309,1176],{"class":248},[242,1311,1312],{"class":441}," active",[242,1314,471],{"class":248},[242,1316,1317],{"class":252}," ptr.moving ",[242,1319,1320],{"class":248},"&&",[242,1322,1323],{"class":252}," mouseInf ",[242,1325,1326],{"class":248},">",[242,1328,1329],{"class":441}," 0\n",[242,1331,1333,1335,1338,1340,1343,1345],{"class":244,"line":1332},67,[242,1334,1176],{"class":248},[242,1336,1337],{"class":441}," mouseRadGrid",[242,1339,471],{"class":248},[242,1341,1342],{"class":441}," 0.1",[242,1344,489],{"class":248},[242,1346,492],{"class":441},[242,1348,1350,1353],{"class":244,"line":1349},68,[242,1351,1352],{"class":248},"      return",[242,1354,1170],{"class":252},[242,1356,1358],{"class":244,"line":1357},69,[242,1359,1360],{"class":252},"        dt: f.dt,\n",[242,1362,1364,1367,1370,1373,1375,1377,1379],{"class":244,"line":1363},70,[242,1365,1366],{"class":252},"        emitX: (emit?.x ",[242,1368,1369],{"class":248},"??",[242,1371,1372],{"class":441}," 0.5",[242,1374,1165],{"class":252},[242,1376,1255],{"class":248},[242,1378,468],{"class":441},[242,1380,954],{"class":252},[242,1382,1384,1387,1389,1392,1395,1397,1400,1403,1405,1407],{"class":244,"line":1383},71,[242,1385,1386],{"class":252},"        emitY: (",[242,1388,1008],{"class":441},[242,1390,1391],{"class":248}," -",[242,1393,1394],{"class":252}," (emit?.y ",[242,1396,1369],{"class":248},[242,1398,1399],{"class":441}," 0",[242,1401,1402],{"class":252},")) ",[242,1404,1255],{"class":248},[242,1406,468],{"class":441},[242,1408,954],{"class":252},[242,1410,1412,1415,1418,1421,1424],{"class":244,"line":1411},72,[242,1413,1414],{"class":252},"        emitVelX: ",[242,1416,1417],{"class":441},"0",[242,1419,1420],{"class":252},", emitVelY: ",[242,1422,1423],{"class":248},"-",[242,1425,1426],{"class":252},"velMag,\n",[242,1428,1430,1433,1435,1438,1440],{"class":244,"line":1429},73,[242,1431,1432],{"class":252},"        perpDirX: ",[242,1434,1008],{"class":441},[242,1436,1437],{"class":252},", perpDirY: ",[242,1439,1417],{"class":441},[242,1441,954],{"class":252},[242,1443,1445,1448,1451,1454,1457,1460,1463],{"class":244,"line":1444},74,[242,1446,1447],{"class":252},"        spreadFactor: Math.",[242,1449,1450],{"class":526},"tan",[242,1452,1453],{"class":252},"(Math.",[242,1455,1456],{"class":441},"PI",[242,1458,1459],{"class":248}," \u002F",[242,1461,1462],{"class":441}," 6",[242,1464,1465],{"class":252},"),\n",[242,1467,1469,1472,1474,1476,1479,1481,1483,1485,1487,1489],{"class":244,"line":1468},75,[242,1470,1471],{"class":252},"        emitRad: f.",[242,1473,1241],{"class":526},[242,1475,756],{"class":252},[242,1477,1478],{"class":259},"'emitRadius'",[242,1480,444],{"class":252},[242,1482,1031],{"class":441},[242,1484,1165],{"class":252},[242,1486,1255],{"class":248},[242,1488,468],{"class":441},[242,1490,954],{"class":252},[242,1492,1494,1497,1499],{"class":244,"line":1493},76,[242,1495,1496],{"class":252},"        emitIntensity: ",[242,1498,1008],{"class":441},[242,1500,954],{"class":252},[242,1502,1504,1507,1509,1511,1514,1516,1518],{"class":244,"line":1503},77,[242,1505,1506],{"class":252},"        dyeFade: f.",[242,1508,1241],{"class":526},[242,1510,756],{"class":252},[242,1512,1513],{"class":259},"'dissipation'",[242,1515,444],{"class":252},[242,1517,1042],{"class":441},[242,1519,1465],{"class":252},[242,1521,1523,1526,1528],{"class":244,"line":1522},78,[242,1524,1525],{"class":252},"        velFade: ",[242,1527,1042],{"class":441},[242,1529,954],{"class":252},[242,1531,1533,1536,1538,1540,1543,1545,1547],{"class":244,"line":1532},79,[242,1534,1535],{"class":252},"        curlStrength: f.",[242,1537,1241],{"class":526},[242,1539,756],{"class":252},[242,1541,1542],{"class":259},"'detail'",[242,1544,444],{"class":252},[242,1546,1053],{"class":441},[242,1548,1465],{"class":252},[242,1550,1552,1555,1557],{"class":244,"line":1551},80,[242,1553,1554],{"class":252},"        gravity: ",[242,1556,1002],{"class":441},[242,1558,954],{"class":252},[242,1560,1562,1565,1568],{"class":244,"line":1561},81,[242,1563,1564],{"class":252},"        colorDecay: ",[242,1566,1567],{"class":441},"0.4",[242,1569,954],{"class":252},[242,1571,1573,1576,1579,1582,1584,1586,1589,1591],{"class":244,"line":1572},82,[242,1574,1575],{"class":252},"        cursorX: active ",[242,1577,1578],{"class":248},"?",[242,1580,1581],{"class":252}," ptr.x ",[242,1583,1255],{"class":248},[242,1585,468],{"class":441},[242,1587,1588],{"class":248}," :",[242,1590,1399],{"class":441},[242,1592,954],{"class":252},[242,1594,1596,1599,1601,1604,1606,1608,1610,1612],{"class":244,"line":1595},83,[242,1597,1598],{"class":252},"        cursorY: active ",[242,1600,1578],{"class":248},[242,1602,1603],{"class":252}," ptr.y ",[242,1605,1255],{"class":248},[242,1607,468],{"class":441},[242,1609,1588],{"class":248},[242,1611,1399],{"class":441},[242,1613,954],{"class":252},[242,1615,1617,1620,1622,1625,1627,1629,1631,1634,1636,1638,1640,1642],{"class":244,"line":1616},84,[242,1618,1619],{"class":252},"        cursorVelX: active ",[242,1621,1578],{"class":248},[242,1623,1624],{"class":252}," ptr.dx ",[242,1626,1255],{"class":248},[242,1628,468],{"class":441},[242,1630,489],{"class":248},[242,1632,1633],{"class":441}," 15",[242,1635,489],{"class":248},[242,1637,1323],{"class":252},[242,1639,1205],{"class":248},[242,1641,1399],{"class":441},[242,1643,954],{"class":252},[242,1645,1647,1650,1652,1655,1657,1659,1661,1663,1665,1667,1669,1671],{"class":244,"line":1646},85,[242,1648,1649],{"class":252},"        cursorVelY: active ",[242,1651,1578],{"class":248},[242,1653,1654],{"class":252}," ptr.dy ",[242,1656,1255],{"class":248},[242,1658,468],{"class":441},[242,1660,489],{"class":248},[242,1662,1633],{"class":441},[242,1664,489],{"class":248},[242,1666,1323],{"class":252},[242,1668,1205],{"class":248},[242,1670,1399],{"class":441},[242,1672,954],{"class":252},[242,1674,1676,1679,1681,1684,1686,1688],{"class":244,"line":1675},86,[242,1677,1678],{"class":252},"        mouseActive: active ",[242,1680,1578],{"class":248},[242,1682,1683],{"class":441}," 1",[242,1685,1588],{"class":248},[242,1687,1399],{"class":441},[242,1689,954],{"class":252},[242,1691,1693,1696,1698],{"class":244,"line":1692},87,[242,1694,1695],{"class":252},"        mouseRadSq: mouseRadGrid ",[242,1697,1255],{"class":248},[242,1699,1700],{"class":252}," mouseRadGrid,\n",[242,1702,1704],{"class":244,"line":1703},88,[242,1705,1706],{"class":252},"      }\n",[242,1708,1710],{"class":244,"line":1709},89,[242,1711,1712],{"class":252},"    },\n",[242,1714,1716],{"class":244,"line":1715},90,[242,1717,1718],{"class":252},"  })),\n",[242,1720,1722],{"class":244,"line":1721},91,[242,1723,1724],{"class":252},"  gpu: {\n",[242,1726,1728,1731,1734,1737,1739,1742,1744,1747,1750,1752,1755,1758,1760,1763,1766],{"class":244,"line":1727},92,[242,1729,1730],{"class":526},"    fragment",[242,1732,1733],{"class":252},": ({",[242,1735,1736],{"class":1161},"ctx",[242,1738,444],{"class":252},[242,1740,1741],{"class":1161},"computeOutputs",[242,1743,444],{"class":252},[242,1745,1746],{"class":1161},"uniforms",[242,1748,1749],{"class":252},"}",[242,1751,1205],{"class":248},[242,1753,1754],{"class":526}," GpuFragmentParams",[242,1756,1757],{"class":252},")",[242,1759,1205],{"class":248},[242,1761,1762],{"class":526}," Expr",[242,1764,1765],{"class":248}," =>",[242,1767,1170],{"class":252},[242,1769,1771,1773,1776,1778,1781,1783,1786,1789],{"class":244,"line":1770},93,[242,1772,1176],{"class":248},[242,1774,1775],{"class":441}," field",[242,1777,471],{"class":248},[242,1779,1780],{"class":252}," computeOutputs?.smokeTexture ",[242,1782,1197],{"class":248},[242,1784,1785],{"class":526}," KitTexture",[242,1787,1788],{"class":248}," |",[242,1790,1226],{"class":441},[242,1792,1794,1797,1800,1803,1806,1809,1812],{"class":244,"line":1793},94,[242,1795,1796],{"class":248},"      if",[242,1798,1799],{"class":252}," (",[242,1801,1802],{"class":248},"!",[242,1804,1805],{"class":252},"field) ",[242,1807,1808],{"class":248},"return",[242,1810,1811],{"class":441}," ZERO",[242,1813,1814],{"class":503}," \u002F\u002F no GPU: transparent\n",[242,1816,1818,1820,1823,1825,1828,1831,1834,1837,1839],{"class":244,"line":1817},95,[242,1819,1176],{"class":248},[242,1821,1822],{"class":441}," s",[242,1824,471],{"class":248},[242,1826,1827],{"class":252}," field.",[242,1829,1830],{"class":526},"sample",[242,1832,1833],{"class":252},"(ctx.uv, ",[242,1835,1836],{"class":259},"'linearClamp'",[242,1838,1165],{"class":252},[242,1840,1841],{"class":503},"\u002F\u002F x = density, y = age\n",[242,1843,1845,1847,1850,1852,1855,1858,1861,1863,1866],{"class":244,"line":1844},96,[242,1846,1176],{"class":248},[242,1848,1849],{"class":441}," color",[242,1851,471],{"class":248},[242,1853,1854],{"class":526}," mixExpr",[242,1856,1857],{"class":252},"(uniforms.colorA, uniforms.colorB, s.",[242,1859,1860],{"class":526},"member",[242,1862,756],{"class":252},[242,1864,1865],{"class":259},"'y'",[242,1867,1868],{"class":252},"))\n",[242,1870,1872,1874,1877,1880,1882,1884,1887,1890,1892,1894,1897,1900,1903,1906,1908,1910,1913],{"class":244,"line":1871},97,[242,1873,1352],{"class":248},[242,1875,1876],{"class":526}," vec4",[242,1878,1879],{"class":252},"(color.",[242,1881,1860],{"class":526},[242,1883,756],{"class":252},[242,1885,1886],{"class":259},"'rgb'",[242,1888,1889],{"class":252},"), color.",[242,1891,1860],{"class":526},[242,1893,756],{"class":252},[242,1895,1896],{"class":259},"'a'",[242,1898,1899],{"class":252},").",[242,1901,1902],{"class":526},"mul",[242,1904,1905],{"class":252},"(s.",[242,1907,1860],{"class":526},[242,1909,756],{"class":252},[242,1911,1912],{"class":259},"'x'",[242,1914,1915],{"class":252},")))\n",[242,1917,1919],{"class":244,"line":1918},98,[242,1920,1712],{"class":252},[242,1922,1924],{"class":244,"line":1923},99,[242,1925,1072],{"class":252},[242,1927,1929],{"class":244,"line":1928},100,[242,1930,560],{"class":252},[262,1932,1934],{"id":1933},"types","Types",[267,1936,1937,1947],{},[270,1938,1939],{},[273,1940,1941,1944],{},[276,1942,1943],{},"Type",[276,1945,1946],{},"What it is",[283,1948,1949,1959,1969,1979,1992,2002,2012,2022,2032,2042,2052,2062],{},[273,1950,1951,1956],{},[288,1952,1953],{},[8,1954,1955],{},"CursorRibbonSpec",[288,1957,1958],{},"This frame's ribbon of stamps along the stroke: spacing, cap, and how each stamp is written.",[273,1960,1961,1966],{},[288,1962,1963],{},[8,1964,1965],{},"FluidContainerParts",[288,1967,1968],{},"What a container (a shape the fluid is confined to) contributes each frame.",[273,1970,1971,1976],{},[288,1972,1973],{},[8,1974,1975],{},"FluidEmitter",[288,1977,1978],{},"Something that injects into the field each frame.",[273,1980,1981,1986],{},[288,1982,1983],{},[8,1984,1985],{},"FluidFrame",[288,1987,1988,1989,1991],{},"One frame, as every part and ",[8,1990,223],{}," sees it: the clamped delta, the clocks, the pointer and your props.",[273,1993,1994,1999],{},[288,1995,1996],{},[8,1997,1998],{},"FluidFrameParams",[288,2000,2001],{},"What the renderer reports each frame: the pointer in uv, the frame delta in seconds, the canvas size in pixels.",[273,2003,2004,2009],{},[288,2005,2006],{},[8,2007,2008],{},"FluidInitIo",[288,2010,2011],{},"What an init part appends with: the frame's pass list, a queued values write, and a full solve.",[273,2013,2014,2019],{},[288,2015,2016],{},[8,2017,2018],{},"FluidInitPart",[288,2020,2021],{},"How the field starts, and when it must start over.",[273,2023,2024,2029],{},[288,2025,2026],{},[8,2027,2028],{},"FluidKernel",[288,2030,2031],{},"A pass function run once per grid cell, with the cell's column and row.",[273,2033,2034,2039],{},[288,2035,2036],{},[8,2037,2038],{},"FluidRoot",[288,2040,2041],{},"The GPU device handle the build callback receives, for creating the resources your passes use.",[273,2043,2044,2049],{},[288,2045,2046],{},[8,2047,2048],{},"FluidSetupCtx",[288,2050,2051],{},"What a part receives when it builds its passes: the device, the grid size, the buffers and a pass builder.",[273,2053,2054,2059],{},[288,2055,2056],{},[8,2057,2058],{},"FluidSimConfig",[288,2060,2061],{},"What a fluid simulation declares: its grid, its solver, its output, its parts and its per-frame values.",[273,2063,2064,2069],{},[288,2065,2066],{},[8,2067,2068],{},"FluidSolveStage",[288,2070,2071,2072,2074,2075,1899],{},"A pass that runs inside every solve, before it (",[8,2073,233],{},") or after it (",[8,2076,2077],{},"post",[262,2079,2081],{"id":2080},"words","Words",[2083,2084,2086],"primitive-words",{":words":2085},"[{\"name\":\"fluidSim\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Ffluidsim\",\"summary\":\"A fluid the engine solves every frame.\"},{\"name\":\"splat\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Fsplat\",\"summary\":\"An emitter at a fixed source: one pass per frame that adds dye and momentum where your pass function says (a cone from a point, a line along an edge).\"},{\"name\":\"cursorRibbon\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Fcursorribbon\",\"summary\":\"An emitter that paints along the pointer's stroke: a ribbon of stamps between last frame's position and this one, so a fast flick leaves a continuous line, not dots.\"},{\"name\":\"seededFieldInit\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Fseededfieldinit\",\"summary\":\"A field that starts full: seed it from a pass function, then run the solve silently `warm.steps` times so the first visible frame already flows.\"},{\"name\":\"ambientForce\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Fambientforce\",\"summary\":\"A force applied to the whole field before every solve: a turbulence field, a steady wind.\"},{\"name\":\"restoreToward\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-fluids\u002Frestoretoward\",\"summary\":\"A correction applied after every solve: re-seed a color that the solve slowly blurs away.\"}]",[2087,2088,2089,2097,2104,2111,2122,2129],"ul",{},[2090,2091,2092,2096],"li",{},[165,2093,2094],{"href":167},[8,2095,170],{}," — A fluid the engine solves every frame.",[2090,2098,2099,2103],{},[165,2100,2101],{"href":180},[8,2102,183],{}," — An emitter at a fixed source: one pass per frame that adds dye and momentum where your pass function says (a cone from a point, a line along an edge).",[2090,2105,2106,2110],{},[165,2107,2108],{"href":187},[8,2109,190],{}," — An emitter that paints along the pointer's stroke: a ribbon of stamps between last frame's position and this one, so a fast flick leaves a continuous line, not dots.",[2090,2112,2113,2117,2118,2121],{},[165,2114,2115],{"href":216},[8,2116,219],{}," — A field that starts full: seed it from a pass function, then run the solve silently ",[8,2119,2120],{},"warm.steps"," times so the first visible frame already flows.",[2090,2123,2124,2128],{},[165,2125,2126],{"href":198},[8,2127,201],{}," — A force applied to the whole field before every solve: a turbulence field, a steady wind.",[2090,2130,2131,2135],{},[165,2132,2133],{"href":205},[8,2134,208],{}," — A correction applied after every solve: re-seed a color that the solve slowly blurs away.",[2137,2138,2139],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":238,"searchDepth":384,"depth":384,"links":2141},[2142,2143,2144,2145],{"id":264,"depth":384,"text":265},{"id":364,"depth":384,"text":365},{"id":1933,"depth":384,"text":1934},{"id":2080,"depth":384,"text":2081},"sim.fluids","sim-fluids","Smoke, ink and fog that flow.","https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fedit\u002Fmain\u002Fpackages\u002Fcore\u002Fdocs\u002Fstd\u002Fsim.fluids.md","md","simulation","Simulation",{},"\u002Fdocs\u002Fprimitives\u002Fsim-fluids",{"title":147,"description":2148},"https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fblob\u002Fmain\u002Fpackages\u002Fcore\u002Fsrc\u002Fstd\u002Fsim\u002Ffluids.ts","docs\u002Fprimitives\u002F38.sim-fluids\u002Findex","g0KYVRC9X_mqfObONn7Z5h0rgGjwBVGr68QB38IagOI"]