Skip to content

Commit aee4943

Browse files
Chau TranChau Tran
authored andcommitted
feat(soba): add mesh distort and mesh wobble material
1 parent e86ebc8 commit aee4943

File tree

16 files changed

+401
-2
lines changed

16 files changed

+401
-2
lines changed

libs/soba/materials/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# angular-three-soba/materials
2+
3+
Secondary entry point of `angular-three-soba`. It can be used by importing from `angular-three-soba/materials`.

libs/soba/materials/ng-package.json

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

libs/soba/materials/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './mesh-distort-material/mesh-distort-material';
2+
export * from './mesh-wobble-material/mesh-wobble-material';
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, Input } from '@angular/core';
2+
import { injectBeforeRender, injectNgtRef, NgtArgs, NgtSignalStore } from 'angular-three';
3+
import { MeshDistortMaterial, NGTS_DISTORT_MATERIAL_SHADER } from 'angular-three-soba/shaders';
4+
5+
export interface NgtsMeshDistortMaterialState {
6+
time: number;
7+
distort: number;
8+
radius: number;
9+
speed: number;
10+
}
11+
12+
@Component({
13+
selector: 'ngts-mesh-distort-material',
14+
standalone: true,
15+
template: `
16+
<ngt-primitive
17+
*args="[material]"
18+
[ref]="materialRef"
19+
[time]="distortTime()"
20+
[distort]="distortDistort()"
21+
[radius]="distortRadius()"
22+
ngtCompound
23+
attach="material"
24+
/>
25+
`,
26+
imports: [NgtArgs],
27+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
28+
})
29+
export class NgtsMeshDistortMaterial extends NgtSignalStore<NgtsMeshDistortMaterialState> {
30+
readonly material = new (inject(NGTS_DISTORT_MATERIAL_SHADER))();
31+
32+
@Input() materialRef = injectNgtRef<InstanceType<MeshDistortMaterial>>();
33+
34+
@Input() set time(time: number) {
35+
this.set({ time });
36+
}
37+
38+
@Input() set distort(distort: number) {
39+
this.set({ distort });
40+
}
41+
42+
@Input() set radius(radius: number) {
43+
this.set({ radius });
44+
}
45+
46+
@Input() set speed(speed: number) {
47+
this.set({ speed });
48+
}
49+
50+
readonly distortTime = this.select('time');
51+
readonly distortDistort = this.select('distort');
52+
readonly distortRadius = this.select('radius');
53+
54+
constructor() {
55+
super({ speed: 1, time: 0, distort: 0.4, radius: 1 });
56+
injectBeforeRender(({ clock }) => {
57+
this.material.time = clock.getElapsedTime() * this.get('speed');
58+
});
59+
}
60+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { Component, CUSTOM_ELEMENTS_SCHEMA, Input } from '@angular/core';
2+
import { extend, injectBeforeRender, injectNgtRef, NgtArgs, NgtSignalStore } from 'angular-three';
3+
import { MeshWobbleMaterial } from 'angular-three-soba/shaders';
4+
5+
extend({ MeshWobbleMaterial });
6+
7+
export interface NgtsMeshWobbleMaterialState {
8+
time: number;
9+
factor: number;
10+
speed: number;
11+
}
12+
13+
@Component({
14+
selector: 'ngts-mesh-wobble-material',
15+
standalone: true,
16+
template: `
17+
<ngt-primitive
18+
*args="[material]"
19+
[ref]="materialRef"
20+
[time]="wobbleTime()"
21+
[factor]="wobbleFactor()"
22+
attach="material"
23+
ngtCompound
24+
/>
25+
`,
26+
imports: [NgtArgs],
27+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
28+
})
29+
export class NgtsMeshWobbleMaterial extends NgtSignalStore<NgtsMeshWobbleMaterialState> {
30+
readonly material = new MeshWobbleMaterial();
31+
32+
@Input() materialRef = injectNgtRef<MeshWobbleMaterial>();
33+
34+
@Input() set time(time: number) {
35+
this.set({ time });
36+
}
37+
38+
@Input() set factor(factor: number) {
39+
this.set({ factor });
40+
}
41+
42+
@Input() set speed(speed: number) {
43+
this.set({ speed });
44+
}
45+
46+
readonly wobbleTime = this.select('time');
47+
readonly wobbleFactor = this.select('factor');
48+
49+
constructor() {
50+
super({ speed: 1, time: 0, factor: 1 });
51+
injectBeforeRender(({ clock }) => {
52+
this.material.time = clock.getElapsedTime() * this.get('speed');
53+
});
54+
}
55+
}

libs/soba/ng-package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
},
77
"assets": [
88
{
9-
"input": "./shaders/src/assets/",
9+
"input": "./shaders/assets/",
1010
"glob": "**/*",
1111
"output": "assets"
1212
}

libs/soba/project.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@
5858
"libs/soba/loaders/**/*.ts",
5959
"libs/soba/loaders/**/*.html",
6060
"libs/soba/shaders/**/*.ts",
61-
"libs/soba/shaders/**/*.html"
61+
"libs/soba/shaders/**/*.html",
62+
"libs/soba/materials/**/*.ts",
63+
"libs/soba/materials/**/*.html"
6264
]
6365
}
6466
},
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#pragma glslify: snoise3 = require(glsl-noise/simplex/3d)

libs/soba/shaders/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export * from './caustics-material/caustics-material';
22
export * from './caustics-material/caustics-projection-material';
33
export * from './discard-material/discard-material';
4+
export * from './mesh-distort-material/mesh-distort-material';
5+
export * from './mesh-wobble-material/mesh-wobble-material';
46
export * from './soft-shadow-material/soft-shadow-material';
57
export * from './sparkles-material/sparkles-material';
68
export * from './spot-light-material/spot-light-material';
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { InjectionToken, Type } from '@angular/core';
2+
import * as THREE from 'three';
3+
4+
interface Uniform<T> {
5+
value: T;
6+
}
7+
8+
/**
9+
* npm i -D raw-loader glslify-loader glsl-noise
10+
* Usage: import distort from 'raw-loader!glslify-loader!angular-three-soba/assets/distort.vert.glsl'
11+
*
12+
* provideNgtsMeshDistortMaterialShader(distort)
13+
*/
14+
15+
export type MeshDistortMaterial = Type<{ time: number; distort: number; radius: number } & THREE.MeshPhysicalMaterial>;
16+
17+
export const NGTS_DISTORT_MATERIAL_SHADER = new InjectionToken<MeshDistortMaterial>('DistortMaterialShader');
18+
19+
export function provideNgtsMeshDistortMaterialShader(distortShader: string) {
20+
return {
21+
provide: NGTS_DISTORT_MATERIAL_SHADER,
22+
useFactory: () => {
23+
return class extends THREE.MeshPhysicalMaterial {
24+
_time: Uniform<number>;
25+
_distort: Uniform<number>;
26+
_radius: Uniform<number>;
27+
28+
constructor(parameters: THREE.MeshPhysicalMaterialParameters = {}) {
29+
super(parameters);
30+
this.setValues(parameters);
31+
this._time = { value: 0 };
32+
this._distort = { value: 0.4 };
33+
this._radius = { value: 1 };
34+
}
35+
36+
override onBeforeCompile(shader: THREE.Shader) {
37+
shader.uniforms['time'] = this._time;
38+
shader.uniforms['radius'] = this._radius;
39+
shader.uniforms['distort'] = this._distort;
40+
41+
shader.vertexShader = `
42+
uniform float time;
43+
uniform float radius;
44+
uniform float distort;
45+
${distortShader}
46+
${shader.vertexShader}
47+
`;
48+
shader.vertexShader = shader.vertexShader.replace(
49+
'#include <begin_vertex>',
50+
`
51+
float updateTime = time / 50.0;
52+
float noise = snoise(vec3(position / 2.0 + updateTime * 5.0));
53+
vec3 transformed = vec3(position * (noise * pow(distort, 2.0) + radius));
54+
`
55+
);
56+
}
57+
58+
get time() {
59+
return this._time.value;
60+
}
61+
62+
set time(v) {
63+
this._time.value = v;
64+
}
65+
66+
get distort() {
67+
return this._distort.value;
68+
}
69+
70+
set distort(v) {
71+
this._distort.value = v;
72+
}
73+
74+
get radius() {
75+
return this._radius.value;
76+
}
77+
78+
set radius(v) {
79+
this._radius.value = v;
80+
}
81+
};
82+
},
83+
};
84+
}

0 commit comments

Comments
 (0)