@react-three/gpu-pathtracer
Version:
⚡️ A React abstraction for the popular three-gpu-pathtracer.
128 lines (127 loc) • 4.21 kB
JavaScript
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