@takram/three-clouds 0.1.0
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/CHANGELOG.md +5 -0
- package/README.md +1130 -0
- package/assets/local_weather.png +0 -0
- package/assets/shape.bin +1 -0
- package/assets/shape_detail.bin +1 -0
- package/assets/turbulence.png +0 -0
- package/build/index.cjs +583 -0
- package/build/index.cjs.map +1 -0
- package/build/index.js +728 -0
- package/build/index.js.map +1 -0
- package/build/r3f.cjs +2 -0
- package/build/r3f.cjs.map +1 -0
- package/build/r3f.js +205 -0
- package/build/r3f.js.map +1 -0
- package/build/shared.cjs +2189 -0
- package/build/shared.cjs.map +1 -0
- package/build/shared.js +3825 -0
- package/build/shared.js.map +1 -0
- package/package.json +77 -0
- package/src/CascadedShadowMaps.ts +288 -0
- package/src/CloudLayer.ts +85 -0
- package/src/CloudLayers.test.ts +61 -0
- package/src/CloudLayers.ts +181 -0
- package/src/CloudShape.ts +22 -0
- package/src/CloudShapeDetail.ts +22 -0
- package/src/CloudsEffect.ts +810 -0
- package/src/CloudsMaterial.ts +467 -0
- package/src/CloudsPass.ts +285 -0
- package/src/CloudsResolveMaterial.ts +108 -0
- package/src/DensityProfile.ts +38 -0
- package/src/LocalWeather.ts +21 -0
- package/src/PassBase.ts +28 -0
- package/src/Procedural3DTexture.ts +94 -0
- package/src/ProceduralTexture.ts +94 -0
- package/src/ShaderArrayPass.ts +32 -0
- package/src/ShadowMaterial.ts +141 -0
- package/src/ShadowPass.ts +185 -0
- package/src/ShadowResolveMaterial.ts +72 -0
- package/src/Turbulence.ts +21 -0
- package/src/bayer.ts +23 -0
- package/src/constants.ts +8 -0
- package/src/helpers/FrustumCorners.ts +138 -0
- package/src/helpers/setArrayRenderTargetLayers.ts +32 -0
- package/src/helpers/splitFrustum.ts +59 -0
- package/src/index.ts +14 -0
- package/src/qualityPresets.ts +117 -0
- package/src/r3f/CloudLayer.tsx +95 -0
- package/src/r3f/CloudLayers.tsx +54 -0
- package/src/r3f/Clouds.tsx +278 -0
- package/src/r3f/index.ts +2 -0
- package/src/shaders/catmullRomSampling.glsl +113 -0
- package/src/shaders/cloudShape.frag +78 -0
- package/src/shaders/cloudShapeDetail.frag +56 -0
- package/src/shaders/clouds.frag +996 -0
- package/src/shaders/clouds.glsl +190 -0
- package/src/shaders/clouds.vert +69 -0
- package/src/shaders/cloudsEffect.frag +11 -0
- package/src/shaders/cloudsResolve.frag +202 -0
- package/src/shaders/cloudsResolve.vert +10 -0
- package/src/shaders/localWeather.frag +83 -0
- package/src/shaders/parameters.glsl +64 -0
- package/src/shaders/perlin.glsl +211 -0
- package/src/shaders/shadow.frag +197 -0
- package/src/shaders/shadow.vert +16 -0
- package/src/shaders/shadowResolve.frag +76 -0
- package/src/shaders/shadowResolve.vert +10 -0
- package/src/shaders/structuredSampling.glsl +101 -0
- package/src/shaders/tileableNoise.glsl +88 -0
- package/src/shaders/turbulence.frag +51 -0
- package/src/shaders/types.glsl +18 -0
- package/src/shaders/varianceClipping.glsl +114 -0
- package/src/uniforms.ts +218 -0
- package/types/CascadedShadowMaps.d.ts +52 -0
- package/types/CloudLayer.d.ts +26 -0
- package/types/CloudLayers.d.ts +21 -0
- package/types/CloudShape.d.ts +5 -0
- package/types/CloudShapeDetail.d.ts +5 -0
- package/types/CloudsEffect.d.ts +170 -0
- package/types/CloudsMaterial.d.ts +86 -0
- package/types/CloudsPass.d.ts +44 -0
- package/types/CloudsResolveMaterial.d.ts +30 -0
- package/types/DensityProfile.d.ts +12 -0
- package/types/LocalWeather.d.ts +5 -0
- package/types/PassBase.d.ts +14 -0
- package/types/Procedural3DTexture.d.ts +20 -0
- package/types/ProceduralTexture.d.ts +24 -0
- package/types/ShaderArrayPass.d.ts +7 -0
- package/types/ShadowMaterial.d.ts +34 -0
- package/types/ShadowPass.d.ts +34 -0
- package/types/ShadowResolveMaterial.d.ts +20 -0
- package/types/Turbulence.d.ts +5 -0
- package/types/bayer.d.ts +4 -0
- package/types/constants.d.ts +6 -0
- package/types/helpers/FrustumCorners.d.ts +18 -0
- package/types/helpers/setArrayRenderTargetLayers.d.ts +3 -0
- package/types/helpers/splitFrustum.d.ts +9 -0
- package/types/index.d.ts +13 -0
- package/types/qualityPresets.d.ts +46 -0
- package/types/r3f/CloudLayer.d.ts +7 -0
- package/types/r3f/CloudLayers.d.ts +15 -0
- package/types/r3f/Clouds.d.ts +16 -0
- package/types/r3f/index.d.ts +2 -0
- package/types/uniforms.d.ts +66 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
precision highp float;
|
2
|
+
precision highp int;
|
3
|
+
|
4
|
+
#include "core/math"
|
5
|
+
#include "perlin"
|
6
|
+
#include "tileableNoise"
|
7
|
+
|
8
|
+
in vec2 vUv;
|
9
|
+
|
10
|
+
layout(location = 0) out vec4 outputColor;
|
11
|
+
|
12
|
+
const vec3 frequency = vec3(12.0);
|
13
|
+
const int octaveCount = 3;
|
14
|
+
|
15
|
+
float perlin(const vec3 point) {
|
16
|
+
return getPerlinNoise(point, frequency, octaveCount);
|
17
|
+
}
|
18
|
+
|
19
|
+
vec3 perlin3d(const vec3 point) {
|
20
|
+
float perlin1 = perlin(point);
|
21
|
+
float perlin2 = perlin(point.yzx + vec3(-19.1, 33.4, 47.2));
|
22
|
+
float perlin3 = perlin(point.zxy + vec3(74.2, -124.5, 99.4));
|
23
|
+
return vec3(perlin1, perlin2, perlin3);
|
24
|
+
}
|
25
|
+
|
26
|
+
vec3 curl(vec3 point) {
|
27
|
+
const float delta = 0.1;
|
28
|
+
vec3 dx = vec3(delta, 0.0, 0.0);
|
29
|
+
vec3 dy = vec3(0.0, delta, 0.0);
|
30
|
+
vec3 dz = vec3(0.0, 0.0, delta);
|
31
|
+
|
32
|
+
vec3 px0 = perlin3d(point - dx);
|
33
|
+
vec3 px1 = perlin3d(point + dx);
|
34
|
+
vec3 py0 = perlin3d(point - dy);
|
35
|
+
vec3 py1 = perlin3d(point + dy);
|
36
|
+
vec3 pz0 = perlin3d(point - dz);
|
37
|
+
vec3 pz1 = perlin3d(point + dz);
|
38
|
+
|
39
|
+
float x = py1.z - py0.z - pz1.y + pz0.y;
|
40
|
+
float y = pz1.x - pz0.x - px1.z + px0.z;
|
41
|
+
float z = px1.y - px0.y - py1.x + py0.x;
|
42
|
+
|
43
|
+
const float divisor = 1.0 / (2.0 * delta);
|
44
|
+
return normalize(vec3(x, y, z) * divisor);
|
45
|
+
}
|
46
|
+
|
47
|
+
void main() {
|
48
|
+
vec3 point = vec3(vUv.x, vUv.y, 0.0);
|
49
|
+
outputColor.rgb = 0.5 * curl(point) + 0.5;
|
50
|
+
outputColor.a = 1.0;
|
51
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
struct GroundIrradiance {
|
2
|
+
vec3 sun;
|
3
|
+
vec3 sky;
|
4
|
+
};
|
5
|
+
|
6
|
+
struct CloudsIrradiance {
|
7
|
+
vec3 minSun;
|
8
|
+
vec3 minSky;
|
9
|
+
vec3 maxSun;
|
10
|
+
vec3 maxSky;
|
11
|
+
};
|
12
|
+
|
13
|
+
struct DensityProfile {
|
14
|
+
vec4 expTerms;
|
15
|
+
vec4 exponents;
|
16
|
+
vec4 linearTerms;
|
17
|
+
vec4 constantTerms;
|
18
|
+
};
|
@@ -0,0 +1,114 @@
|
|
1
|
+
#ifdef VARIANCE_9_SAMPLES
|
2
|
+
#define VARIANCE_OFFSET_COUNT (8)
|
3
|
+
const ivec2 varianceOffsets[8] = ivec2[8](
|
4
|
+
ivec2(-1, -1),
|
5
|
+
ivec2(-1, 1),
|
6
|
+
ivec2(1, -1),
|
7
|
+
ivec2(1, 1),
|
8
|
+
ivec2(1, 0),
|
9
|
+
ivec2(0, -1),
|
10
|
+
ivec2(0, 1),
|
11
|
+
ivec2(-1, 0)
|
12
|
+
);
|
13
|
+
#else // VARIANCE_9_SAMPLES
|
14
|
+
#define VARIANCE_OFFSET_COUNT (4)
|
15
|
+
const ivec2 varianceOffsets[4] = ivec2[4](ivec2(1, 0), ivec2(0, -1), ivec2(0, 1), ivec2(-1, 0));
|
16
|
+
#endif // VARIANCE_9_SAMPLES
|
17
|
+
|
18
|
+
// Reference: https://github.com/playdeadgames/temporal
|
19
|
+
vec4 clipAABB(const vec4 current, const vec4 history, const vec4 minColor, const vec4 maxColor) {
|
20
|
+
vec3 pClip = 0.5 * (maxColor.rgb + minColor.rgb);
|
21
|
+
vec3 eClip = 0.5 * (maxColor.rgb - minColor.rgb) + 1e-7;
|
22
|
+
vec4 vClip = history - vec4(pClip, current.a);
|
23
|
+
vec3 vUnit = vClip.xyz / eClip;
|
24
|
+
vec3 aUnit = abs(vUnit);
|
25
|
+
float maUnit = max(aUnit.x, max(aUnit.y, aUnit.z));
|
26
|
+
if (maUnit > 1.0) {
|
27
|
+
return vec4(pClip, current.a) + vClip / maUnit;
|
28
|
+
}
|
29
|
+
return history;
|
30
|
+
}
|
31
|
+
|
32
|
+
#ifdef VARIANCE_SAMPLER_ARRAY
|
33
|
+
#define VARIANCE_SAMPLER sampler2DArray
|
34
|
+
#define VARIANCE_SAMPLER_COORD ivec3
|
35
|
+
#else // VARIANCE_SAMPLER_ARRAY
|
36
|
+
#define VARIANCE_SAMPLER sampler2D
|
37
|
+
#define VARIANCE_SAMPLER_COORD ivec2
|
38
|
+
#endif // VARIANCE_SAMPLER_ARRAY
|
39
|
+
|
40
|
+
// Variance clipping
|
41
|
+
// Reference: https://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf
|
42
|
+
vec4 varianceClipping(
|
43
|
+
const VARIANCE_SAMPLER inputBuffer,
|
44
|
+
const VARIANCE_SAMPLER_COORD coord,
|
45
|
+
const vec4 current,
|
46
|
+
const vec4 history,
|
47
|
+
const float gamma
|
48
|
+
) {
|
49
|
+
vec4 moment1 = current;
|
50
|
+
vec4 moment2 = current * current;
|
51
|
+
vec4 neighbor;
|
52
|
+
#pragma unroll_loop_start
|
53
|
+
for (int i = 0; i < 8; ++i) {
|
54
|
+
#if UNROLLED_LOOP_INDEX < VARIANCE_OFFSET_COUNT
|
55
|
+
neighbor = texelFetchOffset(inputBuffer, coord, 0, varianceOffsets[i]);
|
56
|
+
moment1 += neighbor;
|
57
|
+
moment2 += neighbor * neighbor;
|
58
|
+
#endif // UNROLLED_LOOP_INDEX < VARIANCE_OFFSET_COUNT
|
59
|
+
}
|
60
|
+
#pragma unroll_loop_end
|
61
|
+
|
62
|
+
const float N = float(VARIANCE_OFFSET_COUNT + 1);
|
63
|
+
vec4 mean = moment1 / N;
|
64
|
+
vec4 varianceGamma = sqrt(max(moment2 / N - mean * mean, 0.0)) * gamma;
|
65
|
+
vec4 minColor = mean - varianceGamma;
|
66
|
+
vec4 maxColor = mean + varianceGamma;
|
67
|
+
return clipAABB(clamp(mean, minColor, maxColor), history, minColor, maxColor);
|
68
|
+
}
|
69
|
+
|
70
|
+
vec4 varianceClipping(
|
71
|
+
const VARIANCE_SAMPLER inputBuffer,
|
72
|
+
const VARIANCE_SAMPLER_COORD coord,
|
73
|
+
const vec4 current,
|
74
|
+
const vec4 history
|
75
|
+
) {
|
76
|
+
return varianceClipping(inputBuffer, coord, current, history, 1.0);
|
77
|
+
}
|
78
|
+
|
79
|
+
vec4 varianceClipping(
|
80
|
+
const sampler2D inputBuffer,
|
81
|
+
const vec2 coord,
|
82
|
+
const vec4 current,
|
83
|
+
const vec4 history,
|
84
|
+
const float gamma
|
85
|
+
) {
|
86
|
+
vec4 moment1 = current;
|
87
|
+
vec4 moment2 = current * current;
|
88
|
+
vec4 neighbor;
|
89
|
+
#pragma unroll_loop_start
|
90
|
+
for (int i = 0; i < 8; ++i) {
|
91
|
+
#if UNROLLED_LOOP_INDEX < VARIANCE_OFFSET_COUNT
|
92
|
+
neighbor = textureOffset(inputBuffer, coord, varianceOffsets[i]);
|
93
|
+
moment1 += neighbor;
|
94
|
+
moment2 += neighbor * neighbor;
|
95
|
+
#endif // UNROLLED_LOOP_INDEX < VARIANCE_OFFSET_COUNT
|
96
|
+
}
|
97
|
+
#pragma unroll_loop_end
|
98
|
+
|
99
|
+
const float N = float(VARIANCE_OFFSET_COUNT + 1);
|
100
|
+
vec4 mean = moment1 / N;
|
101
|
+
vec4 varianceGamma = sqrt(max(moment2 / N - mean * mean, 0.0)) * gamma;
|
102
|
+
vec4 minColor = mean - varianceGamma;
|
103
|
+
vec4 maxColor = mean + varianceGamma;
|
104
|
+
return clipAABB(clamp(mean, minColor, maxColor), history, minColor, maxColor);
|
105
|
+
}
|
106
|
+
|
107
|
+
vec4 varianceClipping(
|
108
|
+
const sampler2D inputBuffer,
|
109
|
+
const vec2 coord,
|
110
|
+
const vec4 current,
|
111
|
+
const vec4 history
|
112
|
+
) {
|
113
|
+
return varianceClipping(inputBuffer, coord, current, history, 1.0);
|
114
|
+
}
|
package/src/uniforms.ts
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
import {
|
2
|
+
Uniform,
|
3
|
+
Vector3,
|
4
|
+
Vector4,
|
5
|
+
type Data3DTexture,
|
6
|
+
type Matrix4,
|
7
|
+
type Texture,
|
8
|
+
type Vector2
|
9
|
+
} from 'three'
|
10
|
+
import invariant from 'tiny-invariant'
|
11
|
+
import { type Primitive } from 'type-fest'
|
12
|
+
|
13
|
+
import { type AtmosphereParameters } from '@takram/three-atmosphere'
|
14
|
+
|
15
|
+
import { type CloudLayers } from './CloudLayers'
|
16
|
+
|
17
|
+
export interface CloudParameterUniforms {
|
18
|
+
// Participating medium
|
19
|
+
scatteringCoefficient: Uniform<number>
|
20
|
+
absorptionCoefficient: Uniform<number>
|
21
|
+
|
22
|
+
// Weather and shape
|
23
|
+
coverage: Uniform<number>
|
24
|
+
localWeatherTexture: Uniform<Texture | null>
|
25
|
+
localWeatherRepeat: Uniform<Vector2>
|
26
|
+
localWeatherOffset: Uniform<Vector2>
|
27
|
+
shapeTexture: Uniform<Data3DTexture | null>
|
28
|
+
shapeRepeat: Uniform<Vector3>
|
29
|
+
shapeOffset: Uniform<Vector3>
|
30
|
+
shapeDetailTexture: Uniform<Data3DTexture | null>
|
31
|
+
shapeDetailRepeat: Uniform<Vector3>
|
32
|
+
shapeDetailOffset: Uniform<Vector3>
|
33
|
+
turbulenceTexture: Uniform<Texture | null>
|
34
|
+
turbulenceRepeat: Uniform<Vector2>
|
35
|
+
turbulenceDisplacement: Uniform<number>
|
36
|
+
}
|
37
|
+
|
38
|
+
// prettier-ignore
|
39
|
+
export type CloudParameterUniformInstances = {
|
40
|
+
[K in keyof CloudParameterUniforms as
|
41
|
+
CloudParameterUniforms[K]['value'] extends Primitive ? never : K
|
42
|
+
]: CloudParameterUniforms[K]['value']
|
43
|
+
}
|
44
|
+
|
45
|
+
export function createCloudParameterUniforms(
|
46
|
+
instances: CloudParameterUniformInstances
|
47
|
+
): CloudParameterUniforms {
|
48
|
+
return {
|
49
|
+
// Participating medium
|
50
|
+
scatteringCoefficient: new Uniform(1),
|
51
|
+
absorptionCoefficient: new Uniform(0),
|
52
|
+
|
53
|
+
// Weather and shape
|
54
|
+
coverage: new Uniform(0.3),
|
55
|
+
localWeatherTexture: new Uniform(instances.localWeatherTexture),
|
56
|
+
localWeatherRepeat: new Uniform(instances.localWeatherRepeat),
|
57
|
+
localWeatherOffset: new Uniform(instances.localWeatherOffset),
|
58
|
+
shapeTexture: new Uniform(instances.shapeTexture),
|
59
|
+
shapeRepeat: new Uniform(instances.shapeRepeat),
|
60
|
+
shapeOffset: new Uniform(instances.shapeOffset),
|
61
|
+
shapeDetailTexture: new Uniform(instances.shapeDetailTexture),
|
62
|
+
shapeDetailRepeat: new Uniform(instances.shapeDetailRepeat),
|
63
|
+
shapeDetailOffset: new Uniform(instances.shapeDetailOffset),
|
64
|
+
turbulenceTexture: new Uniform(instances.turbulenceTexture),
|
65
|
+
turbulenceRepeat: new Uniform(instances.turbulenceRepeat),
|
66
|
+
turbulenceDisplacement: new Uniform(350)
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
interface DensityProfileVectors {
|
71
|
+
expTerms: Vector4
|
72
|
+
exponents: Vector4
|
73
|
+
linearTerms: Vector4
|
74
|
+
constantTerms: Vector4
|
75
|
+
}
|
76
|
+
|
77
|
+
export interface CloudLayerUniforms {
|
78
|
+
minLayerHeights: Uniform<Vector4>
|
79
|
+
maxLayerHeights: Uniform<Vector4>
|
80
|
+
minIntervalHeights: Uniform<Vector3>
|
81
|
+
maxIntervalHeights: Uniform<Vector3>
|
82
|
+
densityScales: Uniform<Vector4>
|
83
|
+
shapeAmounts: Uniform<Vector4>
|
84
|
+
shapeDetailAmounts: Uniform<Vector4>
|
85
|
+
weatherExponents: Uniform<Vector4>
|
86
|
+
shapeAlteringBiases: Uniform<Vector4>
|
87
|
+
coverageFilterWidths: Uniform<Vector4>
|
88
|
+
minHeight: Uniform<number>
|
89
|
+
maxHeight: Uniform<number>
|
90
|
+
shadowTopHeight: Uniform<number>
|
91
|
+
shadowBottomHeight: Uniform<number>
|
92
|
+
shadowLayerMask: Uniform<Vector4>
|
93
|
+
densityProfile: Uniform<DensityProfileVectors>
|
94
|
+
}
|
95
|
+
|
96
|
+
export function createCloudLayerUniforms(): CloudLayerUniforms {
|
97
|
+
return {
|
98
|
+
minLayerHeights: new Uniform(new Vector4()),
|
99
|
+
maxLayerHeights: new Uniform(new Vector4()),
|
100
|
+
minIntervalHeights: new Uniform(new Vector3()),
|
101
|
+
maxIntervalHeights: new Uniform(new Vector3()),
|
102
|
+
densityScales: new Uniform(new Vector4()),
|
103
|
+
shapeAmounts: new Uniform(new Vector4()),
|
104
|
+
shapeDetailAmounts: new Uniform(new Vector4()),
|
105
|
+
weatherExponents: new Uniform(new Vector4()),
|
106
|
+
shapeAlteringBiases: new Uniform(new Vector4()),
|
107
|
+
coverageFilterWidths: new Uniform(new Vector4()),
|
108
|
+
minHeight: new Uniform(0),
|
109
|
+
maxHeight: new Uniform(0),
|
110
|
+
shadowTopHeight: new Uniform(0),
|
111
|
+
shadowBottomHeight: new Uniform(0),
|
112
|
+
shadowLayerMask: new Uniform(new Vector4()),
|
113
|
+
densityProfile: new Uniform({
|
114
|
+
expTerms: new Vector4(),
|
115
|
+
exponents: new Vector4(),
|
116
|
+
linearTerms: new Vector4(),
|
117
|
+
constantTerms: new Vector4()
|
118
|
+
})
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
const shadowLayerMask = [0, 0, 0, 0]
|
123
|
+
|
124
|
+
export function updateCloudLayerUniforms(
|
125
|
+
uniforms: CloudLayerUniforms,
|
126
|
+
layers: CloudLayers
|
127
|
+
): void {
|
128
|
+
layers.packValues('altitude', uniforms.minLayerHeights.value)
|
129
|
+
layers.packSums('altitude', 'height', uniforms.maxLayerHeights.value)
|
130
|
+
layers.packIntervalHeights(
|
131
|
+
uniforms.minIntervalHeights.value,
|
132
|
+
uniforms.maxIntervalHeights.value
|
133
|
+
)
|
134
|
+
layers.packValues('densityScale', uniforms.densityScales.value)
|
135
|
+
layers.packValues('shapeAmount', uniforms.shapeAmounts.value)
|
136
|
+
layers.packValues('shapeDetailAmount', uniforms.shapeDetailAmounts.value)
|
137
|
+
layers.packValues('weatherExponent', uniforms.weatherExponents.value)
|
138
|
+
layers.packValues('shapeAlteringBias', uniforms.shapeAlteringBiases.value)
|
139
|
+
layers.packValues('coverageFilterWidth', uniforms.coverageFilterWidths.value)
|
140
|
+
|
141
|
+
const densityProfile = uniforms.densityProfile.value
|
142
|
+
layers.packDensityProfiles('expTerm', densityProfile.expTerms)
|
143
|
+
layers.packDensityProfiles('exponent', densityProfile.exponents)
|
144
|
+
layers.packDensityProfiles('linearTerm', densityProfile.linearTerms)
|
145
|
+
layers.packDensityProfiles('constantTerm', densityProfile.constantTerms)
|
146
|
+
|
147
|
+
let totalMinHeight = Infinity
|
148
|
+
let totalMaxHeight = 0
|
149
|
+
let shadowBottomHeight = Infinity
|
150
|
+
let shadowTopHeight = 0
|
151
|
+
shadowLayerMask.fill(0)
|
152
|
+
for (let i = 0; i < layers.length; ++i) {
|
153
|
+
const { altitude, height, shadow } = layers[i]
|
154
|
+
const maxHeight = altitude + height
|
155
|
+
if (height > 0) {
|
156
|
+
if (altitude < totalMinHeight) {
|
157
|
+
totalMinHeight = altitude
|
158
|
+
}
|
159
|
+
if (shadow && altitude < shadowBottomHeight) {
|
160
|
+
shadowBottomHeight = altitude
|
161
|
+
}
|
162
|
+
if (maxHeight > totalMaxHeight) {
|
163
|
+
totalMaxHeight = maxHeight
|
164
|
+
}
|
165
|
+
if (shadow && maxHeight > shadowTopHeight) {
|
166
|
+
shadowTopHeight = maxHeight
|
167
|
+
}
|
168
|
+
}
|
169
|
+
shadowLayerMask[i] = shadow ? 1 : 0
|
170
|
+
}
|
171
|
+
if (totalMinHeight !== Infinity) {
|
172
|
+
uniforms.minHeight.value = totalMinHeight
|
173
|
+
uniforms.maxHeight.value = totalMaxHeight
|
174
|
+
} else {
|
175
|
+
invariant(totalMaxHeight === 0)
|
176
|
+
uniforms.minHeight.value = 0
|
177
|
+
}
|
178
|
+
if (shadowBottomHeight !== Infinity) {
|
179
|
+
uniforms.shadowBottomHeight.value = shadowBottomHeight
|
180
|
+
uniforms.shadowTopHeight.value = shadowTopHeight
|
181
|
+
} else {
|
182
|
+
invariant(shadowTopHeight === 0)
|
183
|
+
uniforms.shadowBottomHeight.value = 0
|
184
|
+
}
|
185
|
+
uniforms.shadowLayerMask.value.fromArray(shadowLayerMask)
|
186
|
+
}
|
187
|
+
|
188
|
+
export interface AtmosphereUniforms {
|
189
|
+
bottomRadius: Uniform<number>
|
190
|
+
topRadius: Uniform<number>
|
191
|
+
ellipsoidCenter: Uniform<Vector3>
|
192
|
+
ellipsoidMatrix: Uniform<Matrix4>
|
193
|
+
inverseEllipsoidMatrix: Uniform<Matrix4>
|
194
|
+
altitudeCorrection: Uniform<Vector3>
|
195
|
+
sunDirection: Uniform<Vector3>
|
196
|
+
}
|
197
|
+
|
198
|
+
// prettier-ignore
|
199
|
+
export type AtmosphereUniformInstances = {
|
200
|
+
[K in keyof AtmosphereUniforms as
|
201
|
+
AtmosphereUniforms[K]['value'] extends Primitive ? never : K
|
202
|
+
]: AtmosphereUniforms[K]['value']
|
203
|
+
}
|
204
|
+
|
205
|
+
export function createAtmosphereUniforms(
|
206
|
+
atmosphere: AtmosphereParameters,
|
207
|
+
instances: AtmosphereUniformInstances
|
208
|
+
): AtmosphereUniforms {
|
209
|
+
return {
|
210
|
+
bottomRadius: new Uniform(atmosphere.bottomRadius),
|
211
|
+
topRadius: new Uniform(atmosphere.topRadius),
|
212
|
+
ellipsoidCenter: new Uniform(instances.ellipsoidCenter),
|
213
|
+
ellipsoidMatrix: new Uniform(instances.ellipsoidMatrix),
|
214
|
+
inverseEllipsoidMatrix: new Uniform(instances.inverseEllipsoidMatrix),
|
215
|
+
altitudeCorrection: new Uniform(instances.altitudeCorrection),
|
216
|
+
sunDirection: new Uniform(instances.sunDirection)
|
217
|
+
}
|
218
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import { FrustumSplitMode } from './helpers/splitFrustum';
|
2
|
+
import { Matrix4, Vector2, Vector3, PerspectiveCamera } from 'three';
|
3
|
+
|
4
|
+
export interface Cascade {
|
5
|
+
readonly interval: Vector2;
|
6
|
+
readonly matrix: Matrix4;
|
7
|
+
readonly inverseMatrix: Matrix4;
|
8
|
+
readonly projectionMatrix: Matrix4;
|
9
|
+
readonly inverseProjectionMatrix: Matrix4;
|
10
|
+
readonly viewMatrix: Matrix4;
|
11
|
+
readonly inverseViewMatrix: Matrix4;
|
12
|
+
}
|
13
|
+
export interface CascadedShadowMapsOptions {
|
14
|
+
cascadeCount: number;
|
15
|
+
mapSize: Vector2;
|
16
|
+
maxFar?: number | null;
|
17
|
+
farScale?: number;
|
18
|
+
splitMode?: FrustumSplitMode;
|
19
|
+
splitLambda?: number;
|
20
|
+
margin?: number;
|
21
|
+
fade?: boolean;
|
22
|
+
}
|
23
|
+
export declare const cascadedShadowMapsDefaults: {
|
24
|
+
maxFar: null;
|
25
|
+
farScale: number;
|
26
|
+
splitMode: "practical";
|
27
|
+
splitLambda: number;
|
28
|
+
margin: number;
|
29
|
+
fade: true;
|
30
|
+
};
|
31
|
+
export declare class CascadedShadowMaps {
|
32
|
+
readonly cascades: Cascade[];
|
33
|
+
readonly mapSize: Vector2;
|
34
|
+
maxFar: number | null;
|
35
|
+
farScale: number;
|
36
|
+
splitMode: FrustumSplitMode;
|
37
|
+
splitLambda: number;
|
38
|
+
margin: number;
|
39
|
+
fade: boolean;
|
40
|
+
private readonly cameraFrustum;
|
41
|
+
private readonly frusta;
|
42
|
+
private readonly splits;
|
43
|
+
private _far;
|
44
|
+
constructor(options: CascadedShadowMapsOptions);
|
45
|
+
get cascadeCount(): number;
|
46
|
+
set cascadeCount(value: number);
|
47
|
+
get far(): number;
|
48
|
+
private updateIntervals;
|
49
|
+
private getFrustumRadius;
|
50
|
+
private updateMatrices;
|
51
|
+
update(camera: PerspectiveCamera, sunDirection: Vector3, distance?: number): void;
|
52
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { DensityProfile, DensityProfileLike } from './DensityProfile';
|
2
|
+
|
3
|
+
declare const paramKeys: readonly ["channel", "altitude", "height", "densityScale", "shapeAmount", "shapeDetailAmount", "weatherExponent", "shapeAlteringBias", "coverageFilterWidth", "shadow", "densityProfile"];
|
4
|
+
export interface CloudLayerLike extends Partial<Pick<CloudLayer, Exclude<(typeof paramKeys)[number], 'densityProfile'>>> {
|
5
|
+
densityProfile?: DensityProfileLike;
|
6
|
+
}
|
7
|
+
export type TextureChannel = 'r' | 'g' | 'b' | 'a';
|
8
|
+
export declare class CloudLayer {
|
9
|
+
static readonly DEFAULT: CloudLayer;
|
10
|
+
channel: TextureChannel;
|
11
|
+
altitude: number;
|
12
|
+
height: number;
|
13
|
+
densityScale: number;
|
14
|
+
shapeAmount: number;
|
15
|
+
shapeDetailAmount: number;
|
16
|
+
weatherExponent: number;
|
17
|
+
shapeAlteringBias: number;
|
18
|
+
coverageFilterWidth: number;
|
19
|
+
densityProfile: DensityProfile;
|
20
|
+
shadow: boolean;
|
21
|
+
constructor(options?: CloudLayerLike);
|
22
|
+
set(options?: CloudLayerLike): this;
|
23
|
+
clone(): CloudLayer;
|
24
|
+
copy(other: CloudLayer): this;
|
25
|
+
}
|
26
|
+
export {};
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { DensityProfileLike } from './DensityProfile';
|
2
|
+
import { CloudLayer, CloudLayerLike } from './CloudLayer';
|
3
|
+
import { Vector3, Vector4 } from 'three';
|
4
|
+
|
5
|
+
type NumericKey = keyof {
|
6
|
+
[P in keyof CloudLayer as number extends CloudLayer[P] ? P : never]: any;
|
7
|
+
};
|
8
|
+
export declare class CloudLayers extends Array<CloudLayer> {
|
9
|
+
static readonly DEFAULT: CloudLayers;
|
10
|
+
constructor(options?: readonly CloudLayerLike[]);
|
11
|
+
set(options?: readonly CloudLayerLike[]): this;
|
12
|
+
reset(): this;
|
13
|
+
clone(): CloudLayers;
|
14
|
+
copy(other: CloudLayers): this;
|
15
|
+
get localWeatherChannels(): string;
|
16
|
+
packValues<K extends NumericKey>(key: K, result: Vector4): Vector4;
|
17
|
+
packSums<A extends NumericKey, B extends NumericKey>(a: A, b: B, result: Vector4): Vector4;
|
18
|
+
packDensityProfiles<K extends keyof DensityProfileLike>(key: K, result: Vector4): Vector4;
|
19
|
+
packIntervalHeights(minIntervals: Vector3, maxIntervals: Vector3): void;
|
20
|
+
}
|
21
|
+
export {};
|
@@ -0,0 +1,170 @@
|
|
1
|
+
import { ShadowPass } from './ShadowPass';
|
2
|
+
import { ShadowMaterial } from './ShadowMaterial';
|
3
|
+
import { QualityPreset } from './qualityPresets';
|
4
|
+
import { ProceduralTexture } from './ProceduralTexture';
|
5
|
+
import { Procedural3DTexture } from './Procedural3DTexture';
|
6
|
+
import { CloudsPass } from './CloudsPass';
|
7
|
+
import { CloudsMaterial } from './CloudsMaterial';
|
8
|
+
import { CloudLayers } from './CloudLayers';
|
9
|
+
import { CascadedShadowMaps } from './CascadedShadowMaps';
|
10
|
+
import { UniformMap, Ellipsoid, PropertyShorthand, UniformShorthand } from '@takram/three-geospatial';
|
11
|
+
import { AtmosphereParameters, AtmosphereOverlay, AtmosphereShadow, AtmosphereShadowLength } from '@takram/three-atmosphere';
|
12
|
+
import { Camera, Data3DTexture, EventDispatcher, Matrix4, Texture, Uniform, Vector2, Vector3, DataTexture, DepthPackingStrategies, TextureDataType, WebGLRenderer, WebGLRenderTarget } from 'three';
|
13
|
+
import { Effect, Resolution } from 'postprocessing';
|
14
|
+
|
15
|
+
declare const cloudsUniformKeys: ["maxIterationCount", "minStepSize", "maxStepSize", "maxRayDistance", "perspectiveStepScale", "minDensity", "minExtinction", "minTransmittance", "maxIterationCountToSun", "maxIterationCountToGround", "minSecondaryStepSize", "secondaryStepScale", "maxShadowFilterRadius", "maxShadowLengthIterationCount", "minShadowLengthStepSize", "maxShadowLengthRayDistance", "hazeDensityScale", "hazeExponent"];
|
16
|
+
declare const cloudsMaterialParameterKeys: ["multiScatteringOctaves", "accurateSunSkyIrradiance", "accuratePhaseFunction"];
|
17
|
+
declare const shadowUniformKeys: ["maxIterationCount", "minStepSize", "maxStepSize", "minDensity", "minExtinction", "minTransmittance", "opticalDepthTailScale"];
|
18
|
+
declare const shadowMaterialParameterKeys: ["temporalJitter"];
|
19
|
+
declare const shadowPassParameterKeys: ["temporalPass"];
|
20
|
+
declare const shadowMapsParameterKeys: ["cascadeCount", "mapSize", "maxFar", "farScale", "splitMode", "splitLambda"];
|
21
|
+
interface CloudsShorthand extends UniformShorthand<CloudsMaterial, (typeof cloudsUniformKeys)[number]>, PropertyShorthand<[CloudsMaterial, typeof cloudsMaterialParameterKeys]> {
|
22
|
+
}
|
23
|
+
interface ShadowShorthand extends UniformShorthand<ShadowMaterial, (typeof shadowUniformKeys)[number]>, PropertyShorthand<[
|
24
|
+
ShadowMaterial,
|
25
|
+
typeof shadowMaterialParameterKeys,
|
26
|
+
ShadowPass,
|
27
|
+
typeof shadowPassParameterKeys,
|
28
|
+
CascadedShadowMaps,
|
29
|
+
typeof shadowMapsParameterKeys
|
30
|
+
]> {
|
31
|
+
}
|
32
|
+
export interface CloudsEffectChangeEvent {
|
33
|
+
type: 'change';
|
34
|
+
target?: CloudsEffect;
|
35
|
+
property?: 'atmosphereOverlay' | 'atmosphereShadow' | 'atmosphereShadowLength';
|
36
|
+
}
|
37
|
+
export interface CloudsEffectUniforms {
|
38
|
+
cloudsBuffer: Uniform<Texture | null>;
|
39
|
+
}
|
40
|
+
export interface CloudsEffectOptions {
|
41
|
+
resolutionScale?: number;
|
42
|
+
width?: number;
|
43
|
+
height?: number;
|
44
|
+
resolutionX?: number;
|
45
|
+
resolutionY?: number;
|
46
|
+
}
|
47
|
+
export declare const cloudsPassOptionsDefaults: {
|
48
|
+
resolutionScale: number;
|
49
|
+
width: number;
|
50
|
+
height: number;
|
51
|
+
};
|
52
|
+
export declare class CloudsEffect extends Effect {
|
53
|
+
private camera;
|
54
|
+
private readonly atmosphere;
|
55
|
+
uniforms: UniformMap<CloudsEffectUniforms>;
|
56
|
+
readonly cloudLayers: CloudLayers;
|
57
|
+
correctAltitude: boolean;
|
58
|
+
readonly localWeatherRepeat: Vector2;
|
59
|
+
readonly localWeatherOffset: Vector2;
|
60
|
+
readonly shapeRepeat: Vector3;
|
61
|
+
readonly shapeOffset: Vector3;
|
62
|
+
readonly shapeDetailRepeat: Vector3;
|
63
|
+
readonly shapeDetailOffset: Vector3;
|
64
|
+
readonly turbulenceRepeat: Vector2;
|
65
|
+
readonly ellipsoidCenter: Vector3;
|
66
|
+
readonly ellipsoidMatrix: Matrix4;
|
67
|
+
private readonly inverseEllipsoidMatrix;
|
68
|
+
private readonly altitudeCorrection;
|
69
|
+
readonly sunDirection: Vector3;
|
70
|
+
private readonly parameterUniforms;
|
71
|
+
private readonly layerUniforms;
|
72
|
+
private readonly atmosphereUniforms;
|
73
|
+
readonly localWeatherVelocity: Vector2;
|
74
|
+
readonly shapeVelocity: Vector3;
|
75
|
+
readonly shapeDetailVelocity: Vector3;
|
76
|
+
private proceduralLocalWeather?;
|
77
|
+
private proceduralShape?;
|
78
|
+
private proceduralShapeDetail?;
|
79
|
+
private proceduralTurbulence?;
|
80
|
+
readonly shadowMaps: CascadedShadowMaps;
|
81
|
+
readonly shadowPass: ShadowPass;
|
82
|
+
readonly cloudsPass: CloudsPass;
|
83
|
+
readonly clouds: CloudsShorthand;
|
84
|
+
readonly shadow: ShadowShorthand;
|
85
|
+
private _atmosphereOverlay;
|
86
|
+
private _atmosphereShadow;
|
87
|
+
private _atmosphereShadowLength;
|
88
|
+
readonly resolution: Resolution;
|
89
|
+
readonly events: EventDispatcher<{
|
90
|
+
change: CloudsEffectChangeEvent;
|
91
|
+
}>;
|
92
|
+
private frame;
|
93
|
+
private shadowCascadeCount;
|
94
|
+
private readonly shadowMapSize;
|
95
|
+
constructor(camera?: Camera, options?: CloudsEffectOptions, atmosphere?: AtmosphereParameters);
|
96
|
+
private readonly onResolutionChange;
|
97
|
+
get mainCamera(): Camera;
|
98
|
+
set mainCamera(value: Camera);
|
99
|
+
initialize(renderer: WebGLRenderer, alpha: boolean, frameBufferType: TextureDataType): void;
|
100
|
+
private updateSharedUniforms;
|
101
|
+
private updateWeatherTextureChannels;
|
102
|
+
private updateAtmosphereComposition;
|
103
|
+
update(renderer: WebGLRenderer, inputBuffer: WebGLRenderTarget, deltaTime?: number): void;
|
104
|
+
setSize(baseWidth: number, baseHeight: number): void;
|
105
|
+
setDepthTexture(depthTexture: Texture, depthPacking?: DepthPackingStrategies): void;
|
106
|
+
skipRendering: boolean;
|
107
|
+
set qualityPreset(value: QualityPreset);
|
108
|
+
get localWeatherTexture(): Texture | ProceduralTexture | null;
|
109
|
+
set localWeatherTexture(value: Texture | ProceduralTexture | null);
|
110
|
+
get shapeTexture(): Data3DTexture | Procedural3DTexture | null;
|
111
|
+
set shapeTexture(value: Data3DTexture | Procedural3DTexture | null);
|
112
|
+
get shapeDetailTexture(): Data3DTexture | Procedural3DTexture | null;
|
113
|
+
set shapeDetailTexture(value: Data3DTexture | Procedural3DTexture | null);
|
114
|
+
get turbulenceTexture(): Texture | ProceduralTexture | null;
|
115
|
+
set turbulenceTexture(value: Texture | ProceduralTexture | null);
|
116
|
+
get stbnTexture(): Data3DTexture | null;
|
117
|
+
set stbnTexture(value: Data3DTexture | null);
|
118
|
+
get resolutionScale(): number;
|
119
|
+
set resolutionScale(value: number);
|
120
|
+
get temporalUpscale(): boolean;
|
121
|
+
set temporalUpscale(value: boolean);
|
122
|
+
get lightShafts(): boolean;
|
123
|
+
set lightShafts(value: boolean);
|
124
|
+
get shapeDetail(): boolean;
|
125
|
+
set shapeDetail(value: boolean);
|
126
|
+
get turbulence(): boolean;
|
127
|
+
set turbulence(value: boolean);
|
128
|
+
get haze(): boolean;
|
129
|
+
set haze(value: boolean);
|
130
|
+
get scatteringCoefficient(): number;
|
131
|
+
set scatteringCoefficient(value: number);
|
132
|
+
get absorptionCoefficient(): number;
|
133
|
+
set absorptionCoefficient(value: number);
|
134
|
+
get coverage(): number;
|
135
|
+
set coverage(value: number);
|
136
|
+
get turbulenceDisplacement(): number;
|
137
|
+
set turbulenceDisplacement(value: number);
|
138
|
+
get scatterAnisotropy1(): number;
|
139
|
+
set scatterAnisotropy1(value: number);
|
140
|
+
get scatterAnisotropy2(): number;
|
141
|
+
set scatterAnisotropy2(value: number);
|
142
|
+
get scatterAnisotropyMix(): number;
|
143
|
+
set scatterAnisotropyMix(value: number);
|
144
|
+
get skyIrradianceScale(): number;
|
145
|
+
set skyIrradianceScale(value: number);
|
146
|
+
get groundIrradianceScale(): number;
|
147
|
+
set groundIrradianceScale(value: number);
|
148
|
+
get powderScale(): number;
|
149
|
+
set powderScale(value: number);
|
150
|
+
get powderExponent(): number;
|
151
|
+
set powderExponent(value: number);
|
152
|
+
get atmosphereOverlay(): AtmosphereOverlay | null;
|
153
|
+
get atmosphereShadow(): AtmosphereShadow | null;
|
154
|
+
get atmosphereShadowLength(): AtmosphereShadowLength | null;
|
155
|
+
get irradianceTexture(): DataTexture | null;
|
156
|
+
set irradianceTexture(value: DataTexture | null);
|
157
|
+
get scatteringTexture(): Data3DTexture | null;
|
158
|
+
set scatteringTexture(value: Data3DTexture | null);
|
159
|
+
get transmittanceTexture(): DataTexture | null;
|
160
|
+
set transmittanceTexture(value: DataTexture | null);
|
161
|
+
get useHalfFloat(): boolean;
|
162
|
+
set useHalfFloat(value: boolean);
|
163
|
+
get ellipsoid(): Ellipsoid;
|
164
|
+
set ellipsoid(value: Ellipsoid);
|
165
|
+
get photometric(): boolean;
|
166
|
+
set photometric(value: boolean);
|
167
|
+
get sunAngularRadius(): number;
|
168
|
+
set sunAngularRadius(value: number);
|
169
|
+
}
|
170
|
+
export {};
|