angular-three-soba 4.0.3 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/angular-three-soba-misc.mjs +181 -5
- package/fesm2022/angular-three-soba-misc.mjs.map +1 -1
- package/misc/README.md +19 -0
- package/package.json +1 -1
- package/types/angular-three-soba-abstractions.d.ts +71 -71
- package/types/angular-three-soba-materials.d.ts +2 -2
- package/types/angular-three-soba-misc.d.ts +34 -5
- package/types/angular-three-soba-staging.d.ts +9 -9
|
@@ -243,7 +243,7 @@ function getVersion() {
|
|
|
243
243
|
return parseInt(REVISION.replace(/\D+/g, ''));
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
const defaultOptions$
|
|
246
|
+
const defaultOptions$2 = {
|
|
247
247
|
polygonOffsetFactor: -10,
|
|
248
248
|
debug: false,
|
|
249
249
|
depthTest: false,
|
|
@@ -285,7 +285,7 @@ class NgtsDecal {
|
|
|
285
285
|
/**
|
|
286
286
|
* Decal configuration options including position, scale, rotation, and material properties.
|
|
287
287
|
*/
|
|
288
|
-
this.options = input(defaultOptions$
|
|
288
|
+
this.options = input(defaultOptions$2, { ...(ngDevMode ? { debugName: "options" } : {}), transform: mergeInputs(defaultOptions$2) });
|
|
289
289
|
this.parameters = omit(this.options, [
|
|
290
290
|
'debug',
|
|
291
291
|
'map',
|
|
@@ -1632,7 +1632,7 @@ function surfaceSampler(mesh, { count, transform, weight, instancedMesh, } = {})
|
|
|
1632
1632
|
return new THREE.InstancedBufferAttribute(initialBufferAttribute.array, initialBufferAttribute.itemSize).copy(initialBufferAttribute);
|
|
1633
1633
|
});
|
|
1634
1634
|
}
|
|
1635
|
-
const defaultOptions = {
|
|
1635
|
+
const defaultOptions$1 = {
|
|
1636
1636
|
count: 16,
|
|
1637
1637
|
};
|
|
1638
1638
|
/**
|
|
@@ -1677,7 +1677,7 @@ class NgtsSampler {
|
|
|
1677
1677
|
/**
|
|
1678
1678
|
* Sampler configuration including count, weight attribute, and transform function.
|
|
1679
1679
|
*/
|
|
1680
|
-
this.options = input(defaultOptions, { ...(ngDevMode ? { debugName: "options" } : {}), transform: mergeInputs(defaultOptions) });
|
|
1680
|
+
this.options = input(defaultOptions$1, { ...(ngDevMode ? { debugName: "options" } : {}), transform: mergeInputs(defaultOptions$1) });
|
|
1681
1681
|
this.parameters = omit(this.options, ['weight', 'transform', 'count']);
|
|
1682
1682
|
this.groupRef = viewChild.required('group');
|
|
1683
1683
|
this.count = pick(this.options, 'count');
|
|
@@ -1796,9 +1796,185 @@ function calculateScaleFactor(point3, radiusPx, camera, size) {
|
|
|
1796
1796
|
return scale;
|
|
1797
1797
|
}
|
|
1798
1798
|
|
|
1799
|
+
/*
|
|
1800
|
+
* Integration and compilation: @N8Programs
|
|
1801
|
+
* Inspired by:
|
|
1802
|
+
* https://github.com/mrdoob/three.js/blob/dev/examples/webgl_shadowmap_pcss.html
|
|
1803
|
+
* https://developer.nvidia.com/gpugems/gpugems2/part-ii-shading-lighting-and-shadows/chapter-17-efficient-soft-edged-shadows-using
|
|
1804
|
+
* https://developer.download.nvidia.com/whitepapers/2008/PCSS_Integration.pdf
|
|
1805
|
+
* https://github.com/mrdoob/three.js/blob/master/examples/webgl_shadowmap_pcss.html [spidersharma03]
|
|
1806
|
+
* https://spline.design/
|
|
1807
|
+
* Concept:
|
|
1808
|
+
* https://www.gamedev.net/tutorials/programming/graphics/contact-hardening-soft-shadows-made-fast-r4906/
|
|
1809
|
+
* Vogel Disk Implementation:
|
|
1810
|
+
* https://www.shadertoy.com/view/4l3yRM [ashalah]
|
|
1811
|
+
* High-Frequency Noise Implementation:
|
|
1812
|
+
* https://www.shadertoy.com/view/tt3fDH [spawner64]
|
|
1813
|
+
*/
|
|
1814
|
+
const defaultOptions = {
|
|
1815
|
+
size: 25,
|
|
1816
|
+
samples: 10,
|
|
1817
|
+
focus: 0,
|
|
1818
|
+
};
|
|
1819
|
+
function pcss(options) {
|
|
1820
|
+
const { focus, size, samples } = options;
|
|
1821
|
+
// Three.js r182 removed unpackRGBAToDepth and switched to native depth textures
|
|
1822
|
+
const useNativeDepth = getVersion() >= 182;
|
|
1823
|
+
const sampleDepth = useNativeDepth
|
|
1824
|
+
? 'texture2D( shadowMap, uv + offset ).r'
|
|
1825
|
+
: 'unpackRGBAToDepth( texture2D( shadowMap, uv + offset ) )';
|
|
1826
|
+
return `
|
|
1827
|
+
#define PENUMBRA_FILTER_SIZE float(${size})
|
|
1828
|
+
#define RGB_NOISE_FUNCTION(uv) (randRGB(uv))
|
|
1829
|
+
vec3 randRGB(vec2 uv) {
|
|
1830
|
+
return vec3(
|
|
1831
|
+
fract(sin(dot(uv, vec2(12.75613, 38.12123))) * 13234.76575),
|
|
1832
|
+
fract(sin(dot(uv, vec2(19.45531, 58.46547))) * 43678.23431),
|
|
1833
|
+
fract(sin(dot(uv, vec2(23.67817, 78.23121))) * 93567.23423)
|
|
1834
|
+
);
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
vec3 lowPassRandRGB(vec2 uv) {
|
|
1838
|
+
// 3x3 convolution (average)
|
|
1839
|
+
// can be implemented as separable with an extra buffer for a total of 6 samples instead of 9
|
|
1840
|
+
vec3 result = vec3(0);
|
|
1841
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(-1.0, -1.0));
|
|
1842
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(-1.0, 0.0));
|
|
1843
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(-1.0, +1.0));
|
|
1844
|
+
result += RGB_NOISE_FUNCTION(uv + vec2( 0.0, -1.0));
|
|
1845
|
+
result += RGB_NOISE_FUNCTION(uv + vec2( 0.0, 0.0));
|
|
1846
|
+
result += RGB_NOISE_FUNCTION(uv + vec2( 0.0, +1.0));
|
|
1847
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, -1.0));
|
|
1848
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, 0.0));
|
|
1849
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, +1.0));
|
|
1850
|
+
result *= 0.111111111; // 1.0 / 9.0
|
|
1851
|
+
return result;
|
|
1852
|
+
}
|
|
1853
|
+
vec3 highPassRandRGB(vec2 uv) {
|
|
1854
|
+
// by subtracting the low-pass signal from the original signal, we're being left with the high-pass signal
|
|
1855
|
+
// hp(x) = x - lp(x)
|
|
1856
|
+
return RGB_NOISE_FUNCTION(uv) - lowPassRandRGB(uv) + 0.5;
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
vec2 vogelDiskSample(int sampleIndex, int sampleCount, float angle) {
|
|
1861
|
+
const float goldenAngle = 2.399963f; // radians
|
|
1862
|
+
float r = sqrt(float(sampleIndex) + 0.5f) / sqrt(float(sampleCount));
|
|
1863
|
+
float theta = float(sampleIndex) * goldenAngle + angle;
|
|
1864
|
+
float sine = sin(theta);
|
|
1865
|
+
float cosine = cos(theta);
|
|
1866
|
+
return vec2(cosine, sine) * r;
|
|
1867
|
+
}
|
|
1868
|
+
float penumbraSize( const in float zReceiver, const in float zBlocker ) { // Parallel plane estimation
|
|
1869
|
+
return (zReceiver - zBlocker) / zBlocker;
|
|
1870
|
+
}
|
|
1871
|
+
float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
1872
|
+
float texelSize = 1.0 / float(textureSize(shadowMap, 0).x);
|
|
1873
|
+
float blockerDepthSum = float(${focus});
|
|
1874
|
+
float blockers = 0.0;
|
|
1875
|
+
|
|
1876
|
+
int j = 0;
|
|
1877
|
+
vec2 offset = vec2(0.);
|
|
1878
|
+
float depth = 0.;
|
|
1879
|
+
|
|
1880
|
+
#pragma unroll_loop_start
|
|
1881
|
+
for(int i = 0; i < ${samples}; i ++) {
|
|
1882
|
+
offset = (vogelDiskSample(j, ${samples}, angle) * texelSize) * 2.0 * PENUMBRA_FILTER_SIZE;
|
|
1883
|
+
depth = ${sampleDepth};
|
|
1884
|
+
if (depth < compare) {
|
|
1885
|
+
blockerDepthSum += depth;
|
|
1886
|
+
blockers++;
|
|
1887
|
+
}
|
|
1888
|
+
j++;
|
|
1889
|
+
}
|
|
1890
|
+
#pragma unroll_loop_end
|
|
1891
|
+
|
|
1892
|
+
if (blockers > 0.0) {
|
|
1893
|
+
return blockerDepthSum / blockers;
|
|
1894
|
+
}
|
|
1895
|
+
return -1.0;
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
|
|
1899
|
+
float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRadius, float angle) {
|
|
1900
|
+
float texelSize = 1.0 / float(textureSize(shadowMap, 0).x);
|
|
1901
|
+
float shadow = 0.0f;
|
|
1902
|
+
int j = 0;
|
|
1903
|
+
vec2 vogelSample = vec2(0.0);
|
|
1904
|
+
vec2 offset = vec2(0.0);
|
|
1905
|
+
#pragma unroll_loop_start
|
|
1906
|
+
for (int i = 0; i < ${samples}; i++) {
|
|
1907
|
+
vogelSample = vogelDiskSample(j, ${samples}, angle) * texelSize;
|
|
1908
|
+
offset = vogelSample * (1.0 + filterRadius * float(${size}));
|
|
1909
|
+
shadow += step( zReceiver, ${sampleDepth} );
|
|
1910
|
+
j++;
|
|
1911
|
+
}
|
|
1912
|
+
#pragma unroll_loop_end
|
|
1913
|
+
return shadow * 1.0 / ${samples}.0;
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
float PCSS (sampler2D shadowMap, vec4 coords) {
|
|
1917
|
+
vec2 uv = coords.xy;
|
|
1918
|
+
float zReceiver = coords.z; // Assumed to be eye-space z in this code
|
|
1919
|
+
float angle = highPassRandRGB(gl_FragCoord.xy).r * PI2;
|
|
1920
|
+
float avgBlockerDepth = findBlocker(shadowMap, uv, zReceiver, angle);
|
|
1921
|
+
if (avgBlockerDepth == -1.0) {
|
|
1922
|
+
return 1.0;
|
|
1923
|
+
}
|
|
1924
|
+
float penumbraRatio = penumbraSize(zReceiver, avgBlockerDepth);
|
|
1925
|
+
return vogelFilter(shadowMap, uv, zReceiver, 1.25 * penumbraRatio, angle);
|
|
1926
|
+
}`;
|
|
1927
|
+
}
|
|
1928
|
+
function reset(gl, scene, camera) {
|
|
1929
|
+
scene.traverse((object) => {
|
|
1930
|
+
if (object.material) {
|
|
1931
|
+
gl.properties.remove(object.material);
|
|
1932
|
+
object.material.dispose?.();
|
|
1933
|
+
}
|
|
1934
|
+
});
|
|
1935
|
+
gl.info.programs.length = 0;
|
|
1936
|
+
gl.compile(scene, camera);
|
|
1937
|
+
}
|
|
1938
|
+
/**
|
|
1939
|
+
* A directive that injects Percentage-Closer Soft Shadows (PCSS) into the scene.
|
|
1940
|
+
*
|
|
1941
|
+
* PCSS produces contact-hardening soft shadows where shadows are sharper near the
|
|
1942
|
+
* contact point and softer further away, creating more realistic shadow effects.
|
|
1943
|
+
*
|
|
1944
|
+
* @example
|
|
1945
|
+
* ```html
|
|
1946
|
+
* <ngts-soft-shadows [options]="{ size: 25, samples: 10, focus: 0 }" />
|
|
1947
|
+
* ```
|
|
1948
|
+
*/
|
|
1949
|
+
class NgtsSoftShadows {
|
|
1950
|
+
constructor() {
|
|
1951
|
+
this.options = input(defaultOptions, { ...(ngDevMode ? { debugName: "options" } : {}), transform: mergeInputs(defaultOptions) });
|
|
1952
|
+
const store = injectStore();
|
|
1953
|
+
effect((onCleanup) => {
|
|
1954
|
+
const { gl, scene, camera } = store.snapshot;
|
|
1955
|
+
const options = this.options();
|
|
1956
|
+
const original = THREE.ShaderChunk.shadowmap_pars_fragment;
|
|
1957
|
+
THREE.ShaderChunk.shadowmap_pars_fragment = THREE.ShaderChunk.shadowmap_pars_fragment
|
|
1958
|
+
.replace('#ifdef USE_SHADOWMAP', '#ifdef USE_SHADOWMAP\n' + pcss(options))
|
|
1959
|
+
.replace('#if defined( SHADOWMAP_TYPE_PCF )', '\nreturn PCSS(shadowMap, shadowCoord);\n#if defined( SHADOWMAP_TYPE_PCF )');
|
|
1960
|
+
reset(gl, scene, camera);
|
|
1961
|
+
onCleanup(() => {
|
|
1962
|
+
THREE.ShaderChunk.shadowmap_pars_fragment = original;
|
|
1963
|
+
reset(gl, scene, camera);
|
|
1964
|
+
});
|
|
1965
|
+
});
|
|
1966
|
+
}
|
|
1967
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtsSoftShadows, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1968
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtsSoftShadows, isStandalone: true, selector: "ngts-soft-shadows", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
1969
|
+
}
|
|
1970
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtsSoftShadows, decorators: [{
|
|
1971
|
+
type: Directive,
|
|
1972
|
+
args: [{ selector: 'ngts-soft-shadows' }]
|
|
1973
|
+
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }] } });
|
|
1974
|
+
|
|
1799
1975
|
/**
|
|
1800
1976
|
* Generated bundle index. Do not edit.
|
|
1801
1977
|
*/
|
|
1802
1978
|
|
|
1803
|
-
export { NgtsBakeShadows, NgtsComputedAttribute, NgtsDecal, NgtsFBO, NgtsHTML, NgtsHTMLContent, NgtsHTMLImpl, NgtsIntersect, NgtsPreload, NgtsSampler, animations, calculateScaleFactor, depthBuffer, fbo, getVersion, injectAnimations, injectDepthBuffer, injectFBO, injectIntersect, intersect, setUpdateRange, surfaceSampler };
|
|
1979
|
+
export { NgtsBakeShadows, NgtsComputedAttribute, NgtsDecal, NgtsFBO, NgtsHTML, NgtsHTMLContent, NgtsHTMLImpl, NgtsIntersect, NgtsPreload, NgtsSampler, NgtsSoftShadows, animations, calculateScaleFactor, depthBuffer, fbo, getVersion, injectAnimations, injectDepthBuffer, injectFBO, injectIntersect, intersect, setUpdateRange, surfaceSampler };
|
|
1804
1980
|
//# sourceMappingURL=angular-three-soba-misc.mjs.map
|