1import T from"./5yasBeiv.js";import{d as P,k as R,o as G,c as O,y as d,z as v,A as e,F as n,C as f,B as p,I as U,J as D,R as S,as as L,at as N,au as B,H as E,E as c,g as u}from"./W0D3MKqO.js";import{c as I}from"./BJB7AVyl.js";import{a as F}from"./Ce9hhj85.js";import{_ as H}from"./DlAUqK2U.js";const M={class:"wgsl-studio"},z={key:0,class:"not-supported"},$=["href"],j={key:1,class:"studio-grid"},A={class:"editor-panel"},J={class:"panel-bar"},Y={class:"presets"},q=["onClick"],K={class:"editor-actions"},Q={key:0,class:"error-box"},X={class:"preview-panel"},Z={class:"preview-wrap"},ee={class:"preview-meta"},te={class:"gpu-name"},ne="Try Chrome 113+, Edge 113+, or a browser with WebGPU enabled. The Shader Studio builder works everywhere.",oe=P({__name:"WgslStudioScene.client",setup(se){const{studioLink:x}=F(),C=R(()=>x("webgpu-unsupported").value),m=[{id:"plasma",name:"Plasma",code:`@fragment 2fn fs(in: VOut) -> @location(0) vec4f { 3 let uv = in.uv; 4 let t = u.time; 5 var v = sin(uv.x * 12.0 + t); 6 v += sin((uv.y * 9.0 + t) * 1.3); 7 v += sin((uv.x + uv.y) * 8.0 + t * 0.7); 8 v += sin(length(uv - 0.5) * 18.0 - t * 2.0); 9 v *= 0.25; 10 let c = 0.5 + 0.5 * cos(vec3f(v * 6.28, v * 6.28 + 2.0, v * 6.28 + 4.0) + vec3f(0.0, 0.6, 1.2)); 11 return vec4f(c, 1.0); 12}`},{id:"ripple",name:"Ripple",code:`@fragment 13fn fs(in: VOut) -> @location(0) vec4f { 14 let uv = in.uv * 2.0 - 1.0; 15 let r = length(uv); 16 let a = atan2(uv.y, uv.x); 17 let wave = sin(r * 30.0 - u.time * 3.0) * 0.5 + 0.5; 18 let ring = smoothstep(0.02, 0.0, abs(r - 0.7)); 19 let base = vec3f(0.05, 0.18, 0.22); 20 let col = base + wave * vec3f(0.2, 0.7, 0.9) + ring * vec3f(0.9, 0.4, 0.2); 21 return vec4f(col, 1.0); 22}`},{id:"voronoi",name:"Voronoi",code:`@fragment 23fn fs(in: VOut) -> @location(0) vec4f { 24 let uv = in.uv * 8.0; 25 var minD = 8.0; 26 var cell = vec2f(0.0); 27 for (var y = -1; y <= 1; y = y + 1) { 28 for (var x = -1; x <= 1; x = x + 1) { 29 let g = vec2f(f32(x), f32(y)); 30 let p = g + fract(sin((floor(uv) + g) * vec2f(12.9898, 78.233)) * 43.0); 31 let d = length(fract(uv) - p + 0.5); 32 if (d < minD) { minD = d; cell = floor(uv) + g; } 33 } 34 } 35 let n = fract(sin(dot(cell, vec2f(12.9898, 78.233))) * 43.0); 36 let col = 0.4 + 0.6 * cos(vec3f(n, n + 0.33, n + 0.66) * 6.28 + u.time); 37 return vec4f(col * (0.4 + minD), 1.0); 38}`},{id:"field",name:"Mouse Field",code:`@fragment 39fn fs(in: VOut) -> @location(0) vec4f { 40 let uv = in.uv; 41 let d = distance(uv, u.mouse); 42 let pulse = sin(d * 40.0 - u.time * 4.0) * 0.5 + 0.5; 43 let glow = smoothstep(0.5, 0.0, d) * 0.6; 44 let bg = mix(vec3f(0.05, 0.1, 0.2), vec3f(0.6, 0.9, 0.3), pulse * 0.3); 45 let col = bg + glow * vec3f(0.3, 0.9, 0.5); 46 return vec4f(col, 1.0); 47}`}],g=u("plasma"),o=u(m[0].code),l=u(""),h=u(!1),w=u("WebGPU"),_=u(null),y=typeof navigator<"u"&&!!navigator.gpu;let i=null,b=null;function W(){clearTimeout(b),b=setTimeout(()=>i?.setSource(o.value),250)}function k(s){const t=m.find(r=>r.id===s);t&&(g.value=s,o.value=t.code,l.value="",i?.setSource(t.code))}async function V(){try{await navigator.clipboard.writeText(o.value),h.value=!0,setTimeout(()=>h.value=!1,1200)}catch{}}return G(async()=>{!y||!_.value||(i=I(_.value,{onError:s=>{l.value=s},onReady:s=>{w.value=s.gpu}}),i.setSource(o.value),await i.start())}),O(()=>{clearTimeout(b),i?.stop()}),(s,t)=>{const r=T;return d(),v("div",M,[t[5]||(t[5]=e("header",{class:"scene-header"},[e("h1",{class:"title"},"WGSL Studio"),e("p",{class:"subtitle"},"Write WGSL. See it render. Now."),e("p",{class:"description"}," Edit a WebGPU fragment shader and watch it render live. Pick a preset, tweak the code, and when the idea works, build the finished look in Shader Studio. ")],-1)),n(y)?(d(),v("div",j,[e("section",A,[e("div",J,[e("div",Y,[(d(),v(U,null,D(m,a=>e("button",{key:a.id,class:S(["preset-btn",{active:n(g)===a.id}]),onClick:ae=>k(a.id)},p(a.name),11,q)),64))]),e("div",K,[e("button",{class:"icon-btn",title:"Copy WGSL",onClick:V},[f(r,{name:n(h)?"ph:check":"ph:clipboard"},null,8,["name"])]),e("button",{class:"icon-btn",title:"Reset preset",onClick:t[0]||(t[0]=a=>k(n(g)))},[f(r,{name:"ph:arrow-counter-clockwise"})])])]),L(e("textarea",{"onUpdate:modelValue":t[1]||(t[1]=a=>B(o)?o.value=a:null),class:"code-editor",spellcheck:"false",onInput:W},null,544),[[N,n(o)]]),n(l)?(d(),v("div",Q,[f(r,{name:"ph:x-circle",class:"error-icon"}),e("pre",null,p(n(l)),1)])):E("",!0)]),e("section",X,[e("div",Z,[e("canvas",{ref_key:"canvasRef",ref:_,class:"preview-canvas"},null,512),e("div",ee,[e("span",{class:S(["meta-dot",{live:!n(l)}])},null,2),e("span",null,p(n(l)?"compile error":"rendering"),1),t[3]||(t[3]=e("span",{class:"spacer"},null,-1)),e("span",te,p(n(w)),1)])]),t[4]||(t[4]=e("p",{class:"hint"},[c(" Uniforms available in your shader: "),e("code",null,"u.time"),c(", "),e("code",null,"u.res"),c(", "),e("code",null,"u.mouse"),c(". Your entry point is "),e("code",null,"@fragment fn fs"),c(" receiving "),e("code",null,"in.uv"),c(". ")],-1))])])):(d(),v("div",z,[f(r,{name:"ph:warning-duotone",class:"warn-icon"}),t[2]||(t[2]=e("h2",null,"WebGPU not available",-1)),e("p",null,p(ne)),e("a",{class:"link",href:n(C),target:"_blank",rel:"noopener noreferrer"},"Open Shader Studio instead",8,$)]))])}}}),de=Object.assign(H(oe,[["__scopeId","data-v-b4c11e78"]]),{__name:"ScenesWgslStudioScene"});export{de as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.