[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"github-stars":3,"guide-nav":5,"doc-\u002Fdocs\u002Fprimitives\u002Fdefine":129},{"stars":4},5505,[6,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,72,76,80,84,88,93,97,101,105,109,113,117,121,125],{"path":7,"title":8,"description":9,"category":10},"\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",{"path":12,"title":13,"description":14,"category":10},"\u002Fdocs\u002Fguide\u002Fquickstart","Quickstart","Install Shaders, render your first effect, and drive a prop from state.",{"path":16,"title":17,"description":18,"category":10},"\u002Fdocs\u002Fguide\u002Fcomposing-effects","Composing effects","Stack components as layers and nest them to control which layers an effect touches.",{"path":20,"title":21,"description":22,"category":10},"\u002Fdocs\u002Fguide\u002Fblending-masking","Blending and masking","Control how a layer mixes with the layers below it, and reveal one layer through another.",{"path":24,"title":25,"description":26,"category":10},"\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":28,"title":29,"description":30,"category":10},"\u002Fdocs\u002Fguide\u002Fdynamic-props","Dynamic props","Drive any numeric or position prop from time, the cursor, or another layer, without writing animation code.",{"path":32,"title":33,"description":34,"category":10},"\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":36,"title":37,"description":38,"category":10},"\u002Fdocs\u002Fguide\u002Fsizing-and-units","Sizing and units","Size and place layers in CSS units (px, %, vw, rem, and canvas units) that stay correct as the canvas and window resize.",{"path":40,"title":41,"description":42,"category":10},"\u002Fdocs\u002Fguide\u002Ftransforms","Transforms","Position, size, and rotate any layer inside the canvas with a bounding box, in any CSS unit.",{"path":44,"title":45,"description":46,"category":10},"\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":48,"title":49,"description":50,"category":10},"\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":52,"title":53,"description":54,"category":10},"\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":56,"title":57,"description":58,"category":10},"\u002Fdocs\u002Fguide\u002Fperformance","Performance","Learn what makes an effect expensive on the GPU and how to keep it inside the frame budget.",{"path":60,"title":61,"description":62,"category":10},"\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":64,"title":65,"description":66,"category":10},"\u002Fdocs\u002Fguide\u002Ftelemetry","Telemetry","The `\u003CShader>` component occasionally sends an anonymous performance report to help us improve the engine over time.",{"path":68,"title":69,"description":70,"category":71},"\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":73,"title":74,"description":75,"category":71},"\u002Fdocs\u002Fguide\u002Fcli","Shaders CLI","Install your own shaders and Pro shaders into your codebase as component files, and keep them in sync with the design editor.",{"path":77,"title":78,"description":79,"category":71},"\u002Fdocs\u002Fguide\u002Fagent-skill","Agent skill","Give your coding agent a skill that teaches it to build with Shaders components, the CLI and Pro shaders.",{"path":81,"title":82,"description":83,"category":10},"\u002Fdocs\u002Fguide\u002Fvideo-rendering","Rendering to video","Turn a shader effect into a video file, from the design editor or from a frame-by-frame pipeline such as Remotion, Hyperframes or Puppeteer.",{"path":85,"title":86,"description":87,"category":10},"\u002Fdocs\u002Fguide\u002Fssr","Server rendering","Render Shaders in Next.js, Nuxt, SvelteKit, SolidStart and other SSR apps by keeping each shader on the client.",{"path":89,"title":90,"description":91,"category":92},"\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":94,"title":95,"description":96,"category":92},"\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":98,"title":99,"description":100,"category":92},"\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":102,"title":103,"description":104,"category":92},"\u002Fdocs\u002Fguide\u002Fmasking-and-blending","Masking and blending","How blend modes and masks combine components in the design editor.",{"path":106,"title":107,"description":108,"category":92},"\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":110,"title":111,"description":112,"category":92},"\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":114,"title":115,"description":116,"category":92},"\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":118,"title":119,"description":120,"category":92},"\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":122,"title":123,"description":124,"category":92},"\u002Fdocs\u002Fguide\u002Fglass-component-spotlight","Component spotlight: Glass","A short look at the Glass component and the liquid-glass look it creates.",{"path":126,"title":127,"description":128,"category":92},"\u002Fdocs\u002Fguide\u002Fdigital-looks-component-spotlight","Component spotlight: Digital looks","A look at the digital stylization components for glitchy, futuristic, or technical effects.",{"id":130,"title":131,"body":132,"categoryId":1663,"categorySlug":1663,"categoryTitle":1664,"curated":185,"description":1665,"editUrl":1666,"extension":1667,"group":1663,"groupTitle":1668,"kind":1664,"meta":1669,"navigation":185,"path":1670,"seo":1671,"sourceUrl":1672,"stem":1673,"wordCount":266,"__hash__":1674},"primitives\u002Fdocs\u002Fprimitives\u002F1.define\u002Findex.md","defineShader & wgsl",{"type":133,"value":134,"toc":1657},"minimark",[135,139,151,321,328,410,416,508,538,564,589,607,726,742,747,891,895,1186,1190,1564,1568,1653],[136,137,131],"h1",{"id":138},"defineshader-wgsl",[140,141,142,143,150],"p",{},"A shader is a plain object: a name, the props a user can set, and one field that says what it\ndraws. Hand it to ",[144,145,147],"a",{"href":146},"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fdefineshader",[10,148,149],{},"defineShader"," and it becomes a component you can mount, nest, blend, mask\nand animate like any shader in the library.",[152,153,158],"pre",{"className":154,"code":155,"language":156,"meta":157,"style":157},"language-ts shiki shiki-themes github-dark","import {defineShader, transformColor, transformPosition, wgsl} from 'shaders\u002Fstd'\n\nexport const Halo = defineShader({\n  name: 'Halo',                      \u002F\u002F what the editor and preset JSON call it\n  props: {                           \u002F\u002F the controls a user can set\n    color: {default: '#ffd166', transform: transformColor},\n    center: {default: {x: 0.5, y: 0.5}, transform: transformPosition},\n    radius: {default: 0.6},\n  },\n  paint: wgsl`                       \u002F\u002F what it draws: a color for every pixel\n    let d = length((uv - center) * vec2f(aspect, 1.0)) \u002F radius;\n    return vec4f(color.rgb, 1.0 - smoothstep(0.8, 1.0, d));\n  `,\n})\n","ts","",[10,159,160,180,187,210,226,235,247,264,276,282,294,300,306,315],{"__ignoreMap":157},[161,162,165,169,173,176],"span",{"class":163,"line":164},"line",1,[161,166,168],{"class":167},"snl16","import",[161,170,172],{"class":171},"s95oV"," {defineShader, transformColor, transformPosition, wgsl} ",[161,174,175],{"class":167},"from",[161,177,179],{"class":178},"sU2Wk"," 'shaders\u002Fstd'\n",[161,181,183],{"class":163,"line":182},2,[161,184,186],{"emptyLinePlaceholder":185},true,"\n",[161,188,190,193,196,200,203,207],{"class":163,"line":189},3,[161,191,192],{"class":167},"export",[161,194,195],{"class":167}," const",[161,197,199],{"class":198},"sDLfK"," Halo",[161,201,202],{"class":167}," =",[161,204,206],{"class":205},"svObZ"," defineShader",[161,208,209],{"class":171},"({\n",[161,211,213,216,219,222],{"class":163,"line":212},4,[161,214,215],{"class":171},"  name: ",[161,217,218],{"class":178},"'Halo'",[161,220,221],{"class":171},",                      ",[161,223,225],{"class":224},"sAwPA","\u002F\u002F what the editor and preset JSON call it\n",[161,227,229,232],{"class":163,"line":228},5,[161,230,231],{"class":171},"  props: {                           ",[161,233,234],{"class":224},"\u002F\u002F the controls a user can set\n",[161,236,238,241,244],{"class":163,"line":237},6,[161,239,240],{"class":171},"    color: {default: ",[161,242,243],{"class":178},"'#ffd166'",[161,245,246],{"class":171},", transform: transformColor},\n",[161,248,250,253,256,259,261],{"class":163,"line":249},7,[161,251,252],{"class":171},"    center: {default: {x: ",[161,254,255],{"class":198},"0.5",[161,257,258],{"class":171},", y: ",[161,260,255],{"class":198},[161,262,263],{"class":171},"}, transform: transformPosition},\n",[161,265,267,270,273],{"class":163,"line":266},8,[161,268,269],{"class":171},"    radius: {default: ",[161,271,272],{"class":198},"0.6",[161,274,275],{"class":171},"},\n",[161,277,279],{"class":163,"line":278},9,[161,280,281],{"class":171},"  },\n",[161,283,285,288,291],{"class":163,"line":284},10,[161,286,287],{"class":171},"  paint: ",[161,289,290],{"class":205},"wgsl",[161,292,293],{"class":178},"`                       \u002F\u002F what it draws: a color for every pixel\n",[161,295,297],{"class":163,"line":296},11,[161,298,299],{"class":178},"    let d = length((uv - center) * vec2f(aspect, 1.0)) \u002F radius;\n",[161,301,303],{"class":163,"line":302},12,[161,304,305],{"class":178},"    return vec4f(color.rgb, 1.0 - smoothstep(0.8, 1.0, d));\n",[161,307,309,312],{"class":163,"line":308},13,[161,310,311],{"class":178},"  `",[161,313,314],{"class":171},",\n",[161,316,318],{"class":163,"line":317},14,[161,319,320],{"class":171},"})\n",[140,322,323,327],{},[324,325,326],"strong",{},"One field says what kind of shader it is."," Give exactly one.",[329,330,331,347],"table",{},[332,333,334],"thead",{},[335,336,337,341,344],"tr",{},[338,339,340],"th",{},"Field",[338,342,343],{},"You get",[338,345,346],{},"What is inside it",[348,349,350,364,384,397],"tbody",{},[335,351,352,358,361],{},[353,354,355],"td",{},[10,356,357],{},"paint:",[353,359,360],{},"a generator that paints from coordinates (gradients, noise, light)",[353,362,363],{},"nothing: it stands on its own",[335,365,366,371,374],{},[353,367,368],{},[10,369,370],{},"effect:",[353,372,373],{},"a filter over the layer nested inside it (tints, blurs, ripples)",[353,375,376,377,380,381],{},"the child layer, read as ",[10,378,379],{},"child"," or sampled as ",[10,382,383],{},"childTexture",[335,385,386,391,394],{},[353,387,388],{},[10,389,390],{},"map:",[353,392,393],{},"a distortion that moves the pixels of the layer inside it",[353,395,396],{},"the child layer",[335,398,399,404,407],{},[353,400,401],{},[10,402,403],{},"shape:",[353,405,406],{},"a 2D shape with fill and stroke",[353,408,409],{},"nothing",[140,411,412,415],{},[324,413,414],{},"Two ways to write what it draws."," Compose it from std words (the rest of this reference)\nand the engine compiles the composition to WGSL. A radial gradient between two color props is\none line:",[152,417,419],{"className":154,"code":418,"language":156,"meta":157,"style":157},"paint: rampOver(dist.radial({center: p('center'), radius: p('radius'), aspect: 1, skew: 0}), pair(p('inner'), p('outer'), p('colorSpace')))\n",[10,420,421],{"__ignoreMap":157},[161,422,423,426,429,432,435,438,441,443,446,449,452,454,456,459,462,465,468,471,474,477,479,481,483,486,489,491,493,496,498,500,502,505],{"class":163,"line":164},[161,424,425],{"class":205},"paint",[161,427,428],{"class":171},": ",[161,430,431],{"class":205},"rampOver",[161,433,434],{"class":171},"(dist.",[161,436,437],{"class":205},"radial",[161,439,440],{"class":171},"({center: ",[161,442,140],{"class":205},[161,444,445],{"class":171},"(",[161,447,448],{"class":178},"'center'",[161,450,451],{"class":171},"), radius: ",[161,453,140],{"class":205},[161,455,445],{"class":171},[161,457,458],{"class":178},"'radius'",[161,460,461],{"class":171},"), aspect: ",[161,463,464],{"class":198},"1",[161,466,467],{"class":171},", skew: ",[161,469,470],{"class":198},"0",[161,472,473],{"class":171},"}), ",[161,475,476],{"class":205},"pair",[161,478,445],{"class":171},[161,480,140],{"class":205},[161,482,445],{"class":171},[161,484,485],{"class":178},"'inner'",[161,487,488],{"class":171},"), ",[161,490,140],{"class":205},[161,492,445],{"class":171},[161,494,495],{"class":178},"'outer'",[161,497,488],{"class":171},[161,499,140],{"class":205},[161,501,445],{"class":171},[161,503,504],{"class":178},"'colorSpace'",[161,506,507],{"class":171},")))\n",[140,509,510,511,516,517,520,521,524,525,524,528,524,531,524,534,537],{},"Or write the math yourself in a ",[144,512,514],{"href":513},"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fwgsl",[10,515,290],{}," body: one function that returns a ",[10,518,519],{},"vec4f"," color. Your\nprops, ",[10,522,523],{},"uv",", ",[10,526,527],{},"time",[10,529,530],{},"aspect",[10,532,533],{},"viewport",[10,535,536],{},"pointer"," and the child are bound by name, so there\nis no setup to write. A filter that inverts whatever is inside it:",[152,539,541],{"className":154,"code":540,"language":156,"meta":157,"style":157},"effect: wgsl`\n  return vec4f(1.0 - child.rgb, child.a);\n`\n",[10,542,543,555,560],{"__ignoreMap":157},[161,544,545,548,550,552],{"class":163,"line":164},[161,546,547],{"class":205},"effect",[161,549,428],{"class":171},[161,551,290],{"class":205},[161,553,554],{"class":178},"`\n",[161,556,557],{"class":163,"line":182},[161,558,559],{"class":178},"  return vec4f(1.0 - child.rgb, child.a);\n",[161,561,562],{"class":163,"line":189},[161,563,554],{"class":178},[140,565,566,569,570,573,574,577,578,524,581,584,585,588],{},[324,567,568],{},"Props are the controls."," Each has a ",[10,571,572],{},"default",", usually a ",[10,575,576],{},"transform"," that says what kind of\nvalue it is (",[10,579,580],{},"transformColor",[10,582,583],{},"transformPosition",", …), and optional ",[10,586,587],{},"ui"," metadata that tells\nthe editor how to show it. Blend modes, opacity, masks, transforms, dynamic props and code\nexport come with every shader; you never write them.",[140,590,591,594,595,598,599,602,603,606],{},[324,592,593],{},"Use it like any other shader."," Mount it with ",[10,596,597],{},"\u003CCustomShader src={Halo}>"," in React, Vue,\nSvelte or Solid. Call ",[10,600,601],{},"registerShader(Halo)"," when preset JSON should be able to name it as\n",[10,604,605],{},"type: 'Halo'",".",[152,608,612],{"className":609,"code":610,"language":611,"meta":157,"style":157},"language-tsx shiki shiki-themes github-dark","import {Shader, CustomShader, Blur} from 'shaders\u002Freact' \u002F\u002F or shaders\u002Fvue, shaders\u002Fsvelte, shaders\u002Fsolid\nimport {Halo} from '.\u002Fhalo'\n\n\u003CShader>\n  \u003CBlur intensity={8}>\n    \u003CCustomShader src={Halo} radius={0.8} \u002F>\n  \u003C\u002FBlur>\n\u003C\u002FShader>\n","tsx",[10,613,614,629,641,645,656,679,708,717],{"__ignoreMap":157},[161,615,616,618,621,623,626],{"class":163,"line":164},[161,617,168],{"class":167},[161,619,620],{"class":171}," {Shader, CustomShader, Blur} ",[161,622,175],{"class":167},[161,624,625],{"class":178}," 'shaders\u002Freact'",[161,627,628],{"class":224}," \u002F\u002F or shaders\u002Fvue, shaders\u002Fsvelte, shaders\u002Fsolid\n",[161,630,631,633,636,638],{"class":163,"line":182},[161,632,168],{"class":167},[161,634,635],{"class":171}," {Halo} ",[161,637,175],{"class":167},[161,639,640],{"class":178}," '.\u002Fhalo'\n",[161,642,643],{"class":163,"line":189},[161,644,186],{"emptyLinePlaceholder":185},[161,646,647,650,653],{"class":163,"line":212},[161,648,649],{"class":171},"\u003C",[161,651,652],{"class":198},"Shader",[161,654,655],{"class":171},">\n",[161,657,658,661,664,667,670,673,676],{"class":163,"line":228},[161,659,660],{"class":171},"  \u003C",[161,662,663],{"class":198},"Blur",[161,665,666],{"class":205}," intensity",[161,668,669],{"class":167},"=",[161,671,672],{"class":171},"{",[161,674,675],{"class":198},"8",[161,677,678],{"class":171},"}>\n",[161,680,681,684,687,690,692,695,698,700,702,705],{"class":163,"line":237},[161,682,683],{"class":171},"    \u003C",[161,685,686],{"class":198},"CustomShader",[161,688,689],{"class":205}," src",[161,691,669],{"class":167},[161,693,694],{"class":171},"{Halo} ",[161,696,697],{"class":205},"radius",[161,699,669],{"class":167},[161,701,672],{"class":171},[161,703,704],{"class":198},"0.8",[161,706,707],{"class":171},"} \u002F>\n",[161,709,710,713,715],{"class":163,"line":249},[161,711,712],{"class":171},"  \u003C\u002F",[161,714,663],{"class":198},[161,716,655],{"class":171},[161,718,719,722,724],{"class":163,"line":266},[161,720,721],{"class":171},"\u003C\u002F",[161,723,652],{"class":198},[161,725,655],{"class":171},[152,727,729],{"className":154,"code":728,"language":156,"meta":157,"style":157},"import {defineShader, wgsl, registerShader, …} from 'shaders\u002Fstd'\n",[10,730,731],{"__ignoreMap":157},[161,732,733,735,738,740],{"class":163,"line":164},[161,734,168],{"class":167},[161,736,737],{"class":171}," {defineShader, wgsl, registerShader, …} ",[161,739,175],{"class":167},[161,741,179],{"class":178},[743,744,746],"h2",{"id":745},"reach-for-it-when","Reach for it when",[329,748,749,759],{},[332,750,751],{},[335,752,753,756],{},[338,754,755],{},"When you need",[338,757,758],{},"Use",[348,760,761,772,789,803,826,842,855,872],{},[335,762,763,766],{},[353,764,765],{},"a shader of your own, from a plain object",[353,767,768],{},[144,769,770],{"href":146},[10,771,149],{},[335,773,774,777],{},[353,775,776],{},"per-pixel math you want to write by hand",[353,778,779,783,784,786,787],{},[144,780,781],{"href":513},[10,782,290],{}," in ",[10,785,357],{}," or ",[10,788,370],{},[335,790,791,794],{},[353,792,793],{},"a generator that paints from coordinates",[353,795,796,800,801],{},[144,797,798],{"href":146},[10,799,149],{}," with ",[10,802,357],{},[335,804,805,808],{},[353,806,807],{},"a filter over the layer nested inside",[353,809,810,800,814,816,817,820,821,825],{},[144,811,812],{"href":146},[10,813,149],{},[10,815,370],{}," holding a color word, ",[10,818,819],{},"tintToward",", or a ",[144,822,823],{"href":513},[10,824,290],{}," body that reads child",[335,827,828,831],{},[353,829,830],{},"a filter that reads neighbouring pixels (blur, ripple, mosaic)",[353,832,833,834,838,839],{},"a ",[144,835,836],{"href":513},[10,837,290],{}," body that samples childTexture, or ",[10,840,841],{},"gather",[335,843,844,847],{},[353,845,846],{},"a distortion from one coordinate function",[353,848,849,800,853],{},[144,850,851],{"href":146},[10,852,149],{},[10,854,390],{},[335,856,857,863],{},[353,858,859,860],{},"naming your shader in preset JSON for ",[10,861,862],{},"createShader",[353,864,865,871],{},[144,866,868],{"href":867},"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fregistershader",[10,869,870],{},"registerShader",", or the components option",[335,873,874,877],{},[353,875,876],{},"listing the custom shaders an app has registered",[353,878,879,524,885],{},[144,880,882],{"href":881},"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fgetregisteredshaders",[10,883,884],{},"getRegisteredShaders",[144,886,888],{"href":887},"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fonshaderregistered",[10,889,890],{},"onShaderRegistered",[743,892,894],{"id":893},"example","Example",[152,896,898],{"className":154,"code":897,"language":156,"meta":157,"style":157},"import {defineShader, wgsl, transformColor, transformPosition} from 'shaders\u002Fstd'\n\n\u002F\u002F A generator: concentric color bands radiating from a draggable point, on its own clock.\nexport const Halo = defineShader({\n  name: 'Halo',\n  description: 'Concentric color bands radiating from a point.',\n  animatedTime: {speed: 'speed'},\n  props: {\n    inner: {default: '#ffd166', transform: transformColor, ui: {type: 'color', label: 'Inner'}},\n    outer: {default: '#0b132b', transform: transformColor, ui: {type: 'color', label: 'Outer'}},\n    center: {default: {x: 0.5, y: 0.5}, transform: transformPosition, ui: {type: 'position', label: 'Center'}},\n    radius: {default: 0.6, ui: {type: 'range', min: 0.1, max: 1.5, step: 0.01, label: 'Radius'}},\n    bands: {default: 4, ui: {type: 'range', min: 1, max: 16, step: 1, label: 'Bands'}},\n    speed: {default: 1, ui: {type: 'range', min: 0, max: 4, step: 0.1, label: 'Speed'}},\n  },\n  paint: wgsl`\n    let q = (uv - center) * vec2f(aspect, 1.0);\n    let d = length(q) \u002F radius;\n    let wave = 0.5 + 0.5 * cos(d * bands * 6.2831853 - time * 2.0);\n    let fade = 1.0 - smoothstep(0.7, 1.0, d);\n    return vec4f(mix(outer.rgb, inner.rgb, wave * fade), 1.0);\n  `,\n})\n",[10,899,900,911,915,920,934,942,952,962,967,989,1008,1031,1068,1100,1130,1135,1144,1150,1156,1162,1168,1174,1181],{"__ignoreMap":157},[161,901,902,904,907,909],{"class":163,"line":164},[161,903,168],{"class":167},[161,905,906],{"class":171}," {defineShader, wgsl, transformColor, transformPosition} ",[161,908,175],{"class":167},[161,910,179],{"class":178},[161,912,913],{"class":163,"line":182},[161,914,186],{"emptyLinePlaceholder":185},[161,916,917],{"class":163,"line":189},[161,918,919],{"class":224},"\u002F\u002F A generator: concentric color bands radiating from a draggable point, on its own clock.\n",[161,921,922,924,926,928,930,932],{"class":163,"line":212},[161,923,192],{"class":167},[161,925,195],{"class":167},[161,927,199],{"class":198},[161,929,202],{"class":167},[161,931,206],{"class":205},[161,933,209],{"class":171},[161,935,936,938,940],{"class":163,"line":228},[161,937,215],{"class":171},[161,939,218],{"class":178},[161,941,314],{"class":171},[161,943,944,947,950],{"class":163,"line":237},[161,945,946],{"class":171},"  description: ",[161,948,949],{"class":178},"'Concentric color bands radiating from a point.'",[161,951,314],{"class":171},[161,953,954,957,960],{"class":163,"line":249},[161,955,956],{"class":171},"  animatedTime: {speed: ",[161,958,959],{"class":178},"'speed'",[161,961,275],{"class":171},[161,963,964],{"class":163,"line":266},[161,965,966],{"class":171},"  props: {\n",[161,968,969,972,974,977,980,983,986],{"class":163,"line":278},[161,970,971],{"class":171},"    inner: {default: ",[161,973,243],{"class":178},[161,975,976],{"class":171},", transform: transformColor, ui: {type: ",[161,978,979],{"class":178},"'color'",[161,981,982],{"class":171},", label: ",[161,984,985],{"class":178},"'Inner'",[161,987,988],{"class":171},"}},\n",[161,990,991,994,997,999,1001,1003,1006],{"class":163,"line":284},[161,992,993],{"class":171},"    outer: {default: ",[161,995,996],{"class":178},"'#0b132b'",[161,998,976],{"class":171},[161,1000,979],{"class":178},[161,1002,982],{"class":171},[161,1004,1005],{"class":178},"'Outer'",[161,1007,988],{"class":171},[161,1009,1010,1012,1014,1016,1018,1021,1024,1026,1029],{"class":163,"line":296},[161,1011,252],{"class":171},[161,1013,255],{"class":198},[161,1015,258],{"class":171},[161,1017,255],{"class":198},[161,1019,1020],{"class":171},"}, transform: transformPosition, ui: {type: ",[161,1022,1023],{"class":178},"'position'",[161,1025,982],{"class":171},[161,1027,1028],{"class":178},"'Center'",[161,1030,988],{"class":171},[161,1032,1033,1035,1037,1040,1043,1046,1049,1052,1055,1058,1061,1063,1066],{"class":163,"line":302},[161,1034,269],{"class":171},[161,1036,272],{"class":198},[161,1038,1039],{"class":171},", ui: {type: ",[161,1041,1042],{"class":178},"'range'",[161,1044,1045],{"class":171},", min: ",[161,1047,1048],{"class":198},"0.1",[161,1050,1051],{"class":171},", max: ",[161,1053,1054],{"class":198},"1.5",[161,1056,1057],{"class":171},", step: ",[161,1059,1060],{"class":198},"0.01",[161,1062,982],{"class":171},[161,1064,1065],{"class":178},"'Radius'",[161,1067,988],{"class":171},[161,1069,1070,1073,1076,1078,1080,1082,1084,1086,1089,1091,1093,1095,1098],{"class":163,"line":308},[161,1071,1072],{"class":171},"    bands: {default: ",[161,1074,1075],{"class":198},"4",[161,1077,1039],{"class":171},[161,1079,1042],{"class":178},[161,1081,1045],{"class":171},[161,1083,464],{"class":198},[161,1085,1051],{"class":171},[161,1087,1088],{"class":198},"16",[161,1090,1057],{"class":171},[161,1092,464],{"class":198},[161,1094,982],{"class":171},[161,1096,1097],{"class":178},"'Bands'",[161,1099,988],{"class":171},[161,1101,1102,1105,1107,1109,1111,1113,1115,1117,1119,1121,1123,1125,1128],{"class":163,"line":317},[161,1103,1104],{"class":171},"    speed: {default: ",[161,1106,464],{"class":198},[161,1108,1039],{"class":171},[161,1110,1042],{"class":178},[161,1112,1045],{"class":171},[161,1114,470],{"class":198},[161,1116,1051],{"class":171},[161,1118,1075],{"class":198},[161,1120,1057],{"class":171},[161,1122,1048],{"class":198},[161,1124,982],{"class":171},[161,1126,1127],{"class":178},"'Speed'",[161,1129,988],{"class":171},[161,1131,1133],{"class":163,"line":1132},15,[161,1134,281],{"class":171},[161,1136,1138,1140,1142],{"class":163,"line":1137},16,[161,1139,287],{"class":171},[161,1141,290],{"class":205},[161,1143,554],{"class":178},[161,1145,1147],{"class":163,"line":1146},17,[161,1148,1149],{"class":178},"    let q = (uv - center) * vec2f(aspect, 1.0);\n",[161,1151,1153],{"class":163,"line":1152},18,[161,1154,1155],{"class":178},"    let d = length(q) \u002F radius;\n",[161,1157,1159],{"class":163,"line":1158},19,[161,1160,1161],{"class":178},"    let wave = 0.5 + 0.5 * cos(d * bands * 6.2831853 - time * 2.0);\n",[161,1163,1165],{"class":163,"line":1164},20,[161,1166,1167],{"class":178},"    let fade = 1.0 - smoothstep(0.7, 1.0, d);\n",[161,1169,1171],{"class":163,"line":1170},21,[161,1172,1173],{"class":178},"    return vec4f(mix(outer.rgb, inner.rgb, wave * fade), 1.0);\n",[161,1175,1177,1179],{"class":163,"line":1176},22,[161,1178,311],{"class":178},[161,1180,314],{"class":171},[161,1182,1184],{"class":163,"line":1183},23,[161,1185,320],{"class":171},[743,1187,1189],{"id":1188},"types","Types",[329,1191,1192,1202],{},[332,1193,1194],{},[335,1195,1196,1199],{},[338,1197,1198],{},"Type",[338,1200,1201],{},"What it is",[348,1203,1204,1214,1224,1246,1267,1285,1303,1316,1345,1370,1383,1406,1432,1448,1461,1474,1497,1512,1541,1554],{},[335,1205,1206,1211],{},[353,1207,1208],{},[10,1209,1210],{},"DisplaceByEffectRef",[353,1212,1213],{},"A filter that moves the layer inside by a simulation's vector field.",[335,1215,1216,1221],{},[353,1217,1218],{},[10,1219,1220],{},"GatherEffect",[353,1222,1223],{},"A filter that reads the layer inside anywhere, not just at this pixel: blurs, halftones, displacements.",[335,1225,1226,1231],{},[353,1227,1228],{},[10,1229,1230],{},"IdentityRule",[353,1232,1233,1234,524,1237,524,1240,786,1243,606],{},"When a filter does nothing and can be skipped: built with ",[10,1235,1236],{},"isZero",[10,1238,1239],{},"isValue",[10,1241,1242],{},"allOf",[10,1244,1245],{},"identityWhenever",[335,1247,1248,1253],{},[353,1249,1250],{},[10,1251,1252],{},"PointwiseEffect",[353,1254,1255,1256,524,1259,1262,1263,1266],{},"A filter that edits the layer inside one pixel at a time: what the color words (",[10,1257,1258],{},"saturate",[10,1260,1261],{},"hueRotate",", …) and ",[10,1264,1265],{},"pointwise({build})"," return.",[335,1268,1269,1274],{},[353,1270,1271],{},[10,1272,1273],{},"RecompileRule",[353,1275,1276,1277,1280,1281,1284],{},"When a prop change rebuilds the shader: ",[10,1278,1279],{},"crosses(value)"," at a threshold, or ",[10,1282,1283],{},"recompileWhen(fn)"," by your own test.",[335,1286,1287,1292],{},[353,1288,1289],{},[10,1290,1291],{},"StdCustomDefinition",[353,1293,1294,1295,1298,1299,1302],{},"A raw builder: ",[10,1296,1297],{},"gpu:"," holds a fragment function (and optionally a ",[10,1300,1301],{},"uvRemap",") for effects the words cannot say yet.",[335,1304,1305,1310],{},[353,1306,1307],{},[10,1308,1309],{},"StdDefinition",[353,1311,1312,1313,1315],{},"What ",[10,1314,149],{}," accepts: one of the definition shapes, told apart by which field carries the per-pixel work.",[335,1317,1318,1323],{},[353,1319,1320],{},[10,1321,1322],{},"StdDefinitionBase",[353,1324,1325,1326,524,1329,1332,1333,1336,1337,1340,1341,1344],{},"The fields every definition shares: ",[10,1327,1328],{},"name",[10,1330,1331],{},"props",", optional ",[10,1334,1335],{},"description"," and ",[10,1338,1339],{},"category",", the ",[10,1342,1343],{},"animatedTime"," clock, and engine flags.",[335,1346,1347,1352],{},[353,1348,1349],{},[10,1350,1351],{},"StdGatherFilterDefinition",[353,1353,1354,1355,1357,1358,524,1361,1364,1365,1367,1368,606],{},"A filter that reads the layer inside anywhere: ",[10,1356,370],{}," holds ",[10,1359,1360],{},"gather({…})",[10,1362,1363],{},"displaceBy(…)"," or a ",[10,1366,290],{}," body that samples ",[10,1369,383],{},[335,1371,1372,1377],{},[353,1373,1374],{},[10,1375,1376],{},"StdGeneratorDefinition",[353,1378,1379,1380,1382],{},"A generator: ",[10,1381,357],{}," produces a color from coordinates and needs nothing nested inside.",[335,1384,1385,1390],{},[353,1386,1387],{},[10,1388,1389],{},"StdPointwiseFilterDefinition",[353,1391,1392,1393,1395,1396,524,1398,1364,1401,1403,1404,606],{},"A filter that edits the layer inside one pixel at a time: ",[10,1394,370],{}," holds a color word, ",[10,1397,819],{},[10,1399,1400],{},"pointwise({…})",[10,1402,290],{}," body that reads ",[10,1405,379],{},[335,1407,1408,1413],{},[353,1409,1410],{},[10,1411,1412],{},"StdPropConfig",[353,1414,1415,1416,1332,1418,524,1420,524,1422,524,1424,1427,1428,1431],{},"One prop of a definition: ",[10,1417,572],{},[10,1419,576],{},[10,1421,587],{},[10,1423,1335],{},[10,1425,1426],{},"compileTime",", and a ",[10,1429,1430],{},"recompile:"," rule.",[335,1433,1434,1439],{},[353,1435,1436],{},[10,1437,1438],{},"StdProps",[353,1440,1441,1442,1444,1445,1447],{},"The ",[10,1443,1331],{}," object of a definition: one ",[10,1446,1412],{}," per prop name.",[335,1449,1450,1455],{},[353,1451,1452],{},[10,1453,1454],{},"StdShapeDefinition",[353,1456,1457,1458,1460],{},"A 2D shape: ",[10,1459,403],{}," gives the distance function and the shape's own props; fill, stroke, softness and bounds come for free.",[335,1462,1463,1468],{},[353,1464,1465],{},[10,1466,1467],{},"StdWarpDefinition",[353,1469,1470,1471,1473],{},"A distortion: ",[10,1472,390],{}," is one function from the pixel's coordinate to where in the layer inside to read.",[335,1475,1476,1481],{},[353,1477,1478],{},[10,1479,1480],{},"StdWgslFilterDefinition",[353,1482,1483,1484,1486,1487,1489,1490,1493,1494,1496],{},"A filter whose ",[10,1485,370],{}," is a ",[10,1488,290],{}," body with no ",[10,1491,1492],{},"species"," declared: gather when the body samples ",[10,1495,383],{},", pointwise otherwise.",[335,1498,1499,1504],{},[353,1500,1501],{},[10,1502,1503],{},"WgslHost",[353,1505,1506,1507,1509,1510,606],{},"Where a body runs: a generator's ",[10,1508,357],{},", or a pointwise or gather filter's ",[10,1511,370],{},[335,1513,1514,1519],{},[353,1515,1516],{},[10,1517,1518],{},"WgslInput",[353,1520,1521,1522,1525,1526,1529,1530,1533,1534,1537,1538,606],{},"One entry of ",[10,1523,1524],{},"inputs",": the value to bind under a name — a prop ",[10,1527,1528],{},"p('x')",", a context token ",[10,1531,1532],{},"ctx.time",", a ",[10,1535,1536],{},"Scalar",", or a number — optionally with its WGSL type spelled out as ",[10,1539,1540],{},"{value, type}",[335,1542,1543,1548],{},[353,1544,1545],{},[10,1546,1547],{},"WgslSpec",[353,1549,1550,1551,606],{},"The long form of a body: ",[10,1552,1553],{},"wgsl({body, inputs, alpha, name})",[335,1555,1556,1561],{},[353,1557,1558],{},[10,1559,1560],{},"WgslType",[353,1562,1563],{},"The WGSL types a bound name can have inside a body.",[743,1565,1567],{"id":1566},"words","Words",[1569,1570,1572],"primitive-words",{":words":1571},"[{\"name\":\"defineShader\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fdefineshader\",\"summary\":\"Define a shader component from a plain object: its props, and one field that says what it draws.\"},{\"name\":\"wgsl\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fwgsl\",\"summary\":\"Write the per-pixel math by hand, as one WGSL function body that returns a `vec4f` color.\"},{\"name\":\"registerShader\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fregistershader\",\"summary\":\"Make a user-defined shader findable by its `name`, so preset JSON can reference it as `type: 'Halo'`.\"},{\"name\":\"unregisterShader\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Funregistershader\",\"summary\":\"Forget a user-defined shader by name.\"},{\"name\":\"getRegisteredShader\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fgetregisteredshader\",\"summary\":\"Look up a user-defined shader by name.\"},{\"name\":\"getRegisteredShaders\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fgetregisteredshaders\",\"summary\":\"Every user-defined shader currently registered, oldest first.\"},{\"name\":\"onShaderRegistered\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fonshaderregistered\",\"summary\":\"Be told when a user-defined shader is registered, replaced or removed.\"},{\"name\":\"WgslBody\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fwgslbody\",\"summary\":\"What `wgsl` returns: a body ready to sit in `paint:` or `effect:`.\"}]",[1573,1574,1575,1583,1593,1605,1614,1623,1630,1637],"ul",{},[1576,1577,1578,1582],"li",{},[144,1579,1580],{"href":146},[10,1581,149],{}," — Define a shader component from a plain object: its props, and one field that says what it draws.",[1576,1584,1585,1589,1590,1592],{},[144,1586,1587],{"href":513},[10,1588,290],{}," — Write the per-pixel math by hand, as one WGSL function body that returns a ",[10,1591,519],{}," color.",[1576,1594,1595,1599,1600,1602,1603,606],{},[144,1596,1597],{"href":867},[10,1598,870],{}," — Make a user-defined shader findable by its ",[10,1601,1328],{},", so preset JSON can reference it as ",[10,1604,605],{},[1576,1606,1607,1613],{},[144,1608,1610],{"href":1609},"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Funregistershader",[10,1611,1612],{},"unregisterShader"," — Forget a user-defined shader by name.",[1576,1615,1616,1622],{},[144,1617,1619],{"href":1618},"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fgetregisteredshader",[10,1620,1621],{},"getRegisteredShader"," — Look up a user-defined shader by name.",[1576,1624,1625,1629],{},[144,1626,1627],{"href":881},[10,1628,884],{}," — Every user-defined shader currently registered, oldest first.",[1576,1631,1632,1636],{},[144,1633,1634],{"href":887},[10,1635,890],{}," — Be told when a user-defined shader is registered, replaced or removed.",[1576,1638,1639,1645,1646,1648,1649,786,1651,606],{},[144,1640,1642],{"href":1641},"\u002Fdocs\u002Fprimitives\u002Fdefine\u002Fwgslbody",[10,1643,1644],{},"WgslBody"," — What ",[10,1647,290],{}," returns: a body ready to sit in ",[10,1650,357],{},[10,1652,370],{},[1654,1655,1656],"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 pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}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);}",{"title":157,"searchDepth":182,"depth":182,"links":1658},[1659,1660,1661,1662],{"id":745,"depth":182,"text":746},{"id":893,"depth":182,"text":894},{"id":1188,"depth":182,"text":1189},{"id":1566,"depth":182,"text":1567},"define",null,"A shader is a plain object: a name, the props a user can set, and one field that says what it draws.","https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fedit\u002Fmain\u002Fpackages\u002Fcore\u002Fdocs\u002Fstd\u002Fdefine.md","md","Defining a shader",{},"\u002Fdocs\u002Fprimitives\u002Fdefine",{"title":131,"description":1665},"https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fblob\u002Fmain\u002Fpackages\u002Fcore\u002Fsrc\u002Fstd\u002Flower.ts","docs\u002Fprimitives\u002F1.define\u002Findex","Aq6qh7PFZqQdXTXtiIql7ANtg2ARKkpMNRdobQH_FNs"]