UNPKG

@react-three/gpu-pathtracer

Version:

⚡️ A React abstraction for the popular three-gpu-pathtracer.

128 lines (127 loc) 4.21 kB
import { jsx as h } from "react/jsx-runtime"; import { useThree as p, applyProps as j, useFrame as T, extend as f } from "@react-three/fiber"; import r, { useMemo as G, useEffect as d, useRef as H, useLayoutEffect as y } from "react"; import { WebGLPathTracer as W, FogVolumeMaterial as k, PhysicalCamera as q, PhysicalSpotLight as B, ShapedAreaLight as D } from "three-gpu-pathtracer"; import { FogVolumeMaterial as te, PhysicalCamera as ae, PhysicalSpotLight as re, ShapedAreaLight as se } from "three-gpu-pathtracer"; import "three"; const S = r.createContext(null), U = r.forwardRef( ({ children: t, enabled: a = !0, minSamples: c = 1, samples: L = 32, bounces: n = 4, resolutionFactor: s = 1, renderPriority: i = 1, filteredGlossyFactor: C = 0, renderDelay: M = 0, fadeDuration: v = 0, dynamicLowRes: x = !0, lowResScale: E = 0.25, textureSize: A = [1024, 1024], rasterizeScene: V = !1, tiles: w = [3, 3], ...F }, I) => { const { gl: P, camera: l, scene: m, controls: u } = p(), e = G(() => { const o = new W(P); return o.synchronizeRenderSize = !0, o; }, [P]); r.useImperativeHandle(I, () => e, [e]), r.useLayoutEffect(() => { j(e, { bounces: n, filteredGlossyFactor: C, renderDelay: M, fadeDuration: v, minSamples: c, dynamicLowRes: x, lowResScale: E, rasterizeScene: V, textureSize: A, tiles: w }), e.renderScale = s, e.reset(); }, [F, s, n, c, e]), r.useEffect(() => { a && e.reset(); }, [a]); const R = r.useMemo( () => ({ /** * Update the pathtracer scene. Call this after adding or removing objects from the scene */ update: () => { e.setScene(m, l); }, /** * Reset the pathtracer. Call this after changing any pathtracing properties */ reset: () => { e.reset(); }, /** * @deprecated Use `pathtracer` instead */ renderer: e, pathtracer: e // Use this instead. Keeps base three renderer seperate mentally }), [e, m, l] ); return r.useLayoutEffect(() => { e.setScene(m, l); }, [m, l]), r.useLayoutEffect(() => { const o = () => { e.updateCamera(); }; return u && u.addEventListener("change", o), () => { u && u.removeEventListener("change", o); }; }, [u, e]), T(({ camera: o, gl: z, scene: $ }) => { a && e.samples < (L ?? 1 / 0) && e.renderSample(), a || z.render($, o); }, 1), /* @__PURE__ */ h(S.Provider, { value: R, children: t }); } ); function g() { const t = r.useContext(S); if (!t) throw new Error("usePathtracer must be used within a Pathtracer"); return t; } function X(t) { f({ FogVolumeMaterial: k }); const { pathtracer: a } = g(); return d(() => void a.updateMaterials()), /* @__PURE__ */ h("fogVolumeMaterial", { ...t }); } function Y(t) { f({ PhysicalCamera: q }); const { pathtracer: a } = g(), c = p(({ set: i }) => i), L = p(({ camera: i }) => i), n = p(({ size: i }) => i), s = H(null); return y(() => { t.manual || (s.current.aspect = n.width / n.height); }, [n, t]), y(() => { s.current.updateProjectionMatrix(); }), y(() => { const i = L; return c(() => ({ camera: s.current })), () => c(() => ({ camera: i })); }, [s, c]), d(() => void a.updateCamera()), /* @__PURE__ */ h("physicalCamera", { ref: s, ...t }); } function Z(t) { f({ PhysicalSpotLight: B }); const { pathtracer: a } = g(); return d(() => void a.updateLights()), /* @__PURE__ */ h("physicalSpotLight", { ...t }); } function _(t) { f({ ShapedAreaLight: D }); const { pathtracer: a } = g(); return d(() => void a.updateLights()), /* @__PURE__ */ h("shapedAreaLight", { ...t }); } export { X as FogVolumeMaterial, te as FogVolumeMaterialImpl, U as Pathtracer, Y as PhysicalCamera, ae as PhysicalCameraImpl, Z as PhysicalSpotLight, re as PhysicalSpotLightImpl, _ as ShapedAreaLight, se as ShapedAreaLightImpl, g as usePathtracer }; //# sourceMappingURL=react-three-gpu-pathtracer.es.js.map