Skip to content

Commit 812d8e4

Browse files
committed
accumulative shadows (only works with useLegacyLights)
1 parent 266589e commit 812d8e4

File tree

12 files changed

+814
-6
lines changed

12 files changed

+814
-6
lines changed

libs/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export * from './lib/types';
1818
export * from './lib/utils/apply-props';
1919
export * from './lib/utils/assert-injection-context';
2020
export { createAttachFunction } from './lib/utils/attach';
21+
export * from './lib/utils/create-injection-token';
2122
export * from './lib/utils/is';
2223
export * from './lib/utils/make';
2324
export * from './lib/utils/safe-detect-changes';
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,5 +1,7 @@
1+
export * from './discard-material/discard-material';
12
export * from './grid-material/grid-material';
23
export * from './shader-material/shader-material';
4+
export * from './soft-shadow-material/soft-shadow-material';
35
export * from './sparkles-material/sparkles-material';
46
export * from './spot-light-material/spot-light-material';
57
export * from './star-field-material/star-field-material';
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import type { NgtShaderMaterial } from 'angular-three';
2+
import * as THREE from 'three';
3+
import { shaderMaterial } from '../shader-material/shader-material';
4+
5+
export const SoftShadowMaterial = shaderMaterial(
6+
{
7+
color: new THREE.Color(),
8+
blend: 2.0,
9+
alphaTest: 0.75,
10+
opacity: 0,
11+
map: null,
12+
},
13+
`varying vec2 vUv;
14+
void main() {
15+
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.);
16+
vUv = uv;
17+
}`,
18+
`varying vec2 vUv;
19+
uniform sampler2D map;
20+
uniform vec3 color;
21+
uniform float opacity;
22+
uniform float alphaTest;
23+
uniform float blend;
24+
void main() {
25+
vec4 sampledDiffuseColor = texture2D(map, vUv);
26+
gl_FragColor = vec4(color * sampledDiffuseColor.r * blend, max(0.0, (1.0 - (sampledDiffuseColor.r + sampledDiffuseColor.g + sampledDiffuseColor.b) / alphaTest)) * opacity);
27+
#include <tonemapping_fragment>
28+
#include <${parseInt(THREE.REVISION.replace(/\D+/g, '')) >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>
29+
}`,
30+
);
31+
32+
export type NgtSoftShadowMaterialState = {
33+
map: THREE.Texture;
34+
color?: THREE.ColorRepresentation;
35+
alphaTest?: number;
36+
blend?: number;
37+
};
38+
39+
declare global {
40+
interface HTMLElementTagNameMap {
41+
/**
42+
* @extends ngt-shader-material
43+
*/
44+
'ngt-soft-shadow-material': NgtSoftShadowMaterialState & NgtShaderMaterial;
45+
}
46+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { Component, computed, CUSTOM_ELEMENTS_SCHEMA, effect, Signal } from '@angular/core';
2+
import { Meta } from '@storybook/angular';
3+
import { applyProps, NgtArgs } from 'angular-three';
4+
import { NgtsOrbitControls } from 'angular-three-soba/controls';
5+
import { injectNgtsGLTFLoader, NgtsGLTF } from 'angular-three-soba/loaders';
6+
import { NgtsAccumulativeShadows, NgtsEnvironment, NgtsRandomizedLights } from 'angular-three-soba/staging';
7+
import * as THREE from 'three';
8+
import { FlakesTexture } from 'three/examples/jsm/textures/FlakesTexture';
9+
import { makeDecorators, makeStoryFunction } from '../setup-canvas';
10+
11+
injectNgtsGLTFLoader.preload(
12+
() => 'https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/suzanne-high-poly/model.gltf',
13+
);
14+
15+
type SuziGLTF = NgtsGLTF<{ materials: { default: THREE.MeshStandardMaterial } }>;
16+
17+
@Component({
18+
selector: 'accumulative-shadows-suzi',
19+
standalone: true,
20+
template: ` <ngt-primitive ngtCompound *args="[model()]" /> `,
21+
imports: [NgtArgs],
22+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
23+
})
24+
class Suzi {
25+
private suziGLTF = injectNgtsGLTFLoader(
26+
() => 'https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/suzanne-high-poly/model.gltf',
27+
) as Signal<SuziGLTF>;
28+
model = computed(() => {
29+
const suzi = this.suziGLTF();
30+
if (!suzi) return null;
31+
return suzi.scene;
32+
});
33+
34+
constructor() {
35+
effect(() => {
36+
const suzi = this.suziGLTF();
37+
if (!suzi) return;
38+
const { scene, materials } = suzi;
39+
scene.traverse((obj: any) => obj.isMesh && (obj.receiveShadow = obj.castShadow = true));
40+
applyProps(materials.default, {
41+
color: 'orange',
42+
roughness: 0,
43+
normalMap: new THREE.CanvasTexture(
44+
new FlakesTexture(),
45+
THREE.UVMapping,
46+
THREE.RepeatWrapping,
47+
THREE.RepeatWrapping,
48+
),
49+
normalScale: [0.05, 0.05],
50+
});
51+
applyProps(materials.default.normalMap, {
52+
flipY: false,
53+
repeat: [40, 40],
54+
});
55+
});
56+
}
57+
}
58+
59+
@Component({
60+
standalone: true,
61+
template: `
62+
<ngt-color *args="['goldenrod']" attach="background" />
63+
64+
<accumulative-shadows-suzi [rotation]="[-0.63, 0, 0]" [scale]="2" [position]="[0, -1.175, 0]" />
65+
<ngts-accumulative-shadows
66+
color="goldenrod"
67+
[temporal]="true"
68+
[frames]="100"
69+
[alphaTest]="0.65"
70+
[opacity]="2"
71+
[scale]="14"
72+
[position]="[0, -0.5, 0]"
73+
>
74+
<ngts-randomized-lights [amount]="8" [radius]="4" [ambient]="0.5" [bias]="0.001" [position]="[5, 5, -10]" />
75+
</ngts-accumulative-shadows>
76+
<ngts-orbit-controls [autoRotate]="true" />
77+
<ngts-environment preset="city" />
78+
`,
79+
imports: [NgtsAccumulativeShadows, NgtsRandomizedLights, NgtsOrbitControls, NgtsEnvironment, NgtArgs, Suzi],
80+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
81+
})
82+
class DefaultAccumulativeShadowsStory {}
83+
84+
export default {
85+
title: 'Staging/Accumulative Shadows',
86+
decorators: makeDecorators(),
87+
} as Meta;
88+
89+
export const Default = makeStoryFunction(DefaultAccumulativeShadowsStory, {
90+
compoundPrefixes: ['accumulative-shadows-suzi'],
91+
// NOTE: only works with this
92+
useLegacyLights: true,
93+
});

0 commit comments

Comments
 (0)