[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"guide-nav":3,"doc-\u002Fdocs\u002Fprimitives\u002Fslots":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":607,"categorySlug":607,"categoryTitle":9,"curated":340,"description":608,"editUrl":609,"extension":610,"group":611,"groupTitle":612,"kind":9,"meta":613,"navigation":340,"path":614,"seo":615,"sourceUrl":616,"stem":617,"wordCount":386,"__hash__":618},"primitives\u002Fdocs\u002Fprimitives\u002F3.slots\u002Findex.md","Identity & recompile rules",{"type":149,"value":150,"toc":602},"minimark",[151,155,176,183,212,217,315,319,528,532,598],[152,153,147],"h1",{"id":154},"identity-recompile-rules",[156,157,158,159,163,164,167,168,171,172,175],"p",{},"Two small kinds of rule that make a filter cheap. An ",[160,161,162],"strong",{},"identity rule"," sits on a filter\ndefinition's ",[8,165,166],{},"identityWhen:"," and says when the filter does nothing: while it holds, the layer\ninside passes through untouched and the effect costs no GPU time. A ",[160,169,170],{},"recompile rule"," sits\non a prop's ",[8,173,174],{},"recompile:"," and says which changes rebuild the shader rather than just update a\nvalue.",[156,177,178,179,182],{},"They pair up. The skip is decided when the shader is built, so a prop the identity rule reads\nneeds ",[8,180,181],{},"recompile: crosses(value)"," at the same value. Cross it and the shader rebuilds with\nthe filter switched on or off. A prop that is mapped per pixel by a driver disables the skip\non its own, since its value then varies across the canvas.",[184,185,190],"pre",{"className":186,"code":187,"language":188,"meta":189,"style":189},"language-ts shiki shiki-themes github-dark","import {crosses, isZero, isValue, …} from 'shaders\u002Fstd'\n","ts","",[8,191,192],{"__ignoreMap":189},[193,194,197,201,205,208],"span",{"class":195,"line":196},"line",1,[193,198,200],{"class":199},"snl16","import",[193,202,204],{"class":203},"s95oV"," {crosses, isZero, isValue, …} ",[193,206,207],{"class":199},"from",[193,209,211],{"class":210},"sU2Wk"," 'shaders\u002Fstd'\n",[213,214,216],"h2",{"id":215},"reach-for-it-when","Reach for it when",[218,219,220,233],"table",{},[221,222,223],"thead",{},[224,225,226,230],"tr",{},[227,228,229],"th",{},"When you need",[227,231,232],{},"Use",[234,235,236,259,276,289,302],"tbody",{},[224,237,238,242],{},[239,240,241],"td",{},"skip a filter while a prop is 0",[239,243,244,251,252,258],{},[245,246,248],"a",{"href":247},"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fiszero",[8,249,250],{},"isZero",", with ",[245,253,255],{"href":254},"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fcrosses",[8,256,257],{},"crosses"," on the prop",[224,260,261,264],{},[239,262,263],{},"skip while a prop sits at its neutral value (1 for a gain)",[239,265,266,251,272,258],{},[245,267,269],{"href":268},"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fisvalue",[8,270,271],{},"isValue",[245,273,274],{"href":254},[8,275,257],{},[224,277,278,281],{},[239,279,280],{},"skip only when several props are all at rest",[239,282,283],{},[245,284,286],{"href":285},"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fallof",[8,287,288],{},"allOf",[224,290,291,294],{},[239,292,293],{},"a no-op condition the rules cannot express",[239,295,296],{},[245,297,299],{"href":298},"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fidentitywhenever",[8,300,301],{},"identityWhenever",[224,303,304,307],{},[239,305,306],{},"a rebuild threshold that is not a single value",[239,308,309],{},[245,310,312],{"href":311},"\u002Fdocs\u002Fprimitives\u002Fslots\u002Frecompilewhen",[8,313,314],{},"recompileWhen",[213,316,318],{"id":317},"example","Example",[184,320,322],{"className":186,"code":321,"language":188,"meta":189,"style":189},"import {defineShader, p, crosses, isValue, effects} from 'shaders\u002Fstd'\n\n\u002F\u002F Saturation: free while intensity sits at 1, rebuilt only when it leaves or returns.\nexport const Saturation = defineShader({\n  name: 'Saturation',\n  props: {\n    intensity: {\n      default: 1,\n      recompile: crosses(1),\n      ui: {type: 'range', min: 0, max: 3, step: 0.1, label: 'Intensity'},\n    },\n  },\n  effect: effects.color.saturate(p('intensity')),\n  identityWhen: isValue('intensity', 1),\n  missingChildMessage: 'Nest a layer inside Saturation to adjust its color.',\n})\n",[8,323,324,335,342,349,372,384,390,396,407,423,459,465,471,492,511,522],{"__ignoreMap":189},[193,325,326,328,331,333],{"class":195,"line":196},[193,327,200],{"class":199},[193,329,330],{"class":203}," {defineShader, p, crosses, isValue, effects} ",[193,332,207],{"class":199},[193,334,211],{"class":210},[193,336,338],{"class":195,"line":337},2,[193,339,341],{"emptyLinePlaceholder":340},true,"\n",[193,343,345],{"class":195,"line":344},3,[193,346,348],{"class":347},"sAwPA","\u002F\u002F Saturation: free while intensity sits at 1, rebuilt only when it leaves or returns.\n",[193,350,352,355,358,362,365,369],{"class":195,"line":351},4,[193,353,354],{"class":199},"export",[193,356,357],{"class":199}," const",[193,359,361],{"class":360},"sDLfK"," Saturation",[193,363,364],{"class":199}," =",[193,366,368],{"class":367},"svObZ"," defineShader",[193,370,371],{"class":203},"({\n",[193,373,375,378,381],{"class":195,"line":374},5,[193,376,377],{"class":203},"  name: ",[193,379,380],{"class":210},"'Saturation'",[193,382,383],{"class":203},",\n",[193,385,387],{"class":195,"line":386},6,[193,388,389],{"class":203},"  props: {\n",[193,391,393],{"class":195,"line":392},7,[193,394,395],{"class":203},"    intensity: {\n",[193,397,399,402,405],{"class":195,"line":398},8,[193,400,401],{"class":203},"      default: ",[193,403,404],{"class":360},"1",[193,406,383],{"class":203},[193,408,410,413,415,418,420],{"class":195,"line":409},9,[193,411,412],{"class":203},"      recompile: ",[193,414,257],{"class":367},[193,416,417],{"class":203},"(",[193,419,404],{"class":360},[193,421,422],{"class":203},"),\n",[193,424,426,429,432,435,438,441,444,447,450,453,456],{"class":195,"line":425},10,[193,427,428],{"class":203},"      ui: {type: ",[193,430,431],{"class":210},"'range'",[193,433,434],{"class":203},", min: ",[193,436,437],{"class":360},"0",[193,439,440],{"class":203},", max: ",[193,442,443],{"class":360},"3",[193,445,446],{"class":203},", step: ",[193,448,449],{"class":360},"0.1",[193,451,452],{"class":203},", label: ",[193,454,455],{"class":210},"'Intensity'",[193,457,458],{"class":203},"},\n",[193,460,462],{"class":195,"line":461},11,[193,463,464],{"class":203},"    },\n",[193,466,468],{"class":195,"line":467},12,[193,469,470],{"class":203},"  },\n",[193,472,474,477,480,482,484,486,489],{"class":195,"line":473},13,[193,475,476],{"class":203},"  effect: effects.color.",[193,478,479],{"class":367},"saturate",[193,481,417],{"class":203},[193,483,156],{"class":367},[193,485,417],{"class":203},[193,487,488],{"class":210},"'intensity'",[193,490,491],{"class":203},")),\n",[193,493,495,498,500,502,504,507,509],{"class":195,"line":494},14,[193,496,497],{"class":203},"  identityWhen: ",[193,499,271],{"class":367},[193,501,417],{"class":203},[193,503,488],{"class":210},[193,505,506],{"class":203},", ",[193,508,404],{"class":360},[193,510,422],{"class":203},[193,512,514,517,520],{"class":195,"line":513},15,[193,515,516],{"class":203},"  missingChildMessage: ",[193,518,519],{"class":210},"'Nest a layer inside Saturation to adjust its color.'",[193,521,383],{"class":203},[193,523,525],{"class":195,"line":524},16,[193,526,527],{"class":203},"})\n",[213,529,531],{"id":530},"words","Words",[533,534,536],"primitive-words",{":words":535},"[{\"name\":\"crosses\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fcrosses\",\"summary\":\"Rebuild the shader only when the prop crosses `value`, not on every change.\"},{\"name\":\"isZero\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fiszero\",\"summary\":\"Skip the filter entirely while `prop` is exactly 0.\"},{\"name\":\"isValue\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fisvalue\",\"summary\":\"Skip the filter entirely while `prop` equals `value`, for a filter whose no-op is not 0.\"},{\"name\":\"allOf\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fallof\",\"summary\":\"Skip the filter only while every rule holds, for a no-op that needs several props at rest.\"},{\"name\":\"identityWhenever\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fslots\u002Fidentitywhenever\",\"summary\":\"Skip the filter when your own test of the props' values says so.\"},{\"name\":\"recompileWhen\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fslots\u002Frecompilewhen\",\"summary\":\"Rebuild when your own test of the old and new value says so, for a threshold `crosses` cannot express.\"}]",[537,538,539,551,562,574,581,588],"ul",{},[540,541,542,546,547,550],"li",{},[245,543,544],{"href":254},[8,545,257],{}," — Rebuild the shader only when the prop crosses ",[8,548,549],{},"value",", not on every change.",[540,552,553,557,558,561],{},[245,554,555],{"href":247},[8,556,250],{}," — Skip the filter entirely while ",[8,559,560],{},"prop"," is exactly 0.",[540,563,564,557,568,570,571,573],{},[245,565,566],{"href":268},[8,567,271],{},[8,569,560],{}," equals ",[8,572,549],{},", for a filter whose no-op is not 0.",[540,575,576,580],{},[245,577,578],{"href":285},[8,579,288],{}," — Skip the filter only while every rule holds, for a no-op that needs several props at rest.",[540,582,583,587],{},[245,584,585],{"href":298},[8,586,301],{}," — Skip the filter when your own test of the props' values says so.",[540,589,590,594,595,597],{},[245,591,592],{"href":311},[8,593,314],{}," — Rebuild when your own test of the old and new value says so, for a threshold ",[8,596,257],{}," cannot express.",[599,600,601],"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 .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}",{"title":189,"searchDepth":337,"depth":337,"links":603},[604,605,606],{"id":215,"depth":337,"text":216},{"id":317,"depth":337,"text":318},{"id":530,"depth":337,"text":531},"slots","Two small kinds of rule that make a filter cheap.","https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fedit\u002Fmain\u002Fpackages\u002Fcore\u002Fdocs\u002Fstd\u002Fslots.md","md","define","Defining a shader",{},"\u002Fdocs\u002Fprimitives\u002Fslots",{"title":147,"description":608},"https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fblob\u002Fmain\u002Fpackages\u002Fcore\u002Fsrc\u002Fstd\u002Fslots.ts","docs\u002Fprimitives\u002F3.slots\u002Findex","WrwYbH74ln2CyHTaSnubmshL-oqFke2J1fWpVzda8c0"]