UNPKG

lamina

Version:

🍰 An extensable, layer based shader material for ThreeJS.

232 lines (231 loc) 7.43 kB
import { jsx as u, jsxs as A, Fragment as G } from "react/jsx-runtime"; import { extend as D } from "@react-three/fiber"; import s, { useImperativeHandle as E, useMemo as w } from "react"; import { createRoot as B } from "react-dom/client"; import { useCreateStore as H, useControls as x, button as C, LevaPanel as U } from "leva"; import { TextureLoader as I, Color as V } from "three"; import { L as O, a as T, S as X, g as P, b as q, N as Y, D as K, T as Q, M as W, G as Z, F as k, c as p, C as ee, d as te } from "./vanilla-BEVDQrzM.js"; function N(e) { const t = O[e.constructor], l = new t(); let r = ""; return Object.entries(e.properties).forEach(([n, a]) => { const i = t["u_" + n] ?? l[n]; switch (n) { case "name": a !== e.constructor && (r += ` ${n}={${JSON.stringify(a)}}`); break; case "visible": a || (r += ` ${n}={${JSON.stringify(a)}}`); break; default: a !== i && (r += ` ${n}={${JSON.stringify(a)}}`); break; } }), r; } function re(e, t) { return ` <LayerMaterial${N(t)}> ${e.map((n) => { const a = N(n); return `<${n.constructor}${a} />`; }).join(` `)} </LayerMaterial> `; } function J(e) { const t = O[e.constructor], l = new t(); let r = " "; return Object.entries(e.properties).forEach(([a, i], d) => { var L; const g = ` `; if (a.includes("color")) { const $ = typeof i == "string" ? i : "#" + i.getHexString(); r += `${a}: ${JSON.stringify($)},${g}`; } else { const $ = (L = t["u_" + a]) != null ? L : l[a]; switch (a) { case "name": i !== e.constructor && (r += `${a}: ${JSON.stringify(i)},${g}`); break; case "visible": i || (r += `${a}:${JSON.stringify(i)},${g}`); break; default: i !== $ && (r += `${a}: ${JSON.stringify(i)},${g}`); break; } } }), r; } function ae(e, t) { const l = J(t), r = `${e.map((a) => `new ${a.constructor}({ ${J(a)} })`).join(`, `)}`; return ` new LayerMaterial({ ${l} layers: [ ${r} ] })`; } D({ LayerMaterial: T }); function ne({ name: e, layers: t, store: l, setUpdate: r }) { return x( e, () => { const n = {}; return t.forEach((a, i) => { const d = `${a.label} ~${i}`; n[d] = a, n[d].onChange = () => r([`${e}.${d}`, a.label]); }), n; }, { store: l }, [t, e] ), null; } const de = s.forwardRef(({ children: e, ...t }, l) => { var j, v, M; const r = s.useRef(null); E(l, () => r.current); const n = H(), [a, i] = s.useState({}), [d, L] = s.useState(["", ""]), g = w(() => new I(), []); x( { "Copy JSX": C(() => { const c = r.current.layers.map((f) => f.serialize()), o = re(c, r.current.serialize()); navigator.clipboard.writeText(o); }), "Copy JS": C(() => { const c = r.current.layers.map((f) => f.serialize()), o = ae(c, r.current.serialize()); navigator.clipboard.writeText(o); }) }, { store: n } ); const { Lighting: $ } = x( "Base", { Color: { value: "#" + new V(((j = r.current) == null ? void 0 : j.color) || (t == null ? void 0 : t.color) || "white").convertLinearToSRGB().getHexString(), onChange: (c) => { r.current.color = c; } }, Alpha: { value: ((v = r.current) == null ? void 0 : v.alpha) || (t == null ? void 0 : t.alpha) || 1, min: 0, max: 1, onChange: (c) => { r.current.alpha = c; } }, Lighting: { value: ((M = r.current) == null ? void 0 : M.lighting) || (t == null ? void 0 : t.lighting) || "basic", options: Object.keys(X) } }, { store: n } ), [R, z] = w(() => P({ ...t, lighting: $ }), [t, $]); return s.useEffect(() => { const c = r.current.layers, o = {}; c.forEach((f, _) => { f.getSchema && (o[`${f.name} ~${_}`] = f.getSchema()); }), i(o); }, [e]), s.useEffect(() => { const o = n.getData()[d[0]]; if (o) { const f = d[0].split("."), _ = parseInt(f[0].split(" ~")[1]), h = d[1], F = r.current.layers[_].uuid, b = r.current.uniforms[`u_${F}_${h}`], y = r.current.layers[_]; h !== "map" ? (y[h] = o.value, b ? b.value = q(o.value) : (y.buildShaders(y.constructor), r.current.refresh())) : (async () => { try { if (o.value) { const S = await g.loadAsync(o.value); y[h] = S, b.value = S; } else y[h] = void 0, b.value = void 0; } catch (S) { console.error(S); } })(); } }, [d]), s.useLayoutEffect(() => { var c; r.current.layers = (c = r.current.__r3f.children) == null ? void 0 : c.map((o) => o.object), r.current.refresh(); }, [e, R]), s.useLayoutEffect(() => { const c = document.body.querySelector("#root"), o = document.createElement("div"); return c && (c.appendChild(o), B(o).render( /* @__PURE__ */ u( U, { titleBar: { title: t.name || r.current.name }, store: n } ) )), () => { o.remove(); }; }, [t.name]), /* @__PURE__ */ A(G, { children: [ Object.entries(a).map(([c, o], f) => /* @__PURE__ */ u(ne, { name: c, layers: o, store: n, setUpdate: L }, `${c} ~${f}`)), /* @__PURE__ */ u("layerMaterial", { args: [R], ref: r, ...z, children: e }) ] }); }); D({ LayerMaterial: T, Depth_: te, Color_: ee, Noise_: p, Fresnel_: k, Gradient_: Z, Matcap_: W, Texture_: Q, Displace_: K, Normal_: Y }); const me = s.forwardRef(({ children: e, ...t }, l) => { const r = s.useRef(null); E(l, () => r.current), s.useLayoutEffect(() => { var i; r.current.layers = (i = r.current.__r3f.children) == null ? void 0 : i.map((d) => d.object), r.current.refresh(); }, [e]); const [n, a] = w(() => P(t), [t]); return /* @__PURE__ */ u("layerMaterial", { args: [n], ref: r, ...a, children: e }); }); function m(e) { return [ { mode: e == null ? void 0 : e.mode, visible: e == null ? void 0 : e.visible, type: e == null ? void 0 : e.type, mapping: e == null ? void 0 : e.mapping, map: e == null ? void 0 : e.map, axes: e == null ? void 0 : e.axes } ]; } const ge = s.forwardRef((e, t) => /* @__PURE__ */ u("depth_", { args: m(e), ref: t, ...e })), $e = s.forwardRef((e, t) => /* @__PURE__ */ u("color_", { ref: t, args: m(e), ...e })), he = s.forwardRef((e, t) => /* @__PURE__ */ u("noise_", { ref: t, args: m(e), ...e })), ye = s.forwardRef((e, t) => /* @__PURE__ */ u("fresnel_", { ref: t, args: m(e), ...e })), Le = s.forwardRef((e, t) => /* @__PURE__ */ u("gradient_", { ref: t, args: m(e), ...e })), _e = s.forwardRef((e, t) => /* @__PURE__ */ u("matcap_", { ref: t, args: m(e), ...e })), be = s.forwardRef((e, t) => /* @__PURE__ */ u("texture_", { ref: t, args: m(e), ...e })), Se = s.forwardRef((e, t) => /* @__PURE__ */ u("displace_", { ref: t, args: m(e), ...e })), we = s.forwardRef((e, t) => /* @__PURE__ */ u("normal_", { ref: t, args: m(e), ...e })); export { $e as Color, de as DebugLayerMaterial, ge as Depth, Se as Displace, ye as Fresnel, Le as Gradient, me as LayerMaterial, _e as Matcap, he as Noise, we as Normal, be as Texture }; //# sourceMappingURL=lamina.es.js.map