Skip to content

Commit 6160a2e

Browse files
committed
fix(soba): make fbo return a Signal instead of NgtInjectedRef
1 parent ce60420 commit 6160a2e

File tree

7 files changed

+65
-48
lines changed

7 files changed

+65
-48
lines changed

libs/soba/cameras/src/camera/camera.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export abstract class NgtsCamera<TCamera extends NgtCamera> {
4444
private cameraResolution = this.inputs.select('resolution');
4545

4646
protected store = injectNgtStore();
47-
protected fboRef = injectNgtsFBO(() => ({ width: this.cameraResolution() }));
47+
protected fbo = injectNgtsFBO(() => ({ width: this.cameraResolution() }));
4848

4949
constructor() {
5050
this.setDefaultCamera();

libs/soba/cameras/src/orthographic-camera/orthographic-camera.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ declare global {
4141
/>
4242
</ngt-orthographic-camera>
4343
<ngt-group #group *ngIf="cameraContent && cameraContent.ngtsCameraContent">
44-
<ng-container *ngTemplateOutlet="cameraContent.template; context: { fbo: fboRef.nativeElement, group }" />
44+
<ng-container *ngTemplateOutlet="cameraContent.template; context: { fbo: fbo(), group }" />
4545
</ngt-group>
4646
`,
4747
imports: [NgIf, NgTemplateOutlet],

libs/soba/cameras/src/perspective-camera/perspective-camera.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ declare global {
2727
/>
2828
</ngt-perspective-camera>
2929
<ngt-group #group *ngIf="cameraContent && cameraContent.ngtsCameraContent">
30-
<ng-container *ngTemplateOutlet="cameraContent.template; context: { fbo: fboRef.nativeElement, group }" />
30+
<ng-container *ngTemplateOutlet="cameraContent.template; context: { fbo: fbo(), group }" />
3131
</ngt-group>
3232
`,
3333
imports: [NgIf, NgTemplateOutlet],

libs/soba/materials/src/mesh-transmission-material/mesh-transmission-material.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ declare global {
7474
ngtCompound
7575
*args="[samples(), transmissionSampler()]"
7676
[ref]="materialRef"
77-
[buffer]="buffer() || fboMainRef.nativeElement?.texture"
77+
[buffer]="buffer() || fboMainRef()?.texture"
7878
[_transmission]="transmission()"
7979
[transmission]="transmissionSampler() ? transmission() : 0"
8080
[thickness]="thickness()"
@@ -227,10 +227,7 @@ export class NgtsMeshTranmissionMaterial {
227227

228228
this.materialRef.nativeElement.time = state.clock.getElapsedTime();
229229
// Render only if the buffer matches the built-in and no transmission sampler is set
230-
if (
231-
this.materialRef.nativeElement.buffer === this.fboMainRef.nativeElement?.texture &&
232-
!transmissionSampler
233-
) {
230+
if (this.materialRef.nativeElement.buffer === this.fboMainRef()?.texture && !transmissionSampler) {
234231
parent = getLocalState(this.materialRef.nativeElement).parent?.() as THREE.Object3D;
235232
if (parent) {
236233
// Save defaults
@@ -246,22 +243,22 @@ export class NgtsMeshTranmissionMaterial {
246243

247244
if (backside) {
248245
// Render into the backside buffer
249-
state.gl.setRenderTarget(this.fboBackRef.nativeElement);
246+
state.gl.setRenderTarget(this.fboBackRef());
250247
state.gl.render(state.scene, state.camera);
251248
// And now prepare the material for the main render using the backside buffer
252249
(parent as NgtAnyRecord)['material'] = this.materialRef.nativeElement;
253-
(parent as NgtAnyRecord)['material'].buffer = this.fboBackRef.nativeElement?.texture;
250+
(parent as NgtAnyRecord)['material'].buffer = this.fboBackRef()?.texture;
254251
(parent as NgtAnyRecord)['material'].thickness = backsideThickness;
255252
(parent as NgtAnyRecord)['material'].side = THREE.BackSide;
256253
}
257254

258255
// Render into the main buffer
259-
state.gl.setRenderTarget(this.fboMainRef.nativeElement);
256+
state.gl.setRenderTarget(this.fboMainRef());
260257
state.gl.render(state.scene, state.camera);
261258

262259
(parent as NgtAnyRecord)['material'].thickness = thickness;
263260
(parent as NgtAnyRecord)['material'].side = this.side;
264-
(parent as NgtAnyRecord)['material'].buffer = this.fboMainRef.nativeElement?.texture;
261+
(parent as NgtAnyRecord)['material'].buffer = this.fboMainRef()?.texture;
265262

266263
// Set old state back
267264
state.scene.background = oldBg;

libs/soba/misc/src/caustics/caustics.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ declare global {
118118
<ngt-mesh [renderOrder]="2" [ref]="planeRef" [rotation]="[-Math.PI / 2, 0, 0]">
119119
<ngt-plane-geometry />
120120
<ngt-caustics-projection-material
121-
*ngIf="causticsTargetFbo.nativeElement && causticsTargetBFbo.nativeElement"
121+
*ngIf="causticsTargetFbo() as targetFbo && causticsTargetBFbo() as targetBFbo"
122122
[transparent]="true"
123123
[color]="color()"
124-
[causticsTexture]="causticsTargetFbo.nativeElement.texture"
125-
[causticsTextureB]="causticsTargetBFbo.nativeElement.texture"
124+
[causticsTexture]="targetFbo.texture"
125+
[causticsTextureB]="targetBFbo.texture"
126126
[blending]="CustomBlending"
127127
[blendSrc]="OneFactor"
128128
[blendDst]="SrcAlphaFactor"
@@ -278,10 +278,10 @@ export class NgtsCaustics {
278278
this.causticsRef.nativeElement,
279279
this.sceneRef.nativeElement,
280280
this.cameraRef.nativeElement,
281-
this.normalTargetFbo.nativeElement,
282-
this.normalTargetBFbo.nativeElement,
283-
this.causticsTargetFbo.nativeElement,
284-
this.causticsTargetBFbo.nativeElement,
281+
this.normalTargetFbo(),
282+
this.normalTargetBFbo(),
283+
this.causticsTargetFbo(),
284+
this.causticsTargetBFbo(),
285285
this.planeRef.nativeElement,
286286
this.sceneChildren(),
287287
this.planeChildren(),
Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
import { ChangeDetectorRef, computed, effect, inject, runInInjectionContext, type Injector } from '@angular/core';
2-
import { injectBeforeRender, injectNgtRef, injectNgtStore, safeDetectChanges } from 'angular-three';
1+
import {
2+
ChangeDetectorRef,
3+
computed,
4+
effect,
5+
inject,
6+
runInInjectionContext,
7+
signal,
8+
untracked,
9+
type Injector,
10+
} from '@angular/core';
11+
import { injectBeforeRender, injectNgtStore, safeDetectChanges } from 'angular-three';
312
import { assertInjector } from 'ngxtension/assert-injector';
413
import * as THREE from 'three';
514
import { injectNgtsFBO } from '../fbo/fbo';
@@ -15,29 +24,34 @@ export function injectNgtsDepthBuffer(
1524
) {
1625
injector = assertInjector(injectNgtsDepthBuffer, injector);
1726
return runInInjectionContext(injector, () => {
18-
const depthBufferRef = injectNgtRef<THREE.DepthTexture | null>(null);
27+
const depthBufferSignal = signal<THREE.DepthTexture | null>(null);
1928
const store = injectNgtStore();
2029
const cdr = inject(ChangeDetectorRef);
2130

22-
const size = store.select('size');
23-
const dpr = store.select('viewport', 'dpr');
31+
const [defaultWidth, defaultHeight, dpr] = [
32+
store.select('size', 'width'),
33+
store.select('size', 'height'),
34+
store.select('viewport', 'dpr'),
35+
];
2436

2537
const fboParams = computed(() => {
2638
const params = { size: 256, frames: Infinity, ...paramsFactory() };
27-
const width = params.size || size().width * dpr();
28-
const height = params.size || size().height * dpr();
39+
const width = params.size || defaultWidth() * dpr();
40+
const height = params.size || defaultHeight() * dpr();
2941
const depthTexture = new THREE.DepthTexture(width, height);
3042
depthTexture.format = THREE.DepthFormat;
3143
depthTexture.type = THREE.UnsignedShortType;
3244
return { width, height, settings: { depthTexture } };
3345
});
3446

35-
const fboRef = injectNgtsFBO(fboParams, { injector });
47+
const _fbo = injectNgtsFBO(fboParams, { injector });
3648

3749
effect(() => {
38-
const fbo = fboRef.nativeElement;
50+
const fbo = _fbo();
3951
if (fbo) {
40-
depthBufferRef.nativeElement = fbo.depthTexture;
52+
untracked(() => {
53+
depthBufferSignal.set(fbo.depthTexture);
54+
});
4155
safeDetectChanges(cdr);
4256
}
4357
});
@@ -46,7 +60,7 @@ export function injectNgtsDepthBuffer(
4660
injectBeforeRender(
4761
({ gl, scene, camera }) => {
4862
const params = { size: 256, frames: Infinity, ...paramsFactory() };
49-
const fbo = fboRef.untracked;
63+
const fbo = _fbo();
5064
if ((params.frames === Infinity || count < params.frames) && fbo) {
5165
gl.setRenderTarget(fbo);
5266
gl.render(scene, camera);
@@ -57,6 +71,6 @@ export function injectNgtsDepthBuffer(
5771
{ injector },
5872
);
5973

60-
return depthBufferRef;
74+
return depthBufferSignal.asReadonly();
6175
});
6276
}

libs/soba/misc/src/fbo/fbo.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import {
55
effect,
66
inject,
77
runInInjectionContext,
8+
signal,
9+
untracked,
810
type Injector,
911
} from '@angular/core';
10-
import { injectNgtRef, injectNgtStore, safeDetectChanges } from 'angular-three';
12+
import { injectNgtStore, safeDetectChanges } from 'angular-three';
1113
import { assertInjector } from 'ngxtension/assert-injector';
1214
import * as THREE from 'three';
1315

@@ -30,37 +32,41 @@ export function injectNgtsFBO(fboParams: () => NgtsFBOParams, { injector }: { in
3032
const store = injectNgtStore();
3133
const cdr = inject(ChangeDetectorRef);
3234

33-
const targetRef = injectNgtRef<THREE.WebGLRenderTarget | null>(null);
35+
const targetSignal = signal<THREE.WebGLRenderTarget | null>(null);
3436

35-
inject(DestroyRef).onDestroy(() => targetRef.nativeElement?.dispose());
37+
inject(DestroyRef).onDestroy(() => targetSignal()?.dispose());
3638

37-
const size = store.select('size');
38-
const dpr = store.select('viewport', 'dpr');
39+
const [defaultWidth, defaultHeight, dpr] = [
40+
store.select('size', 'width'),
41+
store.select('size', 'height'),
42+
store.select('viewport', 'dpr'),
43+
];
3944
const fboSettings = computed(() => {
4045
const { width, height, settings } = fboParams();
41-
const _width = typeof width === 'number' ? width : size().width * dpr();
42-
const _height = typeof height === 'number' ? height : size().height * dpr();
43-
const _settings = (typeof width === 'number' ? settings : (width as FBOSettings)) || {};
44-
45-
return { width: _width, height: _height, settings: _settings };
46+
return [
47+
typeof width === 'number' ? width : defaultWidth() * dpr(),
48+
typeof height === 'number' ? height : defaultHeight() * dpr(),
49+
(typeof width === 'number' ? settings : (width as FBOSettings)) || {},
50+
] as const;
4651
});
4752

4853
effect(() => {
49-
const { width, height, settings } = fboSettings();
50-
const { samples = 0, depth, ...targetSettings } = settings;
51-
let untrackedTarget = targetRef.untracked;
54+
const [width, height, { samples = 0, depth, ...settings }] = fboSettings();
55+
let untrackedTarget = untracked(targetSignal);
5256
if (!untrackedTarget) {
5357
const target = new THREE.WebGLRenderTarget(width, height, {
5458
minFilter: THREE.LinearFilter,
5559
magFilter: THREE.LinearFilter,
5660
type: THREE.HalfFloatType,
57-
...targetSettings,
61+
...settings,
5862
});
5963
if (depth) target.depthTexture = new THREE.DepthTexture(width, height, THREE.FloatType);
6064

6165
target.samples = samples;
62-
targetRef.nativeElement = target;
63-
untrackedTarget = targetRef.untracked;
66+
untracked(() => {
67+
targetSignal.set(target);
68+
});
69+
untrackedTarget = untracked(targetSignal);
6470
}
6571

6672
if (untrackedTarget) {
@@ -70,6 +76,6 @@ export function injectNgtsFBO(fboParams: () => NgtsFBOParams, { injector }: { in
7076
}
7177
});
7278

73-
return targetRef;
79+
return targetSignal.asReadonly();
7480
});
7581
}

0 commit comments

Comments
 (0)