UNPKG

@threlte/extras

Version:

Utilities, abstractions and plugins for your Threlte apps

46 lines (45 loc) 1.87 kB
import { DepthTexture, WebGLRenderTarget } from 'three'; import { isInstanceOf, useThrelte } from '@threlte/core'; import { fromStore } from 'svelte/store'; import { untrack } from 'svelte'; const isGetter = (value) => typeof value === 'function'; export function useFBO(optionsArg) { const { dpr: dprStore, size: sizeStore } = useThrelte(); const dpr = fromStore(dprStore); const size = fromStore(sizeStore); const getOptions = isGetter(optionsArg) ? () => optionsArg() ?? {} : () => optionsArg ?? {}; const { depth, size: userSize, ...targetOptions } = $derived(getOptions()); const width = $derived(userSize ? Math.max(userSize.width ?? 1, 1) : dpr.current * size.current.width); const height = $derived(userSize ? Math.max(userSize.height ?? 1, 1) : dpr.current * size.current.height); const target = new WebGLRenderTarget(untrack(() => width), untrack(() => height), untrack(() => targetOptions)); $effect(() => { target.setSize(width, height); }); $effect(() => { if (depth === true) { const created = new DepthTexture(target.width, target.height); target.depthTexture = created; return () => created.dispose(); } if (isInstanceOf(depth, 'DepthTexture')) { target.depthTexture = depth; return; } if (depth !== false && depth !== undefined) { const width = Math.max(depth.width ?? 1, 1); const height = Math.max(depth.height ?? 1, 1); const created = new DepthTexture(width, height); target.depthTexture = created; return () => created.dispose(); } target.depthTexture = null; return; }); $effect(() => { const current = target; return () => current.dispose(); }); return target; }