angular-three-soba 4.0.4 → 4.0.6
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 +152 -16
- package/fesm2022/angular-three-soba-misc.mjs.map +1 -1
- package/package.json +1 -1
- package/types/angular-three-soba-abstractions.d.ts +71 -71
- package/types/angular-three-soba-cameras.d.ts +3 -3
- package/types/angular-three-soba-gizmos.d.ts +3 -3
- package/types/angular-three-soba-materials.d.ts +5 -5
- package/types/angular-three-soba-performances.d.ts +5 -5
- package/types/angular-three-soba-shaders.d.ts +2 -2
|
@@ -1816,7 +1816,10 @@ const defaultOptions = {
|
|
|
1816
1816
|
samples: 10,
|
|
1817
1817
|
focus: 0,
|
|
1818
1818
|
};
|
|
1819
|
-
|
|
1819
|
+
/**
|
|
1820
|
+
* Generates PCSS shader code for Three.js < r182 (uses RGBA-packed depth)
|
|
1821
|
+
*/
|
|
1822
|
+
function pcssLegacy(options) {
|
|
1820
1823
|
const { focus, size, samples } = options;
|
|
1821
1824
|
return `
|
|
1822
1825
|
#define PENUMBRA_FILTER_SIZE float(${size})
|
|
@@ -1830,8 +1833,6 @@ vec3 randRGB(vec2 uv) {
|
|
|
1830
1833
|
}
|
|
1831
1834
|
|
|
1832
1835
|
vec3 lowPassRandRGB(vec2 uv) {
|
|
1833
|
-
// 3x3 convolution (average)
|
|
1834
|
-
// can be implemented as separable with an extra buffer for a total of 6 samples instead of 9
|
|
1835
1836
|
vec3 result = vec3(0);
|
|
1836
1837
|
result += RGB_NOISE_FUNCTION(uv + vec2(-1.0, -1.0));
|
|
1837
1838
|
result += RGB_NOISE_FUNCTION(uv + vec2(-1.0, 0.0));
|
|
@@ -1842,32 +1843,31 @@ vec3 lowPassRandRGB(vec2 uv) {
|
|
|
1842
1843
|
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, -1.0));
|
|
1843
1844
|
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, 0.0));
|
|
1844
1845
|
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, +1.0));
|
|
1845
|
-
result *= 0.111111111;
|
|
1846
|
+
result *= 0.111111111;
|
|
1846
1847
|
return result;
|
|
1847
1848
|
}
|
|
1849
|
+
|
|
1848
1850
|
vec3 highPassRandRGB(vec2 uv) {
|
|
1849
|
-
// by subtracting the low-pass signal from the original signal, we're being left with the high-pass signal
|
|
1850
|
-
// hp(x) = x - lp(x)
|
|
1851
1851
|
return RGB_NOISE_FUNCTION(uv) - lowPassRandRGB(uv) + 0.5;
|
|
1852
1852
|
}
|
|
1853
1853
|
|
|
1854
|
-
|
|
1855
1854
|
vec2 vogelDiskSample(int sampleIndex, int sampleCount, float angle) {
|
|
1856
|
-
const float goldenAngle = 2.399963f;
|
|
1855
|
+
const float goldenAngle = 2.399963f;
|
|
1857
1856
|
float r = sqrt(float(sampleIndex) + 0.5f) / sqrt(float(sampleCount));
|
|
1858
1857
|
float theta = float(sampleIndex) * goldenAngle + angle;
|
|
1859
1858
|
float sine = sin(theta);
|
|
1860
1859
|
float cosine = cos(theta);
|
|
1861
1860
|
return vec2(cosine, sine) * r;
|
|
1862
1861
|
}
|
|
1863
|
-
|
|
1862
|
+
|
|
1863
|
+
float penumbraSize( const in float zReceiver, const in float zBlocker ) {
|
|
1864
1864
|
return (zReceiver - zBlocker) / zBlocker;
|
|
1865
1865
|
}
|
|
1866
|
+
|
|
1866
1867
|
float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
1867
1868
|
float texelSize = 1.0 / float(textureSize(shadowMap, 0).x);
|
|
1868
1869
|
float blockerDepthSum = float(${focus});
|
|
1869
1870
|
float blockers = 0.0;
|
|
1870
|
-
|
|
1871
1871
|
int j = 0;
|
|
1872
1872
|
vec2 offset = vec2(0.);
|
|
1873
1873
|
float depth = 0.;
|
|
@@ -1875,7 +1875,7 @@ float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
|
1875
1875
|
#pragma unroll_loop_start
|
|
1876
1876
|
for(int i = 0; i < ${samples}; i ++) {
|
|
1877
1877
|
offset = (vogelDiskSample(j, ${samples}, angle) * texelSize) * 2.0 * PENUMBRA_FILTER_SIZE;
|
|
1878
|
-
depth = unpackRGBAToDepth( texture2D( shadowMap, uv + offset));
|
|
1878
|
+
depth = unpackRGBAToDepth( texture2D( shadowMap, uv + offset ) );
|
|
1879
1879
|
if (depth < compare) {
|
|
1880
1880
|
blockerDepthSum += depth;
|
|
1881
1881
|
blockers++;
|
|
@@ -1890,13 +1890,13 @@ float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
|
1890
1890
|
return -1.0;
|
|
1891
1891
|
}
|
|
1892
1892
|
|
|
1893
|
-
|
|
1894
1893
|
float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRadius, float angle) {
|
|
1895
1894
|
float texelSize = 1.0 / float(textureSize(shadowMap, 0).x);
|
|
1896
1895
|
float shadow = 0.0f;
|
|
1897
1896
|
int j = 0;
|
|
1898
1897
|
vec2 vogelSample = vec2(0.0);
|
|
1899
1898
|
vec2 offset = vec2(0.0);
|
|
1899
|
+
|
|
1900
1900
|
#pragma unroll_loop_start
|
|
1901
1901
|
for (int i = 0; i < ${samples}; i++) {
|
|
1902
1902
|
vogelSample = vogelDiskSample(j, ${samples}, angle) * texelSize;
|
|
@@ -1905,12 +1905,13 @@ float vogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRad
|
|
|
1905
1905
|
j++;
|
|
1906
1906
|
}
|
|
1907
1907
|
#pragma unroll_loop_end
|
|
1908
|
+
|
|
1908
1909
|
return shadow * 1.0 / ${samples}.0;
|
|
1909
1910
|
}
|
|
1910
1911
|
|
|
1911
1912
|
float PCSS (sampler2D shadowMap, vec4 coords) {
|
|
1912
1913
|
vec2 uv = coords.xy;
|
|
1913
|
-
float zReceiver = coords.z;
|
|
1914
|
+
float zReceiver = coords.z;
|
|
1914
1915
|
float angle = highPassRandRGB(gl_FragCoord.xy).r * PI2;
|
|
1915
1916
|
float avgBlockerDepth = findBlocker(shadowMap, uv, zReceiver, angle);
|
|
1916
1917
|
if (avgBlockerDepth == -1.0) {
|
|
@@ -1920,6 +1921,127 @@ float PCSS (sampler2D shadowMap, vec4 coords) {
|
|
|
1920
1921
|
return vogelFilter(shadowMap, uv, zReceiver, 1.25 * penumbraRatio, angle);
|
|
1921
1922
|
}`;
|
|
1922
1923
|
}
|
|
1924
|
+
/**
|
|
1925
|
+
* Generates PCSS shader code for Three.js >= r182 (uses native depth textures)
|
|
1926
|
+
*/
|
|
1927
|
+
function pcssModern(options) {
|
|
1928
|
+
const { focus, size, samples } = options;
|
|
1929
|
+
return `
|
|
1930
|
+
#define PENUMBRA_FILTER_SIZE float(${size})
|
|
1931
|
+
#define RGB_NOISE_FUNCTION(uv) (randRGB(uv))
|
|
1932
|
+
vec3 randRGB(vec2 uv) {
|
|
1933
|
+
return vec3(
|
|
1934
|
+
fract(sin(dot(uv, vec2(12.75613, 38.12123))) * 13234.76575),
|
|
1935
|
+
fract(sin(dot(uv, vec2(19.45531, 58.46547))) * 43678.23431),
|
|
1936
|
+
fract(sin(dot(uv, vec2(23.67817, 78.23121))) * 93567.23423)
|
|
1937
|
+
);
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
vec3 lowPassRandRGB(vec2 uv) {
|
|
1941
|
+
vec3 result = vec3(0);
|
|
1942
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(-1.0, -1.0));
|
|
1943
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(-1.0, 0.0));
|
|
1944
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(-1.0, +1.0));
|
|
1945
|
+
result += RGB_NOISE_FUNCTION(uv + vec2( 0.0, -1.0));
|
|
1946
|
+
result += RGB_NOISE_FUNCTION(uv + vec2( 0.0, 0.0));
|
|
1947
|
+
result += RGB_NOISE_FUNCTION(uv + vec2( 0.0, +1.0));
|
|
1948
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, -1.0));
|
|
1949
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, 0.0));
|
|
1950
|
+
result += RGB_NOISE_FUNCTION(uv + vec2(+1.0, +1.0));
|
|
1951
|
+
result *= 0.111111111;
|
|
1952
|
+
return result;
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
vec3 highPassRandRGB(vec2 uv) {
|
|
1956
|
+
return RGB_NOISE_FUNCTION(uv) - lowPassRandRGB(uv) + 0.5;
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
vec2 pcssVogelDiskSample(int sampleIndex, int sampleCount, float angle) {
|
|
1960
|
+
const float goldenAngle = 2.399963f;
|
|
1961
|
+
float r = sqrt(float(sampleIndex) + 0.5f) / sqrt(float(sampleCount));
|
|
1962
|
+
float theta = float(sampleIndex) * goldenAngle + angle;
|
|
1963
|
+
float sine = sin(theta);
|
|
1964
|
+
float cosine = cos(theta);
|
|
1965
|
+
return vec2(cosine, sine) * r;
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
float penumbraSize( const in float zReceiver, const in float zBlocker ) {
|
|
1969
|
+
return (zReceiver - zBlocker) / zBlocker;
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
float findBlocker(sampler2D shadowMap, vec2 uv, float compare, float angle) {
|
|
1973
|
+
float texelSize = 1.0 / float(textureSize(shadowMap, 0).x);
|
|
1974
|
+
float blockerDepthSum = float(${focus});
|
|
1975
|
+
float blockers = 0.0;
|
|
1976
|
+
int j = 0;
|
|
1977
|
+
vec2 offset = vec2(0.);
|
|
1978
|
+
float depth = 0.;
|
|
1979
|
+
|
|
1980
|
+
#pragma unroll_loop_start
|
|
1981
|
+
for(int i = 0; i < ${samples}; i ++) {
|
|
1982
|
+
offset = (pcssVogelDiskSample(j, ${samples}, angle) * texelSize) * 2.0 * PENUMBRA_FILTER_SIZE;
|
|
1983
|
+
depth = texture2D( shadowMap, uv + offset ).r;
|
|
1984
|
+
if (depth < compare) {
|
|
1985
|
+
blockerDepthSum += depth;
|
|
1986
|
+
blockers++;
|
|
1987
|
+
}
|
|
1988
|
+
j++;
|
|
1989
|
+
}
|
|
1990
|
+
#pragma unroll_loop_end
|
|
1991
|
+
|
|
1992
|
+
if (blockers > 0.0) {
|
|
1993
|
+
return blockerDepthSum / blockers;
|
|
1994
|
+
}
|
|
1995
|
+
return -1.0;
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
float pcssVogelFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRadius, float angle) {
|
|
1999
|
+
float texelSize = 1.0 / float(textureSize(shadowMap, 0).x);
|
|
2000
|
+
float shadow = 0.0f;
|
|
2001
|
+
int j = 0;
|
|
2002
|
+
vec2 vogelSample = vec2(0.0);
|
|
2003
|
+
vec2 offset = vec2(0.0);
|
|
2004
|
+
|
|
2005
|
+
#pragma unroll_loop_start
|
|
2006
|
+
for (int i = 0; i < ${samples}; i++) {
|
|
2007
|
+
vogelSample = pcssVogelDiskSample(j, ${samples}, angle) * texelSize;
|
|
2008
|
+
offset = vogelSample * (1.0 + filterRadius * float(${size}));
|
|
2009
|
+
shadow += step( zReceiver, texture2D( shadowMap, uv + offset ).r );
|
|
2010
|
+
j++;
|
|
2011
|
+
}
|
|
2012
|
+
#pragma unroll_loop_end
|
|
2013
|
+
|
|
2014
|
+
return shadow * 1.0 / ${samples}.0;
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
float PCSS (sampler2D shadowMap, vec4 coords, float shadowIntensity) {
|
|
2018
|
+
vec2 uv = coords.xy;
|
|
2019
|
+
float zReceiver = coords.z;
|
|
2020
|
+
float angle = highPassRandRGB(gl_FragCoord.xy).r * PI2;
|
|
2021
|
+
float avgBlockerDepth = findBlocker(shadowMap, uv, zReceiver, angle);
|
|
2022
|
+
if (avgBlockerDepth == -1.0) {
|
|
2023
|
+
return 1.0;
|
|
2024
|
+
}
|
|
2025
|
+
float penumbraRatio = penumbraSize(zReceiver, avgBlockerDepth);
|
|
2026
|
+
float shadow = pcssVogelFilter(shadowMap, uv, zReceiver, 1.25 * penumbraRatio, angle);
|
|
2027
|
+
return mix( 1.0, shadow, shadowIntensity );
|
|
2028
|
+
}`;
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
2031
|
+
* Generates the replacement getShadow function for r182+
|
|
2032
|
+
*/
|
|
2033
|
+
function getShadowReplacement() {
|
|
2034
|
+
return `float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
|
|
2035
|
+
shadowCoord.xyz /= shadowCoord.w;
|
|
2036
|
+
shadowCoord.z += shadowBias;
|
|
2037
|
+
bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;
|
|
2038
|
+
bool frustumTest = inFrustum && shadowCoord.z <= 1.0;
|
|
2039
|
+
if ( frustumTest ) {
|
|
2040
|
+
return PCSS( shadowMap, shadowCoord, shadowIntensity );
|
|
2041
|
+
}
|
|
2042
|
+
return 1.0;
|
|
2043
|
+
}`;
|
|
2044
|
+
}
|
|
1923
2045
|
function reset(gl, scene, camera) {
|
|
1924
2046
|
scene.traverse((object) => {
|
|
1925
2047
|
if (object.material) {
|
|
@@ -1948,10 +2070,24 @@ class NgtsSoftShadows {
|
|
|
1948
2070
|
effect((onCleanup) => {
|
|
1949
2071
|
const { gl, scene, camera } = store.snapshot;
|
|
1950
2072
|
const options = this.options();
|
|
2073
|
+
const version = getVersion();
|
|
1951
2074
|
const original = THREE.ShaderChunk.shadowmap_pars_fragment;
|
|
1952
|
-
|
|
1953
|
-
.
|
|
1954
|
-
|
|
2075
|
+
if (version >= 182) {
|
|
2076
|
+
// Three.js r182+ uses native depth textures and has a different shader structure
|
|
2077
|
+
// We need to replace the getShadow function entirely
|
|
2078
|
+
const pcssCode = pcssModern(options);
|
|
2079
|
+
// Find and replace the PCF getShadow function
|
|
2080
|
+
const getShadowRegex = /(#if defined\( SHADOWMAP_TYPE_PCF \)\s+float getShadow\( sampler2DShadow shadowMap[^}]+\})/s;
|
|
2081
|
+
THREE.ShaderChunk.shadowmap_pars_fragment = THREE.ShaderChunk.shadowmap_pars_fragment
|
|
2082
|
+
.replace('#ifdef USE_SHADOWMAP', '#ifdef USE_SHADOWMAP\n' + pcssCode)
|
|
2083
|
+
.replace(getShadowRegex, `#if defined( SHADOWMAP_TYPE_PCF )\n\t\t${getShadowReplacement()}`);
|
|
2084
|
+
}
|
|
2085
|
+
else {
|
|
2086
|
+
// Three.js < r182 uses RGBA-packed depth
|
|
2087
|
+
THREE.ShaderChunk.shadowmap_pars_fragment = THREE.ShaderChunk.shadowmap_pars_fragment
|
|
2088
|
+
.replace('#ifdef USE_SHADOWMAP', '#ifdef USE_SHADOWMAP\n' + pcssLegacy(options))
|
|
2089
|
+
.replace('#if defined( SHADOWMAP_TYPE_PCF )', '\nreturn PCSS(shadowMap, shadowCoord);\n#if defined( SHADOWMAP_TYPE_PCF )');
|
|
2090
|
+
}
|
|
1955
2091
|
reset(gl, scene, camera);
|
|
1956
2092
|
onCleanup(() => {
|
|
1957
2093
|
THREE.ShaderChunk.shadowmap_pars_fragment = original;
|