@threlte/extras
Version:
Utilities, abstractions and plugins for your Threlte apps
46 lines (45 loc) • 1.87 kB
JavaScript
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;
}