[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"guide-nav":3,"doc-\u002Fdocs\u002Fprimitives\u002Fsim-grids":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":1077,"categorySlug":1078,"categoryTitle":9,"curated":495,"description":1079,"editUrl":1080,"extension":1081,"group":1082,"groupTitle":1083,"kind":9,"meta":1084,"navigation":495,"path":1085,"seo":1086,"sourceUrl":1087,"stem":1088,"wordCount":643,"__hash__":1089},"primitives\u002Fdocs\u002Fprimitives\u002F37.sim-grids\u002Findex.md","Grid programs",{"type":149,"value":150,"toc":1071},"minimark",[151,155,241,249,278,307,312,470,474,812,816,910,914,1067],[152,153,147],"h1",{"id":154},"grid-programs",[156,157,158,159,166,167,171,172,175,176,182,183,182,189,195,196,202,203,182,209,182,215,182,221,182,227,233,234,240],"p",{},"A grid simulation is a fixed-size field of cells (a displacement per cell, two chemical\nconcentrations, a sort offset) that changes a little every frame. ",[160,161,163],"a",{"href":162},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fgridsim",[8,164,165],{},"gridSim"," runs it: you\ndescribe the frame as an ordered list of ",[168,169,170],"strong",{},"stages"," built with ",[8,173,174],{},"op.*",", and the engine runs that\nlist every frame, owning the clock, the frame-delta clamp, the ready gate, the settle gate and\nthe outputs the layer samples. A stage is bookkeeping (",[160,177,179],{"href":178},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-host",[8,180,181],{},"op.host",", ",[160,184,186],{"href":185},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-values",[8,187,188],{},"op.values",[160,190,192],{"href":191},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-readywhen",[8,193,194],{},"op.readyWhen",",\n",[160,197,199],{"href":198},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-settle",[8,200,201],{},"op.settle",") or work (",[160,204,206],{"href":205},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-pass",[8,207,208],{},"op.pass",[160,210,212],{"href":211},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-cache",[8,213,214],{},"op.cache",[160,216,218],{"href":217},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-seedonce",[8,219,220],{},"op.seedOnce",[160,222,224],{"href":223},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-iterate",[8,225,226],{},"op.iterate",[160,228,230],{"href":229},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-sortpass",[8,231,232],{},"op.sortPass","), and\nevery frame ends with ",[160,235,237],{"href":236},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-publish",[8,238,239],{},"op.publish",", which writes the state into the texture the fragment reads.",[156,242,243,244,248],{},"The build callback runs once per instance of the layer and returns the outputs, the clamp and\nthe stages; anything it creates (buffers, passes, trackers) belongs to that instance. A settled\nfield costs nothing: once ",[160,245,246],{"href":198},[8,247,201],{}," sees nothing driving it, frames are skipped and the last\npublished picture stays on screen.",[156,250,251,252,255,256,259,260,266,267,273,274,277],{},"Two shortcuts sit on top. The pointer fields in ",[8,253,254],{},"effects.pointerFields"," are whole grid programs\nyou spread as ",[8,257,258],{},"...gridSim(springLatticeField({...}))"," and read with a warp map. And for a small\nfield whose arithmetic reads better as JavaScript loops, ",[160,261,263],{"href":262},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fhostgridprogram",[8,264,265],{},"hostGridProgram"," runs the same named\nsteps on the CPU and ",[160,268,270],{"href":269},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fhostfieldtexture",[8,271,272],{},"hostFieldTexture"," uploads the cells as a texture. When a wave field and a\ndisplacement are all you need, declare them with ",[8,275,276],{},"simulate.grid"," instead.",[279,280,285],"pre",{"className":281,"code":282,"language":283,"meta":284,"style":284},"language-ts shiki shiki-themes github-dark","import {sim} from 'shaders\u002Fstd'\n","ts","",[8,286,287],{"__ignoreMap":284},[288,289,292,296,300,303],"span",{"class":290,"line":291},"line",1,[288,293,295],{"class":294},"snl16","import",[288,297,299],{"class":298},"s95oV"," {sim} ",[288,301,302],{"class":294},"from",[288,304,306],{"class":305},"sU2Wk"," 'shaders\u002Fstd'\n",[308,309,311],"h2",{"id":310},"reach-for-it-when","Reach for it when",[313,314,315,328],"table",{},[316,317,318],"thead",{},[319,320,321,325],"tr",{},[322,323,324],"th",{},"When you need",[322,326,327],{},"Use",[329,330,331,348,369,386,397,413,424,435,448],"tbody",{},[319,332,333,337],{},[334,335,336],"td",{},"liquid or fabric that ripples after the cursor pushes it",[334,338,339,343,344,347],{},[160,340,341],{"href":162},[8,342,165],{}," with ",[8,345,346],{},"springLatticeField"," and a warp map",[319,349,350,353],{},[334,351,352],{},"a rule that must run N times per frame (reaction-diffusion)",[334,354,355,359,360,364,365],{},[160,356,357],{"href":223},[8,358,226],{}," after ",[160,361,362],{"href":185},[8,363,188],{},", then ",[160,366,367],{"href":236},[8,368,239],{},[319,370,371,374],{},[334,372,373],{},"a sort that settles a little more every frame",[334,375,376,380,381,385],{},[160,377,378],{"href":229},[8,379,232],{},", with ",[160,382,383],{"href":236},[8,384,239],{}," reading its side",[319,387,388,391],{},[334,389,390],{},"the state must be reset on the first frame or a seed change",[334,392,393],{},[160,394,395],{"href":217},[8,396,220],{},[319,398,399,402],{},[334,400,401],{},"a pass that needs the child's picture, which arrives late",[334,403,404,408,409],{},[160,405,406],{"href":191},[8,407,194],{}," and ",[160,410,411],{"href":211},[8,412,214],{},[319,414,415,418],{},[334,416,417],{},"the simulation should sleep once nothing drives it",[334,419,420],{},[160,421,422],{"href":198},[8,423,201],{},[319,425,426,429],{},[334,427,428],{},"this frame's values written before the passes read them",[334,430,431],{},[160,432,433],{"href":185},[8,434,188],{},[319,436,437,440],{},[334,438,439],{},"the canvas size or aspect inside a stage",[334,441,442],{},[160,443,445],{"href":444},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Ftrackedviewport",[8,446,447],{},"trackedViewport",[319,449,450,453],{},[334,451,452],{},"a small field stepped in plain JavaScript",[334,454,455,343,459,465,466],{},[160,456,457],{"href":262},[8,458,265],{},[160,460,462],{"href":461},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fhoststep",[8,463,464],{},"hostStep",", published by ",[160,467,468],{"href":269},[8,469,272],{},[308,471,473],{"id":472},"example","Example",[279,475,477],{"className":281,"code":476,"language":283,"meta":284,"style":284},"import {defineShader, p, sim, effects, warps, transformEdges} from 'shaders\u002Fstd'\n\nconst {gridSim} = sim.grids\nconst {springLatticeField} = effects.pointerFields\n\n\u002F\u002F Liquify: a spring lattice the cursor pushes, published as a displacement field the warp map reads.\n\u002F\u002F The pointer field packages the whole stage list (pointer tracking, values, the step passes, the\n\u002F\u002F settle gate, publish); this definition only names the props and the output.\nexport const Liquify = defineShader({\n  name: 'Liquify',\n  usesPointer: true,\n  props: {\n    intensity: {default: 10},\n    stiffness: {default: 3},\n    damping: {default: 3},\n    radius: {default: 1},\n    edges: {default: 'stretch', transform: transformEdges, compileTime: true},\n  },\n  ...gridSim(springLatticeField({\n    stiffness: p('stiffness'), damping: p('damping'), radius: p('radius'),\n    output: 'displacement',\n  })),\n  \u002F\u002F Bend the incoming coordinate by the field, scaled by intensity, then handle the edges.\n  map: warps.liquidDisplace({intensity: p('intensity'), output: 'displacement'}),\n  \u002F\u002F Before the field exists (no GPU yet), the warp passes the layer through untouched.\n  uvRemapIdentityWhen: ({computeOutputs}) => !computeOutputs?.displacement,\n})\n",[8,478,479,490,497,518,534,539,546,552,558,580,591,602,608,620,631,641,652,668,674,689,725,736,742,748,775,781,806],{"__ignoreMap":284},[288,480,481,483,486,488],{"class":290,"line":291},[288,482,295],{"class":294},[288,484,485],{"class":298}," {defineShader, p, sim, effects, warps, transformEdges} ",[288,487,302],{"class":294},[288,489,306],{"class":305},[288,491,493],{"class":290,"line":492},2,[288,494,496],{"emptyLinePlaceholder":495},true,"\n",[288,498,500,503,506,509,512,515],{"class":290,"line":499},3,[288,501,502],{"class":294},"const",[288,504,505],{"class":298}," {",[288,507,165],{"class":508},"sDLfK",[288,510,511],{"class":298},"} ",[288,513,514],{"class":294},"=",[288,516,517],{"class":298}," sim.grids\n",[288,519,521,523,525,527,529,531],{"class":290,"line":520},4,[288,522,502],{"class":294},[288,524,505],{"class":298},[288,526,346],{"class":508},[288,528,511],{"class":298},[288,530,514],{"class":294},[288,532,533],{"class":298}," effects.pointerFields\n",[288,535,537],{"class":290,"line":536},5,[288,538,496],{"emptyLinePlaceholder":495},[288,540,542],{"class":290,"line":541},6,[288,543,545],{"class":544},"sAwPA","\u002F\u002F Liquify: a spring lattice the cursor pushes, published as a displacement field the warp map reads.\n",[288,547,549],{"class":290,"line":548},7,[288,550,551],{"class":544},"\u002F\u002F The pointer field packages the whole stage list (pointer tracking, values, the step passes, the\n",[288,553,555],{"class":290,"line":554},8,[288,556,557],{"class":544},"\u002F\u002F settle gate, publish); this definition only names the props and the output.\n",[288,559,561,564,567,570,573,577],{"class":290,"line":560},9,[288,562,563],{"class":294},"export",[288,565,566],{"class":294}," const",[288,568,569],{"class":508}," Liquify",[288,571,572],{"class":294}," =",[288,574,576],{"class":575},"svObZ"," defineShader",[288,578,579],{"class":298},"({\n",[288,581,583,586,589],{"class":290,"line":582},10,[288,584,585],{"class":298},"  name: ",[288,587,588],{"class":305},"'Liquify'",[288,590,195],{"class":298},[288,592,594,597,600],{"class":290,"line":593},11,[288,595,596],{"class":298},"  usesPointer: ",[288,598,599],{"class":508},"true",[288,601,195],{"class":298},[288,603,605],{"class":290,"line":604},12,[288,606,607],{"class":298},"  props: {\n",[288,609,611,614,617],{"class":290,"line":610},13,[288,612,613],{"class":298},"    intensity: {default: ",[288,615,616],{"class":508},"10",[288,618,619],{"class":298},"},\n",[288,621,623,626,629],{"class":290,"line":622},14,[288,624,625],{"class":298},"    stiffness: {default: ",[288,627,628],{"class":508},"3",[288,630,619],{"class":298},[288,632,634,637,639],{"class":290,"line":633},15,[288,635,636],{"class":298},"    damping: {default: ",[288,638,628],{"class":508},[288,640,619],{"class":298},[288,642,644,647,650],{"class":290,"line":643},16,[288,645,646],{"class":298},"    radius: {default: ",[288,648,649],{"class":508},"1",[288,651,619],{"class":298},[288,653,655,658,661,664,666],{"class":290,"line":654},17,[288,656,657],{"class":298},"    edges: {default: ",[288,659,660],{"class":305},"'stretch'",[288,662,663],{"class":298},", transform: transformEdges, compileTime: ",[288,665,599],{"class":508},[288,667,619],{"class":298},[288,669,671],{"class":290,"line":670},18,[288,672,673],{"class":298},"  },\n",[288,675,677,680,682,685,687],{"class":290,"line":676},19,[288,678,679],{"class":294},"  ...",[288,681,165],{"class":575},[288,683,684],{"class":298},"(",[288,686,346],{"class":575},[288,688,579],{"class":298},[288,690,692,695,697,699,702,705,707,709,712,715,717,719,722],{"class":290,"line":691},20,[288,693,694],{"class":298},"    stiffness: ",[288,696,156],{"class":575},[288,698,684],{"class":298},[288,700,701],{"class":305},"'stiffness'",[288,703,704],{"class":298},"), damping: ",[288,706,156],{"class":575},[288,708,684],{"class":298},[288,710,711],{"class":305},"'damping'",[288,713,714],{"class":298},"), radius: ",[288,716,156],{"class":575},[288,718,684],{"class":298},[288,720,721],{"class":305},"'radius'",[288,723,724],{"class":298},"),\n",[288,726,728,731,734],{"class":290,"line":727},21,[288,729,730],{"class":298},"    output: ",[288,732,733],{"class":305},"'displacement'",[288,735,195],{"class":298},[288,737,739],{"class":290,"line":738},22,[288,740,741],{"class":298},"  })),\n",[288,743,745],{"class":290,"line":744},23,[288,746,747],{"class":544},"  \u002F\u002F Bend the incoming coordinate by the field, scaled by intensity, then handle the edges.\n",[288,749,751,754,757,760,762,764,767,770,772],{"class":290,"line":750},24,[288,752,753],{"class":298},"  map: warps.",[288,755,756],{"class":575},"liquidDisplace",[288,758,759],{"class":298},"({intensity: ",[288,761,156],{"class":575},[288,763,684],{"class":298},[288,765,766],{"class":305},"'intensity'",[288,768,769],{"class":298},"), output: ",[288,771,733],{"class":305},[288,773,774],{"class":298},"}),\n",[288,776,778],{"class":290,"line":777},25,[288,779,780],{"class":544},"  \u002F\u002F Before the field exists (no GPU yet), the warp passes the layer through untouched.\n",[288,782,784,787,790,794,797,800,803],{"class":290,"line":783},26,[288,785,786],{"class":575},"  uvRemapIdentityWhen",[288,788,789],{"class":298},": ({",[288,791,793],{"class":792},"s9osk","computeOutputs",[288,795,796],{"class":298},"}) ",[288,798,799],{"class":294},"=>",[288,801,802],{"class":294}," !",[288,804,805],{"class":298},"computeOutputs?.displacement,\n",[288,807,809],{"class":290,"line":808},27,[288,810,811],{"class":298},"})\n",[308,813,815],{"id":814},"types","Types",[313,817,818,828],{},[316,819,820],{},[319,821,822,825],{},[322,823,824],{},"Type",[322,826,827],{},"What it is",[329,829,830,840,850,860,870,880,890,900],{},[319,831,832,837],{},[334,833,834],{},[8,835,836],{},"GridFrame",[334,838,839],{},"One frame, as every stage sees it: the clamped delta, the clock, and your props.",[319,841,842,847],{},[334,843,844],{},[8,845,846],{},"GridFrameParams",[334,848,849],{},"What the renderer reports each frame: the pointer in uv, the frame delta in seconds, the canvas size in pixels.",[319,851,852,857],{},[334,853,854],{},[8,855,856],{},"GridRoot",[334,858,859],{},"The GPU device handle the build callback receives, for creating the buffers and passes your stages use.",[319,861,862,867],{},[334,863,864],{},[8,865,866],{},"GridSimConfig",[334,868,869],{},"What a GPU grid simulation declares: its outputs, its frame-delta clamp, and its stages.",[319,871,872,877],{},[334,873,874],{},[8,875,876],{},"GridStage",[334,878,879],{},"One stage of the frame.",[319,881,882,887],{},[334,883,884],{},[8,885,886],{},"HostFrame",[334,888,889],{},"One frame of a JavaScript-stepped grid: the clamped delta, the clock and the pointer in uv.",[319,891,892,897],{},[334,893,894],{},[8,895,896],{},"HostStep",[334,898,899],{},"One named JavaScript step.",[319,901,902,907],{},[334,903,904],{},[8,905,906],{},"SortPassStage",[334,908,909],{},"A sort chain's stage, which also reports which of its two buffers holds the current result.",[308,911,913],{"id":912},"words","Words",[915,916,918],"primitive-words",{":words":917},"[{\"name\":\"gridSim\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fgridsim\",\"summary\":\"A field of cells advanced every frame by an ordered list of stages.\"},{\"name\":\"op\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop\",\"summary\":\"The stages a grid frame is built from.\"},{\"name\":\"op.values\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-values\",\"summary\":\"A named step that writes this frame's values for the passes after it.\"},{\"name\":\"op.pass\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-pass\",\"summary\":\"One GPU pass, the same every frame.\"},{\"name\":\"op.publish\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-publish\",\"summary\":\"The last stage: write the state into the texture the layer samples.\"},{\"name\":\"op.iterate\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-iterate\",\"summary\":\"Run a step `count` times this frame.\"},{\"name\":\"op.seedOnce\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-seedonce\",\"summary\":\"A one-shot reset run before the rest of the frame whenever `staleWhen` says the state is stale: on the first frame, or when a seed prop changes.\"},{\"name\":\"op.sortPass\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-sortpass\",\"summary\":\"A compare-and-swap sort that converges a little more every frame: `passes` swaps per frame, alternating odd and even pairs and the two buffers.\"},{\"name\":\"op.cache\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-cache\",\"summary\":\"A GPU pass chosen per frame, for a pass whose input is rebound after the frame starts.\"},{\"name\":\"op.readyWhen\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-readywhen\",\"summary\":\"Run nothing until `fn` returns true, typically once the child's picture has arrived through `bindInputs`.\"},{\"name\":\"op.settle\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-settle\",\"summary\":\"Sleep the simulation once nothing has driven it for `settleMs` of simulated time.\"},{\"name\":\"op.host\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop-host\",\"summary\":\"A named step that runs before any gate: pointer smoothing, activity flags, anything a later `settle` needs to know.\"},{\"name\":\"trackedViewport\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Ftrackedviewport\",\"summary\":\"The canvas size in pixels, kept current across resizes, in the two forms a stage wants.\"},{\"name\":\"hostGridProgram\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fhostgridprogram\",\"summary\":\"A frame program for a small grid stepped in plain JavaScript: the steps run in order every frame until one returns `'skip'`.\"},{\"name\":\"hostStep\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fhoststep\",\"summary\":\"One named step of a JavaScript-stepped grid.\"},{\"name\":\"hostFieldTexture\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fhostfieldtexture\",\"summary\":\"The texture a JavaScript-stepped grid is read through.\"}]",[919,920,921,929,938,945,952,959,970,981,992,999,1014,1025,1036,1043,1053,1060],"ul",{},[922,923,924,928],"li",{},[160,925,926],{"href":162},[8,927,165],{}," — A field of cells advanced every frame by an ordered list of stages.",[922,930,931,937],{},[160,932,934],{"href":933},"\u002Fdocs\u002Fprimitives\u002Fsim-grids\u002Fop",[8,935,936],{},"op"," — The stages a grid frame is built from.",[922,939,940,944],{},[160,941,942],{"href":185},[8,943,188],{}," — A named step that writes this frame's values for the passes after it.",[922,946,947,951],{},[160,948,949],{"href":205},[8,950,208],{}," — One GPU pass, the same every frame.",[922,953,954,958],{},[160,955,956],{"href":236},[8,957,239],{}," — The last stage: write the state into the texture the layer samples.",[922,960,961,965,966,969],{},[160,962,963],{"href":223},[8,964,226],{}," — Run a step ",[8,967,968],{},"count"," times this frame.",[922,971,972,976,977,980],{},[160,973,974],{"href":217},[8,975,220],{}," — A one-shot reset run before the rest of the frame whenever ",[8,978,979],{},"staleWhen"," says the state is stale: on the first frame, or when a seed prop changes.",[922,982,983,987,988,991],{},[160,984,985],{"href":229},[8,986,232],{}," — A compare-and-swap sort that converges a little more every frame: ",[8,989,990],{},"passes"," swaps per frame, alternating odd and even pairs and the two buffers.",[922,993,994,998],{},[160,995,996],{"href":211},[8,997,214],{}," — A GPU pass chosen per frame, for a pass whose input is rebound after the frame starts.",[922,1000,1001,1005,1006,1009,1010,1013],{},[160,1002,1003],{"href":191},[8,1004,194],{}," — Run nothing until ",[8,1007,1008],{},"fn"," returns true, typically once the child's picture has arrived through ",[8,1011,1012],{},"bindInputs",".",[922,1015,1016,1020,1021,1024],{},[160,1017,1018],{"href":198},[8,1019,201],{}," — Sleep the simulation once nothing has driven it for ",[8,1022,1023],{},"settleMs"," of simulated time.",[922,1026,1027,1031,1032,1035],{},[160,1028,1029],{"href":178},[8,1030,181],{}," — A named step that runs before any gate: pointer smoothing, activity flags, anything a later ",[8,1033,1034],{},"settle"," needs to know.",[922,1037,1038,1042],{},[160,1039,1040],{"href":444},[8,1041,447],{}," — The canvas size in pixels, kept current across resizes, in the two forms a stage wants.",[922,1044,1045,1049,1050,1013],{},[160,1046,1047],{"href":262},[8,1048,265],{}," — A frame program for a small grid stepped in plain JavaScript: the steps run in order every frame until one returns ",[8,1051,1052],{},"'skip'",[922,1054,1055,1059],{},[160,1056,1057],{"href":461},[8,1058,464],{}," — One named step of a JavaScript-stepped grid.",[922,1061,1062,1066],{},[160,1063,1064],{"href":269},[8,1065,272],{}," — The texture a JavaScript-stepped grid is read through.",[1068,1069,1070],"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":284,"searchDepth":492,"depth":492,"links":1072},[1073,1074,1075,1076],{"id":310,"depth":492,"text":311},{"id":472,"depth":492,"text":473},{"id":814,"depth":492,"text":815},{"id":912,"depth":492,"text":913},"sim.grids","sim-grids","A grid simulation is a fixed-size field of cells (a displacement per cell, two chemical concentrations, a sort offset) that changes a little every frame. gridSim runs it: you describe the frame as an ordered list of stages built with op., and the engine runs that list every frame, owning the clock, the frame-delta clamp, the ready gate, the settle gate and the outputs the layer samples.","https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fedit\u002Fmain\u002Fpackages\u002Fcore\u002Fdocs\u002Fstd\u002Fsim.grids.md","md","simulation","Simulation",{},"\u002Fdocs\u002Fprimitives\u002Fsim-grids",{"title":147,"description":1079},"https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fblob\u002Fmain\u002Fpackages\u002Fcore\u002Fsrc\u002Fstd\u002Fsim\u002Fgrids.ts","docs\u002Fprimitives\u002F37.sim-grids\u002Findex","EamxLgb9xTQRs36aauk9DSac_cKRPlHwKdbXhEDiKBM"]