Skip to content

Commit b0080e0

Browse files
Chau TranChau Tran
Chau Tran
authored and
Chau Tran
committed
feat(soba): migrate accumulative shadows
1 parent 5285174 commit b0080e0

File tree

15 files changed

+829
-11
lines changed

15 files changed

+829
-11
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"eslint.validate": ["json"]
2+
"eslint.validate": ["json"],
3+
"html.customData": ["node_modules/angular-three/metadata.json"]
34
}

libs/angular-three/metadata.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

libs/angular-three/src/lib/utils/apply-props.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@ export function applyProps(instance: NgtInstanceNode, props: NgtAnyRecord): NgtI
9090
currentInstance[key].type === THREE.UnsignedByteType
9191
) {
9292
const texture = currentInstance[key] as THREE.Texture;
93-
if (is.colorSpaceExist(texture) && is.colorSpaceExist(rootState.gl))
94-
texture.colorSpace = rootState.gl.outputColorSpace;
95-
else texture.encoding = rootState.gl.outputEncoding;
93+
if (rootState?.gl) {
94+
if (is.colorSpaceExist(texture) && is.colorSpaceExist(rootState.gl))
95+
texture.colorSpace = rootState.gl.outputColorSpace;
96+
else texture.encoding = rootState.gl.outputEncoding;
97+
}
9698
}
9799
}
98100

libs/angular-three/web-types.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { shaderMaterial } from '../shader-material/shader-material';
2+
3+
export const DiscardMaterial = shaderMaterial(
4+
{},
5+
'void main() { }',
6+
'void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); discard; }'
7+
);

libs/soba/shaders/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export * from './discard-material/discard-material';
2+
export * from './soft-shadow-material/soft-shadow-material';
13
export * from './sparkles-material/sparkles-material';
24
export * from './spot-light-material/spot-light-material';
35
export * from './star-field-material/star-field-material';
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import * as THREE from 'three';
2+
import { shaderMaterial } from '../shader-material/shader-material';
3+
4+
export const SoftShadowMaterial = shaderMaterial(
5+
{
6+
color: new THREE.Color(),
7+
blend: 2.0,
8+
alphaTest: 0.75,
9+
opacity: 0,
10+
map: null,
11+
},
12+
// language=glsl
13+
`
14+
varying vec2 vUv;
15+
void main() {
16+
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.);
17+
vUv = uv;
18+
}
19+
`,
20+
// language=glsl
21+
`
22+
varying vec2 vUv;
23+
uniform sampler2D map;
24+
uniform vec3 color;
25+
uniform float opacity;
26+
uniform float alphaTest;
27+
uniform float blend;
28+
void main() {
29+
vec4 sampledDiffuseColor = texture2D(map, vUv);
30+
gl_FragColor = vec4(color * sampledDiffuseColor.r * blend, max(0.0, (1.0 - (sampledDiffuseColor.r + sampledDiffuseColor.g + sampledDiffuseColor.b) / alphaTest)) * opacity);
31+
#include <tonemapping_fragment>
32+
#include <encodings_fragment>
33+
}
34+
`
35+
);
36+
37+
export interface SoftShadowMaterialInputs {
38+
map: THREE.Texture;
39+
color?: THREE.ColorRepresentation;
40+
alphaTest?: number;
41+
blend?: number;
42+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { Component, computed, CUSTOM_ELEMENTS_SCHEMA, effect, NO_ERRORS_SCHEMA, Signal } from '@angular/core';
2+
import { Meta, moduleMetadata } from '@storybook/angular';
3+
import { applyProps, NgtArgs } from 'angular-three';
4+
import { NgtsOrbitControls } from 'angular-three-soba/controls';
5+
import { injectNgtsGLTFLoader } from 'angular-three-soba/loaders';
6+
import { NgtsAccumulativeShadows, NgtsEnvironment, NgtsRandomizedLights } from 'angular-three-soba/staging';
7+
import * as THREE from 'three';
8+
import { GLTF } from 'three-stdlib';
9+
import { FlakesTexture } from 'three/examples/jsm/textures/FlakesTexture';
10+
import { makeStoryFunction, StorybookSetup } from '../setup-canvas';
11+
12+
injectNgtsGLTFLoader.preload(
13+
() => 'https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/models/suzanne-high-poly/model.gltf'
14+
);
15+
16+
interface SuziGLTF extends GLTF {
17+
materials: { default: THREE.MeshStandardMaterial };
18+
}
19+
20+
@Component({
21+
selector: 'Suzi',
22+
standalone: true,
23+
template: ` <ngt-primitive ngtCompound *args="[model()]" /> `,
24+
imports: [NgtArgs],
25+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
26+
})
27+
class Suzi {
28+
readonly #suzi = injectNgtsGLTFLoader(
29+
() => 'https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/models/suzanne-high-poly/model.gltf'
30+
) as unknown as Signal<SuziGLTF>;
31+
readonly model = computed(() => {
32+
const suzi = this.#suzi();
33+
if (!suzi) return null;
34+
return suzi.scene;
35+
});
36+
37+
constructor() {
38+
effect(() => {
39+
const suzi = this.#suzi();
40+
if (!suzi) return;
41+
const { scene, materials } = suzi;
42+
scene.traverse((obj: any) => obj.isMesh && (obj.receiveShadow = obj.castShadow = true));
43+
applyProps(materials.default, {
44+
color: 'orange',
45+
roughness: 0,
46+
normalMap: new THREE.CanvasTexture(
47+
new FlakesTexture(),
48+
THREE.UVMapping,
49+
THREE.RepeatWrapping,
50+
THREE.RepeatWrapping
51+
),
52+
normalScale: [0.05, 0.05],
53+
});
54+
applyProps(materials.default.normalMap, {
55+
flipY: false,
56+
repeat: [40, 40],
57+
});
58+
});
59+
}
60+
}
61+
62+
@Component({
63+
standalone: true,
64+
template: `
65+
<ngt-color *args="['chocolate']" attach="background" />
66+
67+
<Suzi [rotation]="[-0.63, 0, 0]" [scale]="2" [position]="[0, -1.175, 0]" />
68+
<ngts-accumulative-shadows
69+
color="goldenrod"
70+
[temporal]="true"
71+
[frames]="100"
72+
[alphaTest]="0.65"
73+
[opacity]="2"
74+
[scale]="14"
75+
[position]="[0, -0.5, 0]"
76+
>
77+
<ngts-randomized-lights [amount]="8" [radius]="4" [ambient]="0.5" [bias]="0.001" [position]="[5, 5, -10]" />
78+
</ngts-accumulative-shadows>
79+
<ngts-orbit-controls [autoRotate]="true" />
80+
<ngts-environment preset="city" />
81+
`,
82+
imports: [NgtsAccumulativeShadows, NgtsRandomizedLights, NgtsOrbitControls, NgtsEnvironment, NgtArgs, Suzi],
83+
schemas: [NO_ERRORS_SCHEMA],
84+
})
85+
class DefaultAccumulativeShadowsStory {}
86+
87+
export default {
88+
title: 'Staging/Accumulative Shadows',
89+
decorators: [moduleMetadata({ imports: [StorybookSetup] })],
90+
} as Meta;
91+
92+
export const Default = makeStoryFunction(DefaultAccumulativeShadowsStory, { compoundPrefixes: ['Suzi'] });

libs/soba/src/staging/bounds.stories.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ class Models {
5858

5959
onClick(event: NgtThreeEvent<MouseEvent>) {
6060
event.stopPropagation();
61-
event.delta <= 2 && this.#boundsApi.refresh(event.object).fit();
61+
event.delta <= 2 && this.#boundsApi().refresh(event.object).fit();
6262
}
6363

6464
onPointerMissed(event: NgtThreeEvent<PointerEvent>) {
65-
(event as NgtAnyRecord)['button'] === 0 && this.#boundsApi.refresh().fit();
65+
(event as NgtAnyRecord)['button'] === 0 && this.#boundsApi().refresh().fit();
6666
}
6767
}
6868

0 commit comments

Comments
 (0)