Skip to content

Commit 7c73755

Browse files
committed
feat(postprocessing): add n8ao as an entry point; add tonemapping
angular-three-postprocessing/n8ao needs n8ao as a peer dependency
1 parent 7e2048b commit 7c73755

File tree

11 files changed

+238
-3
lines changed

11 files changed

+238
-3
lines changed

Diff for: libs/postprocessing/n8ao/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# angular-three-postprocessing/n8ao
2+
3+
Secondary entry point of `angular-three-postprocessing`. It can be used by importing from `angular-three-postprocessing/n8ao`.

Diff for: libs/postprocessing/n8ao/ng-package.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"lib": {
3+
"entryFile": "src/index.ts"
4+
}
5+
}

Diff for: libs/postprocessing/n8ao/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './lib/n8ao';

Diff for: libs/postprocessing/n8ao/src/lib/n8ao.ts

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// @ts-expect-error - n8ao is not typed
2+
import { N8AOPostPass } from 'n8ao';
3+
4+
import {
5+
ChangeDetectionStrategy,
6+
Component,
7+
computed,
8+
CUSTOM_ELEMENTS_SCHEMA,
9+
effect,
10+
inject,
11+
input,
12+
} from '@angular/core';
13+
import { applyProps, NgtArgs, pick } from 'angular-three';
14+
import { NgtpEffectComposer } from 'angular-three-postprocessing';
15+
import { mergeInputs } from 'ngxtension/inject-inputs';
16+
import { ColorRepresentation } from 'three';
17+
18+
export interface NgtpN8AOOptions {
19+
aoRadius: number;
20+
aoTones: number;
21+
distanceFalloff: number;
22+
intensity: number;
23+
biasOffset: number;
24+
biasMultiplier: number;
25+
aoSamples: number;
26+
denoiseSamples: number;
27+
denoiseRadius: number;
28+
color: ColorRepresentation;
29+
halfRes: boolean;
30+
depthAwareUpsampling: boolean;
31+
screenSpaceRadius: boolean;
32+
renderMode: 0 | 1 | 2 | 3 | 4;
33+
denoiseIterations: number;
34+
transparencyAware: boolean;
35+
gammaCorrection: boolean;
36+
logarithmicDepthBuffer: boolean;
37+
colorMultiply: boolean;
38+
accumulate: boolean;
39+
quality?: 'performance' | 'low' | 'medium' | 'high' | 'ultra';
40+
}
41+
42+
const defaultOptions: NgtpN8AOOptions = {
43+
aoSamples: 16,
44+
aoRadius: 5.0,
45+
aoTones: 0.0,
46+
denoiseSamples: 8,
47+
denoiseRadius: 12,
48+
distanceFalloff: 1.0,
49+
intensity: 5,
50+
denoiseIterations: 2.0,
51+
renderMode: 0,
52+
biasOffset: 0.0,
53+
biasMultiplier: 0.0,
54+
color: 'black',
55+
gammaCorrection: true,
56+
logarithmicDepthBuffer: false,
57+
screenSpaceRadius: false,
58+
halfRes: false,
59+
depthAwareUpsampling: true,
60+
colorMultiply: true,
61+
transparencyAware: false,
62+
accumulate: false,
63+
};
64+
65+
@Component({
66+
selector: 'ngtp-n8ao',
67+
standalone: true,
68+
template: `
69+
<ngt-primitive *args="[effect()]" />
70+
`,
71+
imports: [NgtArgs],
72+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
73+
changeDetection: ChangeDetectionStrategy.OnPush,
74+
})
75+
export class NgtpN8AO {
76+
options = input(defaultOptions, { transform: mergeInputs(defaultOptions) });
77+
78+
private quality = pick(this.options, 'quality');
79+
80+
private effectComposer = inject(NgtpEffectComposer);
81+
82+
effect = computed(() => {
83+
const [scene, camera] = [this.effectComposer.scene(), this.effectComposer.camera()];
84+
return new N8AOPostPass(scene, camera);
85+
});
86+
87+
constructor() {
88+
effect(() => {
89+
const n8aoEffect = this.effect();
90+
if (!n8aoEffect) return;
91+
92+
const { quality: _, ...configurations } = this.options();
93+
applyProps(n8aoEffect.configuration, configurations);
94+
});
95+
96+
effect(() => {
97+
this.setQualityEffect();
98+
});
99+
}
100+
101+
private setQualityEffect() {
102+
const effect = this.effect();
103+
if (!effect) return;
104+
105+
const quality = this.quality();
106+
if (!quality) return;
107+
108+
const titleCaseQuality = quality.charAt(0).toUpperCase() + quality.slice(1);
109+
effect.setQuality(titleCaseQuality);
110+
}
111+
}

Diff for: libs/postprocessing/package.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,17 @@
2525
"@angular/common": ">=18.0.0 <19.0.0",
2626
"@angular/core": ">=18.0.0 <19.0.0",
2727
"maath": ">=0.10.0 <0.11.0",
28+
"n8ao": "^1.9.0",
2829
"postprocessing": "^6.0.0",
2930
"three": ">=0.148.0 <0.169.0",
3031
"three-stdlib": "^2.0.0"
3132
},
32-
"dependencies": {
33+
"peerDependenciesMeta": {
34+
"n8ao": {
35+
"optional": true
36+
}
37+
},
38+
"dependencies": {
3339
"tslib": "^2.7.0"
3440
},
3541
"sideEffects": false,

Diff for: libs/postprocessing/src/lib/effects/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ export * from './shock-wave';
2323
export * from './smaa';
2424
export * from './tilt-shift';
2525
export * from './tilt-shift-2';
26+
export * from './tone-mapping';
2627
export * from './vignette';
2728
export * from './water';

Diff for: libs/postprocessing/src/lib/effects/tone-mapping.ts

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { ChangeDetectionStrategy, Component, computed, CUSTOM_ELEMENTS_SCHEMA, effect, input } from '@angular/core';
2+
import { NgtArgs, omit, pick } from 'angular-three';
3+
import { EffectAttribute, ToneMappingEffect } from 'postprocessing';
4+
5+
export type NgtpToneMappingOptions = Partial<NonNullable<ConstructorParameters<typeof ToneMappingEffect>[0]>>;
6+
7+
@Component({
8+
selector: 'ngtp-tone-mapping',
9+
standalone: true,
10+
template: `
11+
<ngt-primitive *args="[effect()]" [parameters]="parameters()" />
12+
`,
13+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
14+
changeDetection: ChangeDetectionStrategy.OnPush,
15+
imports: [NgtArgs],
16+
})
17+
export class NgtpToneMapping {
18+
options = input({} as NgtpToneMappingOptions);
19+
protected parameters = omit(this.options, [
20+
'blendFunction',
21+
'adaptive',
22+
'mode',
23+
'resolution',
24+
'maxLuminance',
25+
'whitePoint',
26+
'middleGrey',
27+
'minLuminance',
28+
'averageLuminance',
29+
'adaptationRate',
30+
]);
31+
32+
private blendFunction = pick(this.options, 'blendFunction');
33+
private adaptive = pick(this.options, 'adaptive');
34+
private mode = pick(this.options, 'mode');
35+
private resolution = pick(this.options, 'resolution');
36+
private maxLuminance = pick(this.options, 'maxLuminance');
37+
private whitePoint = pick(this.options, 'whitePoint');
38+
private middleGrey = pick(this.options, 'middleGrey');
39+
private minLuminance = pick(this.options, 'minLuminance');
40+
private averageLuminance = pick(this.options, 'averageLuminance');
41+
private adaptationRate = pick(this.options, 'adaptationRate');
42+
43+
effect = computed(() => {
44+
const [
45+
blendFunction,
46+
adaptive,
47+
mode,
48+
resolution,
49+
maxLuminance,
50+
whitePoint,
51+
middleGrey,
52+
minLuminance,
53+
averageLuminance,
54+
adaptationRate,
55+
] = [
56+
this.blendFunction(),
57+
this.adaptive(),
58+
this.mode(),
59+
this.resolution(),
60+
this.maxLuminance(),
61+
this.whitePoint(),
62+
this.middleGrey(),
63+
this.minLuminance(),
64+
this.averageLuminance(),
65+
this.adaptationRate(),
66+
];
67+
68+
const effect = new ToneMappingEffect({
69+
blendFunction,
70+
adaptive,
71+
mode,
72+
resolution,
73+
maxLuminance,
74+
whitePoint,
75+
middleGrey,
76+
minLuminance,
77+
averageLuminance,
78+
adaptationRate,
79+
});
80+
81+
effect['setAttributes'](EffectAttribute.CONVOLUTION);
82+
83+
return effect;
84+
});
85+
86+
constructor() {
87+
effect((onCleanup) => {
88+
const toneMappingEffect = this.effect();
89+
onCleanup(() => toneMappingEffect.dispose());
90+
});
91+
}
92+
}

Diff for: libs/postprocessing/tsconfig.lib.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
"inlineSources": true,
88
"types": []
99
},
10-
"exclude": ["src/**/*.spec.ts", "src/test-setup.ts", "src/**/*.test.ts"],
11-
"include": ["src/**/*.ts"]
10+
"exclude": ["**/*.spec.ts", "test-setup.ts", "**/*.test.ts"],
11+
"include": ["**/*.ts"]
1212
}

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
"marked-highlight": "^2.1.4",
142142
"mermaid": "^10.9.1",
143143
"meshline": "^3.3.1",
144+
"n8ao": "^1.9.1",
144145
"ngxtension": "^4.0.0",
145146
"nice-color-palettes": "^3.0.0",
146147
"node-three-gltf": "^1.8.2",

Diff for: pnpm-lock.yaml

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: tsconfig.base.json

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"angular-three-cannon/constraint": ["libs/cannon/constraint/src/index.ts"],
2222
"angular-three-cannon/debug": ["libs/cannon/debug/src/index.ts"],
2323
"angular-three-postprocessing": ["libs/postprocessing/src/index.ts"],
24+
"angular-three-postprocessing/n8ao": ["libs/postprocessing/n8ao/src/index.ts"],
2425
"angular-three-rapier": ["libs/rapier/src/index.ts"],
2526
"angular-three-soba": ["libs/soba/src/index.ts"],
2627
"angular-three-soba/abstractions": ["libs/soba/abstractions/src/index.ts"],

0 commit comments

Comments
 (0)