@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,181 @@
|
|
1
|
+
import { type Vector3, type Vector4 } from 'three'
|
2
|
+
|
3
|
+
import { CloudLayer, type CloudLayerLike } from './CloudLayer'
|
4
|
+
import { type DensityProfileLike } from './DensityProfile'
|
5
|
+
|
6
|
+
type NumericKey = keyof {
|
7
|
+
[P in keyof CloudLayer as number extends CloudLayer[P] ? P : never]: any
|
8
|
+
}
|
9
|
+
|
10
|
+
interface Entry {
|
11
|
+
value: number
|
12
|
+
flag: 0 | 1
|
13
|
+
}
|
14
|
+
|
15
|
+
// prettier-ignore
|
16
|
+
const entriesScratch: Entry[] = /*#__PURE__*/ Array.from(
|
17
|
+
{ length: 8 },
|
18
|
+
() => ({ value: 0, flag: 0 })
|
19
|
+
)
|
20
|
+
// prettier-ignore
|
21
|
+
const intervalsScratch = /*#__PURE__*/ Array.from(
|
22
|
+
{ length: 3 },
|
23
|
+
() => ({ min: 0, max: 0 })
|
24
|
+
)
|
25
|
+
|
26
|
+
function compareEntries(a: Entry, b: Entry): number {
|
27
|
+
return a.value !== b.value ? a.value - b.value : a.flag - b.flag
|
28
|
+
}
|
29
|
+
|
30
|
+
export class CloudLayers extends Array<CloudLayer> {
|
31
|
+
static readonly DEFAULT = /*#__PURE__*/ new CloudLayers([
|
32
|
+
{
|
33
|
+
channel: 'r',
|
34
|
+
altitude: 750,
|
35
|
+
height: 650,
|
36
|
+
densityScale: 0.2,
|
37
|
+
shapeAmount: 1,
|
38
|
+
shapeDetailAmount: 1,
|
39
|
+
weatherExponent: 1,
|
40
|
+
shapeAlteringBias: 0.35,
|
41
|
+
coverageFilterWidth: 0.6,
|
42
|
+
shadow: true
|
43
|
+
},
|
44
|
+
{
|
45
|
+
channel: 'g',
|
46
|
+
altitude: 1000,
|
47
|
+
height: 1200,
|
48
|
+
densityScale: 0.2,
|
49
|
+
shapeAmount: 1,
|
50
|
+
shapeDetailAmount: 1,
|
51
|
+
weatherExponent: 1,
|
52
|
+
shapeAlteringBias: 0.35,
|
53
|
+
coverageFilterWidth: 0.6,
|
54
|
+
shadow: true
|
55
|
+
},
|
56
|
+
{
|
57
|
+
channel: 'b',
|
58
|
+
altitude: 7500,
|
59
|
+
height: 500,
|
60
|
+
densityScale: 0.003,
|
61
|
+
shapeAmount: 0.4,
|
62
|
+
shapeDetailAmount: 0,
|
63
|
+
weatherExponent: 1,
|
64
|
+
shapeAlteringBias: 0.35,
|
65
|
+
coverageFilterWidth: 0.5
|
66
|
+
},
|
67
|
+
{ channel: 'a' }
|
68
|
+
])
|
69
|
+
|
70
|
+
constructor(options?: readonly CloudLayerLike[]) {
|
71
|
+
super(
|
72
|
+
new CloudLayer(options?.[0]),
|
73
|
+
new CloudLayer(options?.[1]),
|
74
|
+
new CloudLayer(options?.[2]),
|
75
|
+
new CloudLayer(options?.[3])
|
76
|
+
)
|
77
|
+
}
|
78
|
+
|
79
|
+
set(options?: readonly CloudLayerLike[]): this {
|
80
|
+
this[0].set(options?.[0])
|
81
|
+
this[1].set(options?.[1])
|
82
|
+
this[2].set(options?.[2])
|
83
|
+
this[3].set(options?.[3])
|
84
|
+
return this
|
85
|
+
}
|
86
|
+
|
87
|
+
reset(): this {
|
88
|
+
this[0].copy(CloudLayer.DEFAULT)
|
89
|
+
this[1].copy(CloudLayer.DEFAULT)
|
90
|
+
this[2].copy(CloudLayer.DEFAULT)
|
91
|
+
this[3].copy(CloudLayer.DEFAULT)
|
92
|
+
return this
|
93
|
+
}
|
94
|
+
|
95
|
+
clone(): CloudLayers {
|
96
|
+
return new CloudLayers(this)
|
97
|
+
}
|
98
|
+
|
99
|
+
copy(other: CloudLayers): this {
|
100
|
+
this[0].copy(other[0])
|
101
|
+
this[1].copy(other[1])
|
102
|
+
this[2].copy(other[2])
|
103
|
+
this[3].copy(other[3])
|
104
|
+
return this
|
105
|
+
}
|
106
|
+
|
107
|
+
get localWeatherChannels(): string {
|
108
|
+
return this[0].channel + this[1].channel + this[2].channel + this[3].channel
|
109
|
+
}
|
110
|
+
|
111
|
+
packValues<K extends NumericKey>(key: K, result: Vector4): Vector4 {
|
112
|
+
return result.set(this[0][key], this[1][key], this[2][key], this[3][key])
|
113
|
+
}
|
114
|
+
|
115
|
+
packSums<A extends NumericKey, B extends NumericKey>(
|
116
|
+
a: A,
|
117
|
+
b: B,
|
118
|
+
result: Vector4
|
119
|
+
): Vector4 {
|
120
|
+
return result.set(
|
121
|
+
this[0][a] + this[0][b],
|
122
|
+
this[1][a] + this[1][b],
|
123
|
+
this[2][a] + this[2][b],
|
124
|
+
this[3][a] + this[3][b]
|
125
|
+
)
|
126
|
+
}
|
127
|
+
|
128
|
+
packDensityProfiles<K extends keyof DensityProfileLike>(
|
129
|
+
key: K,
|
130
|
+
result: Vector4
|
131
|
+
): Vector4 {
|
132
|
+
return result.set(
|
133
|
+
this[0].densityProfile[key],
|
134
|
+
this[1].densityProfile[key],
|
135
|
+
this[2].densityProfile[key],
|
136
|
+
this[3].densityProfile[key]
|
137
|
+
)
|
138
|
+
}
|
139
|
+
|
140
|
+
// Redundant, but need to avoid creating garbage here as this runs every frame.
|
141
|
+
packIntervalHeights(minIntervals: Vector3, maxIntervals: Vector3): void {
|
142
|
+
for (let i = 0; i < 4; ++i) {
|
143
|
+
const layer = this[i]
|
144
|
+
let entry = entriesScratch[i]
|
145
|
+
entry.value = layer.altitude
|
146
|
+
entry.flag = 0
|
147
|
+
entry = entriesScratch[i + 4]
|
148
|
+
entry.value = layer.altitude + layer.height
|
149
|
+
entry.flag = 1
|
150
|
+
}
|
151
|
+
entriesScratch.sort(compareEntries)
|
152
|
+
|
153
|
+
// Reference: https://dilipkumar.medium.com/interval-coding-pattern-068c36197cf5
|
154
|
+
let intervalIndex = 0
|
155
|
+
let balance = 0
|
156
|
+
for (let entryIndex = 0; entryIndex < entriesScratch.length; ++entryIndex) {
|
157
|
+
const { value, flag } = entriesScratch[entryIndex]
|
158
|
+
if (balance === 0 && entryIndex > 0) {
|
159
|
+
const interval = intervalsScratch[intervalIndex++]
|
160
|
+
interval.min = entriesScratch[entryIndex - 1].value
|
161
|
+
interval.max = value
|
162
|
+
}
|
163
|
+
balance += flag === 0 ? 1 : -1
|
164
|
+
}
|
165
|
+
for (; intervalIndex < 3; ++intervalIndex) {
|
166
|
+
const interval = intervalsScratch[intervalIndex]
|
167
|
+
interval.min = 0
|
168
|
+
interval.max = 0
|
169
|
+
}
|
170
|
+
|
171
|
+
let interval = intervalsScratch[0]
|
172
|
+
minIntervals.x = interval.min
|
173
|
+
maxIntervals.x = interval.max
|
174
|
+
interval = intervalsScratch[1]
|
175
|
+
minIntervals.y = interval.min
|
176
|
+
maxIntervals.y = interval.max
|
177
|
+
interval = intervalsScratch[2]
|
178
|
+
minIntervals.z = interval.min
|
179
|
+
maxIntervals.z = interval.max
|
180
|
+
}
|
181
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { resolveIncludes } from '@takram/three-geospatial'
|
2
|
+
import { math } from '@takram/three-geospatial/shaders'
|
3
|
+
|
4
|
+
import { CLOUD_SHAPE_TEXTURE_SIZE } from './constants'
|
5
|
+
import { Procedural3DTextureBase } from './Procedural3DTexture'
|
6
|
+
|
7
|
+
import fragmentShader from './shaders/cloudShape.frag?raw'
|
8
|
+
import perlin from './shaders/perlin.glsl?raw'
|
9
|
+
import tileableNoise from './shaders/tileableNoise.glsl?raw'
|
10
|
+
|
11
|
+
export class CloudShape extends Procedural3DTextureBase {
|
12
|
+
constructor() {
|
13
|
+
super({
|
14
|
+
size: CLOUD_SHAPE_TEXTURE_SIZE,
|
15
|
+
fragmentShader: resolveIncludes(fragmentShader, {
|
16
|
+
core: { math },
|
17
|
+
perlin,
|
18
|
+
tileableNoise
|
19
|
+
})
|
20
|
+
})
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { resolveIncludes } from '@takram/three-geospatial'
|
2
|
+
import { math } from '@takram/three-geospatial/shaders'
|
3
|
+
|
4
|
+
import { CLOUD_SHAPE_DETAIL_TEXTURE_SIZE } from './constants'
|
5
|
+
import { Procedural3DTextureBase } from './Procedural3DTexture'
|
6
|
+
|
7
|
+
import fragmentShader from './shaders/cloudShapeDetail.frag?raw'
|
8
|
+
import perlin from './shaders/perlin.glsl?raw'
|
9
|
+
import tileableNoise from './shaders/tileableNoise.glsl?raw'
|
10
|
+
|
11
|
+
export class CloudShapeDetail extends Procedural3DTextureBase {
|
12
|
+
constructor() {
|
13
|
+
super({
|
14
|
+
size: CLOUD_SHAPE_DETAIL_TEXTURE_SIZE,
|
15
|
+
fragmentShader: resolveIncludes(fragmentShader, {
|
16
|
+
core: { math },
|
17
|
+
perlin,
|
18
|
+
tileableNoise
|
19
|
+
})
|
20
|
+
})
|
21
|
+
}
|
22
|
+
}
|