Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1d2e7fc

Browse files
ctranctran
ctran
authored and
ctran
committed
kinda done with basic effects
1 parent f768ef7 commit 1d2e7fc

File tree

12 files changed

+409
-6
lines changed

12 files changed

+409
-6
lines changed

apps/kitchen-sink/src/app/postprocessing/basic/experience.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
viewChild,
88
} from '@angular/core';
99
import { NgtArgs, extend, injectBeforeRender } from 'angular-three';
10-
import { NgtpEffectComposer, NgtpEffects, NgtpLensFlare } from 'angular-three-postprocessing';
10+
import { NgtpEffectComposer, NgtpEffects, NgtpGodRays } from 'angular-three-postprocessing';
1111
import * as THREE from 'three';
1212
import { Group, Mesh } from 'three';
1313

@@ -38,7 +38,7 @@ export class Sun {
3838
template: `
3939
<ngt-color *args="['#171717']" attach="background" />
4040
41-
<!-- <app-sun color="yellow" /> -->
41+
<app-sun color="yellow" />
4242
4343
<ngt-group #group>
4444
<ngt-mesh>
@@ -51,26 +51,28 @@ export class Sun {
5151
<ngt-mesh-basic-material color="aquamarine" />
5252
</ngt-mesh>
5353
54-
<ngt-mesh [position]="[-2, -2, -2]" [userData]="{ lensflare: 'no-occlusion' }">
54+
<ngt-mesh [position]="[-2, -2, -2]">
5555
<ngt-box-geometry />
5656
<ngt-mesh-basic-material color="goldenrod" />
5757
</ngt-mesh>
5858
</ngt-group>
5959
6060
<ngtp-effect-composer>
6161
<ng-template effects>
62-
<ngtp-lens-flare [options]="{ followMouse: false }" />
62+
@if (sun().sunRef().nativeElement; as sun) {
63+
<ngtp-god-rays [options]="{ sun }" />
64+
}
6365
</ng-template>
6466
</ngtp-effect-composer>
6567
`,
6668
schemas: [CUSTOM_ELEMENTS_SCHEMA],
67-
imports: [NgtpEffectComposer, NgtpEffects, NgtArgs, NgtpLensFlare, Sun],
69+
imports: [NgtpEffectComposer, NgtpEffects, NgtArgs, NgtpGodRays, Sun],
6870
changeDetection: ChangeDetectionStrategy.OnPush,
6971
host: { class: 'experience-basic-postprocessing' },
7072
})
7173
export class Experience {
7274
group = viewChild.required<ElementRef<Group>>('group');
73-
// sun = viewChild.required(Sun);
75+
sun = viewChild.required(Sun);
7476

7577
constructor() {
7678
injectBeforeRender(() => {

libs/postprocessing/src/lib/effects/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,13 @@ export * from './grid';
1414
export * from './hue-saturation';
1515
export * from './lens-flare';
1616
export * from './lut';
17+
export * from './noise';
18+
export * from './pixelation';
19+
export * from './scanline';
20+
export * from './sepia';
21+
export * from './shock-wave';
22+
export * from './smaa';
23+
export * from './tilt-shift';
24+
export * from './tilt-shift-2';
25+
export * from './vignette';
26+
export * from './water';
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
2+
import { NgtArgs, extend } from 'angular-three';
3+
import { BlendFunction, NoiseEffect } from 'postprocessing';
4+
import { NgtpEffect, NgtpEffectBlendMode, NgtpEffectHostDirective, provideDefaultEffectOptions } from '../effect';
5+
6+
extend({ NoiseEffect });
7+
8+
export type NoiseEffectOptions = Partial<NonNullable<ConstructorParameters<typeof NoiseEffect>[0]>>;
9+
10+
@Component({
11+
selector: 'ngtp-noise',
12+
template: `
13+
<ngt-noise-effect *args="[options()]" [camera]="effect.camera()" [ref]="effect.effectRef()" ngtCompound>
14+
<ngtp-effect-blend-mode />
15+
<ng-content />
16+
</ngt-noise-effect>
17+
`,
18+
standalone: true,
19+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
20+
changeDetection: ChangeDetectionStrategy.OnPush,
21+
imports: [NgtArgs, NgtpEffectBlendMode],
22+
hostDirectives: [NgtpEffectHostDirective],
23+
providers: [provideDefaultEffectOptions({ blendFunction: BlendFunction.COLOR_DODGE })],
24+
})
25+
export class NgtpNoise {
26+
effect = inject(NgtpEffect, { host: true });
27+
options = input({} as Omit<NoiseEffectOptions, 'blendFunction'>);
28+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
2+
import { NgtArgs, injectNgtRef } from 'angular-three';
3+
import { mergeInputs } from 'ngxtension/inject-inputs';
4+
import { PixelationEffect } from 'postprocessing';
5+
6+
export interface PixelationOptions {
7+
granularity: number;
8+
}
9+
@Component({
10+
selector: 'ngtp-pixelation',
11+
template: `
12+
<ngt-primitive *args="[effect()]" [ref]="effectRef()" ngtCompound />
13+
`,
14+
standalone: true,
15+
changeDetection: ChangeDetectionStrategy.OnPush,
16+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
17+
imports: [NgtArgs],
18+
})
19+
export class NgtpPixelation {
20+
effectRef = input(injectNgtRef<PixelationEffect>());
21+
options = input({ granularity: 5 } as PixelationOptions, { transform: mergeInputs({ granularity: 5 }) });
22+
granularity = computed(() => this.options().granularity);
23+
24+
effect = computed(() => new PixelationEffect(this.granularity()));
25+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
2+
import { NgtArgs, extend } from 'angular-three';
3+
import { mergeInputs } from 'ngxtension/inject-inputs';
4+
import { BlendFunction, ScanlineEffect } from 'postprocessing';
5+
import { NgtpEffect, NgtpEffectBlendMode, NgtpEffectHostDirective, provideDefaultEffectOptions } from '../effect';
6+
7+
extend({ ScanlineEffect });
8+
9+
export type ScanlineEffectOptions = Partial<NonNullable<ConstructorParameters<typeof ScanlineEffect>[0]>>;
10+
11+
const defaultOptions: Omit<ScanlineEffectOptions, 'blendFunction'> = {
12+
density: 1.25,
13+
};
14+
15+
@Component({
16+
selector: 'ngtp-scanline',
17+
template: `
18+
<ngt-scanline-effect *args="[options()]" [camera]="effect.camera()" [ref]="effect.effectRef()" ngtCompound>
19+
<ngtp-effect-blend-mode />
20+
<ng-content />
21+
</ngt-scanline-effect>
22+
`,
23+
standalone: true,
24+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
25+
changeDetection: ChangeDetectionStrategy.OnPush,
26+
imports: [NgtArgs, NgtpEffectBlendMode],
27+
hostDirectives: [NgtpEffectHostDirective],
28+
providers: [provideDefaultEffectOptions({ blendFunction: BlendFunction.OVERLAY })],
29+
})
30+
export class NgtpScanline {
31+
effect = inject(NgtpEffect, { host: true });
32+
options = input(defaultOptions, { transform: mergeInputs(defaultOptions) });
33+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
2+
import { NgtArgs, extend } from 'angular-three';
3+
import { SepiaEffect } from 'postprocessing';
4+
import { NgtpEffect, NgtpEffectBlendMode, NgtpEffectHostDirective } from '../effect';
5+
6+
extend({ SepiaEffect });
7+
8+
export type SepiaEffectOptions = Partial<NonNullable<ConstructorParameters<typeof SepiaEffect>[0]>>;
9+
10+
@Component({
11+
selector: 'ngtp-sepia',
12+
template: `
13+
<ngt-sepia-effect *args="[options()]" [camera]="effect.camera()" [ref]="effect.effectRef()" ngtCompound>
14+
<ngtp-effect-blend-mode />
15+
<ng-content />
16+
</ngt-sepia-effect>
17+
`,
18+
standalone: true,
19+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
20+
changeDetection: ChangeDetectionStrategy.OnPush,
21+
imports: [NgtArgs, NgtpEffectBlendMode],
22+
hostDirectives: [NgtpEffectHostDirective],
23+
})
24+
export class NgtpSepia {
25+
effect = inject(NgtpEffect, { host: true });
26+
options = input({} as Omit<SepiaEffectOptions, 'blendFunction'>);
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
2+
import { NgtArgs, extend } from 'angular-three';
3+
import { ShockWaveEffect } from 'postprocessing';
4+
import { NgtpEffect, NgtpEffectBlendMode, NgtpEffectHostDirective } from '../effect';
5+
6+
extend({ ShockWaveEffect });
7+
8+
export type ShockWaveEffectOptions = Partial<NonNullable<ConstructorParameters<typeof ShockWaveEffect>[0]>>;
9+
10+
@Component({
11+
selector: 'ngtp-shock-wave',
12+
template: `
13+
<ngt-shock-wave-effect *args="[options()]" [camera]="effect.camera()" [ref]="effect.effectRef()" ngtCompound>
14+
<ngtp-effect-blend-mode />
15+
<ng-content />
16+
</ngt-shock-wave-effect>
17+
`,
18+
standalone: true,
19+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
20+
changeDetection: ChangeDetectionStrategy.OnPush,
21+
imports: [NgtArgs, NgtpEffectBlendMode],
22+
hostDirectives: [NgtpEffectHostDirective],
23+
})
24+
export class NgtpShockWave {
25+
effect = inject(NgtpEffect, { host: true });
26+
options = input({} as Omit<ShockWaveEffectOptions, 'blendFunction'>);
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
2+
import { NgtArgs, extend } from 'angular-three';
3+
import { SMAAEffect } from 'postprocessing';
4+
import { NgtpEffect, NgtpEffectBlendMode, NgtpEffectHostDirective } from '../effect';
5+
6+
extend({ SMAAEffect });
7+
8+
export type SMAAEffectOptions = Partial<NonNullable<ConstructorParameters<typeof SMAAEffect>[0]>>;
9+
10+
@Component({
11+
selector: 'ngtp-smaa',
12+
template: `
13+
<ngt-sMAA-effect *args="[options()]" [camera]="effect.camera()" [ref]="effect.effectRef()" ngtCompound>
14+
<ngtp-effect-blend-mode />
15+
<ng-content />
16+
</ngt-sMAA-effect>
17+
`,
18+
standalone: true,
19+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
20+
changeDetection: ChangeDetectionStrategy.OnPush,
21+
imports: [NgtArgs, NgtpEffectBlendMode],
22+
hostDirectives: [NgtpEffectHostDirective],
23+
})
24+
export class NgtpSMAA {
25+
effect = inject(NgtpEffect, { host: true });
26+
options = input({} as Omit<SMAAEffectOptions, 'blendFunction'>);
27+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
2+
import { NgtArgs, extend } from 'angular-three';
3+
import { BlendFunction, Effect, EffectAttribute } from 'postprocessing';
4+
import { Uniform } from 'three';
5+
import { NgtpEffect, NgtpEffectBlendMode, NgtpEffectHostDirective, provideDefaultEffectOptions } from '../effect';
6+
7+
const TiltShiftShader = {
8+
fragmentShader: `
9+
10+
// original shader by Evan Wallace
11+
12+
#define MAX_ITERATIONS 100
13+
14+
uniform float blur;
15+
uniform float taper;
16+
uniform vec2 start;
17+
uniform vec2 end;
18+
uniform vec2 direction;
19+
uniform int samples;
20+
21+
float random(vec3 scale, float seed) {
22+
/* use the fragment position for a different seed per-pixel */
23+
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
24+
}
25+
26+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
27+
vec4 color = vec4(0.0);
28+
float total = 0.0;
29+
vec2 startPixel = vec2(start.x * resolution.x, start.y * resolution.y);
30+
vec2 endPixel = vec2(end.x * resolution.x, end.y * resolution.y);
31+
float f_samples = float(samples);
32+
float half_samples = f_samples / 2.0;
33+
34+
// use screen diagonal to normalize blur radii
35+
float maxScreenDistance = distance(vec2(0.0), resolution); // diagonal distance
36+
float gradientRadius = taper * (maxScreenDistance);
37+
float blurRadius = blur * (maxScreenDistance / 16.0);
38+
39+
/* randomize the lookup values to hide the fixed number of samples */
40+
float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);
41+
vec2 normal = normalize(vec2(startPixel.y - endPixel.y, endPixel.x - startPixel.x));
42+
float radius = smoothstep(0.0, 1.0, abs(dot(uv * resolution - startPixel, normal)) / gradientRadius) * blurRadius;
43+
44+
#pragma unroll_loop_start
45+
for (int i = 0; i <= MAX_ITERATIONS; i++) {
46+
if (i >= samples) { break; } // return early if over sample count
47+
float f_i = float(i);
48+
float s_i = -half_samples + f_i;
49+
float percent = (s_i + offset - 0.5) / half_samples;
50+
float weight = 1.0 - abs(percent);
51+
vec4 sample_i = texture2D(inputBuffer, uv + normalize(direction) / resolution * percent * radius);
52+
/* switch to pre-multiplied alpha to correctly blur transparent images */
53+
sample_i.rgb *= sample_i.a;
54+
color += sample_i * weight;
55+
total += weight;
56+
}
57+
#pragma unroll_loop_end
58+
59+
outputColor = color / total;
60+
61+
/* switch back from pre-multiplied alpha */
62+
outputColor.rgb /= outputColor.a + 0.00001;
63+
}
64+
`,
65+
};
66+
67+
export class TiltShift2Effect extends Effect {
68+
constructor({
69+
blendFunction = BlendFunction.NORMAL,
70+
blur = 0.15, // [0, 1], can go beyond 1 for extra
71+
taper = 0.5, // [0, 1], can go beyond 1 for extra
72+
start = [0.5, 0.0], // [0,1] percentage x,y of screenspace
73+
end = [0.5, 1.0], // [0,1] percentage x,y of screenspace
74+
samples = 10.0, // number of blur samples
75+
direction = [1, 1], // direction of blur
76+
} = {}) {
77+
super('TiltShiftEffect', TiltShiftShader.fragmentShader, {
78+
blendFunction,
79+
attributes: EffectAttribute.CONVOLUTION,
80+
uniforms: new Map<string, Uniform<number | number[]>>([
81+
['blur', new Uniform(blur)],
82+
['taper', new Uniform(taper)],
83+
['start', new Uniform(start)],
84+
['end', new Uniform(end)],
85+
['samples', new Uniform(samples)],
86+
['direction', new Uniform(direction)],
87+
]),
88+
});
89+
}
90+
}
91+
92+
export type TiltShift2EffectOptions = Partial<NonNullable<ConstructorParameters<typeof TiltShift2Effect>[0]>>;
93+
94+
extend({ TiltShift2Effect });
95+
96+
@Component({
97+
selector: 'ngtp-tilt-shift2',
98+
standalone: true,
99+
template: `
100+
<ngt-tilt-shift2-effect *args="[options()]" [camera]="effect.camera()" [ref]="effect.effectRef()" ngtCompound>
101+
<ngtp-effect-blend-mode />
102+
<ng-content />
103+
</ngt-tilt-shift2-effect>
104+
`,
105+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
106+
changeDetection: ChangeDetectionStrategy.OnPush,
107+
imports: [NgtArgs, NgtpEffectBlendMode],
108+
hostDirectives: [NgtpEffectHostDirective],
109+
providers: [provideDefaultEffectOptions({ blendFunction: BlendFunction.NORMAL })],
110+
})
111+
export class NgtpTiltShift2 {
112+
effect = inject(NgtpEffect, { host: true });
113+
options = input({} as Omit<TiltShift2EffectOptions, 'blendFunction'>);
114+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
2+
import { NgtArgs, extend } from 'angular-three';
3+
import { BlendFunction, TiltShiftEffect } from 'postprocessing';
4+
import { NgtpEffect, NgtpEffectBlendMode, NgtpEffectHostDirective, provideDefaultEffectOptions } from '../effect';
5+
6+
extend({ TiltShiftEffect });
7+
8+
export type TiltShiftEffectOptions = Partial<NonNullable<ConstructorParameters<typeof TiltShiftEffect>[0]>>;
9+
10+
@Component({
11+
selector: 'ngtp-tilt-shift',
12+
template: `
13+
<ngt-tilt-shift-effect *args="[options()]" [camera]="effect.camera()" [ref]="effect.effectRef()" ngtCompound>
14+
<ngtp-effect-blend-mode />
15+
<ng-content />
16+
</ngt-tilt-shift-effect>
17+
`,
18+
standalone: true,
19+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
20+
changeDetection: ChangeDetectionStrategy.OnPush,
21+
imports: [NgtArgs, NgtpEffectBlendMode],
22+
hostDirectives: [NgtpEffectHostDirective],
23+
providers: [provideDefaultEffectOptions({ blendFunction: BlendFunction.ADD })],
24+
})
25+
export class NgtpTiltShift {
26+
effect = inject(NgtpEffect, { host: true });
27+
options = input({} as Omit<TiltShiftEffectOptions, 'blendFunction'>);
28+
}

0 commit comments

Comments
 (0)