@takram/three-clouds 0.3.0 → 0.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takram/three-clouds",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A Three.js and R3F implementation of geospatial volumetric clouds",
5
5
  "keywords": [
6
6
  "three",
@@ -45,8 +45,8 @@
45
45
  "README.md"
46
46
  ],
47
47
  "dependencies": {
48
- "@takram/three-atmosphere": "0.12.0",
49
- "@takram/three-geospatial": "0.2.2",
48
+ "@takram/three-atmosphere": "0.13.0",
49
+ "@takram/three-geospatial": "0.3.0",
50
50
  "tiny-invariant": "^1.3.3",
51
51
  "type-fest": "^4.34.1"
52
52
  },
@@ -1,7 +1,7 @@
1
- import { type Vector3, type Vector4 } from 'three'
1
+ import type { Vector3, Vector4 } from 'three'
2
2
 
3
3
  import { CloudLayer, type CloudLayerLike } from './CloudLayer'
4
- import { type DensityProfileLike } from './DensityProfile'
4
+ import type { DensityProfileLike } from './DensityProfile'
5
5
 
6
6
  type NumericKey = keyof {
7
7
  [P in keyof CloudLayer as number extends CloudLayer[P] ? P : never]: any
@@ -8,7 +8,6 @@ import {
8
8
  Uniform,
9
9
  Vector2,
10
10
  Vector3,
11
- type DataTexture,
12
11
  type DepthPackingStrategies,
13
12
  type PerspectiveCamera,
14
13
  type TextureDataType,
@@ -36,18 +35,12 @@ import {
36
35
 
37
36
  import { CascadedShadowMaps } from './CascadedShadowMaps'
38
37
  import { CloudLayers } from './CloudLayers'
39
- import {
40
- type CloudsMaterial,
41
- type CloudsMaterialUniforms
42
- } from './CloudsMaterial'
38
+ import type { CloudsMaterial, CloudsMaterialUniforms } from './CloudsMaterial'
43
39
  import { CloudsPass } from './CloudsPass'
44
- import { type Procedural3DTexture } from './Procedural3DTexture'
45
- import { type ProceduralTexture } from './ProceduralTexture'
40
+ import type { Procedural3DTexture } from './Procedural3DTexture'
41
+ import type { ProceduralTexture } from './ProceduralTexture'
46
42
  import { defaults, qualityPresets, type QualityPreset } from './qualityPresets'
47
- import {
48
- type ShadowMaterial,
49
- type ShadowMaterialUniforms
50
- } from './ShadowMaterial'
43
+ import type { ShadowMaterial, ShadowMaterialUniforms } from './ShadowMaterial'
51
44
  import { ShadowPass } from './ShadowPass'
52
45
  import {
53
46
  createAtmosphereUniforms,
@@ -90,7 +83,7 @@ const cloudsUniformKeys = [
90
83
  // prettier-ignore
91
84
  const cloudsMaterialParameterKeys = [
92
85
  'multiScatteringOctaves',
93
- 'accurateSunSkyIrradiance',
86
+ 'accurateSunSkyLight',
94
87
  'accuratePhaseFunction',
95
88
  ] as const satisfies Array<keyof CloudsMaterial>
96
89
 
@@ -708,20 +701,40 @@ export class CloudsEffect extends Effect {
708
701
  this.cloudsPass.currentMaterial.scatterAnisotropyMix = value
709
702
  }
710
703
 
704
+ /** @deprecated Use skyLightScale instead. */
711
705
  get skyIrradianceScale(): number {
712
- return this.cloudsPass.currentMaterial.uniforms.skyIrradianceScale.value
706
+ return this.skyLightScale
713
707
  }
714
708
 
709
+ /** @deprecated Use skyLightScale instead. */
715
710
  set skyIrradianceScale(value: number) {
716
- this.cloudsPass.currentMaterial.uniforms.skyIrradianceScale.value = value
711
+ this.skyLightScale = value
712
+ }
713
+
714
+ get skyLightScale(): number {
715
+ return this.cloudsPass.currentMaterial.uniforms.skyLightScale.value
716
+ }
717
+
718
+ set skyLightScale(value: number) {
719
+ this.cloudsPass.currentMaterial.uniforms.skyLightScale.value = value
717
720
  }
718
721
 
722
+ /** @deprecated Use groundBounceScale instead. */
719
723
  get groundIrradianceScale(): number {
720
- return this.cloudsPass.currentMaterial.uniforms.groundIrradianceScale.value
724
+ return this.groundBounceScale
721
725
  }
722
726
 
727
+ /** @deprecated Use groundBounceScale instead. */
723
728
  set groundIrradianceScale(value: number) {
724
- this.cloudsPass.currentMaterial.uniforms.groundIrradianceScale.value = value
729
+ this.groundBounceScale = value
730
+ }
731
+
732
+ get groundBounceScale(): number {
733
+ return this.cloudsPass.currentMaterial.uniforms.groundBounceScale.value
734
+ }
735
+
736
+ set groundBounceScale(value: number) {
737
+ this.cloudsPass.currentMaterial.uniforms.groundBounceScale.value = value
725
738
  }
726
739
 
727
740
  get powderScale(): number {
@@ -756,11 +769,11 @@ export class CloudsEffect extends Effect {
756
769
 
757
770
  // Atmosphere parameters
758
771
 
759
- get irradianceTexture(): DataTexture | null {
772
+ get irradianceTexture(): Texture | null {
760
773
  return this.cloudsPass.currentMaterial.irradianceTexture
761
774
  }
762
775
 
763
- set irradianceTexture(value: DataTexture | null) {
776
+ set irradianceTexture(value: Texture | null) {
764
777
  this.cloudsPass.currentMaterial.irradianceTexture = value
765
778
  }
766
779
 
@@ -772,28 +785,36 @@ export class CloudsEffect extends Effect {
772
785
  this.cloudsPass.currentMaterial.scatteringTexture = value
773
786
  }
774
787
 
775
- get transmittanceTexture(): DataTexture | null {
788
+ get transmittanceTexture(): Texture | null {
776
789
  return this.cloudsPass.currentMaterial.transmittanceTexture
777
790
  }
778
791
 
779
- set transmittanceTexture(value: DataTexture | null) {
792
+ set transmittanceTexture(value: Texture | null) {
780
793
  this.cloudsPass.currentMaterial.transmittanceTexture = value
781
794
  }
782
795
 
783
- get ellipsoid(): Ellipsoid {
784
- return this.cloudsPass.currentMaterial.ellipsoid
796
+ get singleMieScatteringTexture(): Data3DTexture | null {
797
+ return this.cloudsPass.currentMaterial.singleMieScatteringTexture
785
798
  }
786
799
 
787
- set ellipsoid(value: Ellipsoid) {
788
- this.cloudsPass.currentMaterial.ellipsoid = value
800
+ set singleMieScatteringTexture(value: Data3DTexture | null) {
801
+ this.cloudsPass.currentMaterial.singleMieScatteringTexture = value
789
802
  }
790
803
 
791
- get photometric(): boolean {
792
- return this.cloudsPass.currentMaterial.photometric
804
+ get higherOrderScatteringTexture(): Data3DTexture | null {
805
+ return this.cloudsPass.currentMaterial.higherOrderScatteringTexture
793
806
  }
794
807
 
795
- set photometric(value: boolean) {
796
- this.cloudsPass.currentMaterial.photometric = value
808
+ set higherOrderScatteringTexture(value: Data3DTexture | null) {
809
+ this.cloudsPass.currentMaterial.higherOrderScatteringTexture = value
810
+ }
811
+
812
+ get ellipsoid(): Ellipsoid {
813
+ return this.cloudsPass.currentMaterial.ellipsoid
814
+ }
815
+
816
+ set ellipsoid(value: Ellipsoid) {
817
+ this.cloudsPass.currentMaterial.ellipsoid = value
797
818
  }
798
819
 
799
820
  get sunAngularRadius(): number {
@@ -24,9 +24,10 @@ import {
24
24
  type AtmosphereMaterialBaseUniforms
25
25
  } from '@takram/three-atmosphere'
26
26
  import {
27
- parameters as atmosphereParameters,
28
- functions
29
- } from '@takram/three-atmosphere/shaders'
27
+ common,
28
+ definitions,
29
+ runtime
30
+ } from '@takram/three-atmosphere/shaders/bruneton'
30
31
  import {
31
32
  assertType,
32
33
  define,
@@ -50,10 +51,10 @@ import {
50
51
 
51
52
  import { bayerOffsets } from './bayer'
52
53
  import { defaults } from './qualityPresets'
53
- import {
54
- type AtmosphereUniforms,
55
- type CloudLayerUniforms,
56
- type CloudParameterUniforms
54
+ import type {
55
+ AtmosphereUniforms,
56
+ CloudLayerUniforms,
57
+ CloudParameterUniforms
57
58
  } from './uniforms'
58
59
 
59
60
  import fragmentShader from './shaders/clouds.frag?raw'
@@ -97,8 +98,8 @@ export interface CloudsMaterialUniforms
97
98
  stbnTexture: Uniform<Data3DTexture | null>
98
99
 
99
100
  // Scattering
100
- skyIrradianceScale: Uniform<number>
101
- groundIrradianceScale: Uniform<number>
101
+ skyLightScale: Uniform<number>
102
+ groundBounceScale: Uniform<number>
102
103
  powderScale: Uniform<number>
103
104
  powderExponent: Uniform<number>
104
105
 
@@ -160,8 +161,11 @@ export class CloudsMaterial extends AtmosphereMaterialBase {
160
161
  glslVersion: GLSL3,
161
162
  vertexShader: resolveIncludes(vertexShader, {
162
163
  atmosphere: {
163
- parameters: atmosphereParameters,
164
- functions
164
+ bruneton: {
165
+ common,
166
+ definitions,
167
+ runtime
168
+ }
165
169
  },
166
170
  types
167
171
  }),
@@ -178,8 +182,11 @@ export class CloudsMaterial extends AtmosphereMaterialBase {
178
182
  vogelDisk
179
183
  },
180
184
  atmosphere: {
181
- parameters: atmosphereParameters,
182
- functions
185
+ bruneton: {
186
+ common,
187
+ definitions,
188
+ runtime
189
+ }
183
190
  },
184
191
  types,
185
192
  parameters,
@@ -208,8 +215,8 @@ export class CloudsMaterial extends AtmosphereMaterialBase {
208
215
  stbnTexture: new Uniform(null),
209
216
 
210
217
  // Scattering
211
- skyIrradianceScale: new Uniform(1),
212
- groundIrradianceScale: new Uniform(1),
218
+ skyLightScale: new Uniform(1),
219
+ groundBounceScale: new Uniform(1),
213
220
  powderScale: new Uniform(0.8),
214
221
  powderExponent: new Uniform(150),
215
222
 
@@ -292,15 +299,15 @@ export class CloudsMaterial extends AtmosphereMaterialBase {
292
299
  this.needsUpdate = true
293
300
  }
294
301
 
295
- const prevGroundIrradiance = this.defines.GROUND_IRRADIANCE != null
302
+ const prevGroundIrradiance = this.defines.GROUND_BOUNCE != null
296
303
  const nextGroundIrradiance =
297
- this.uniforms.groundIrradianceScale.value > 0 &&
304
+ this.uniforms.groundBounceScale.value > 0 &&
298
305
  this.uniforms.maxIterationCountToGround.value > 0
299
306
  if (nextGroundIrradiance !== prevGroundIrradiance) {
300
307
  if (nextPowder) {
301
- this.defines.GROUND_IRRADIANCE = '1'
308
+ this.defines.GROUND_BOUNCE = '1'
302
309
  } else {
303
- delete this.defines.GROUND_IRRADIANCE
310
+ delete this.defines.GROUND_BOUNCE
304
311
  }
305
312
  this.needsUpdate = true
306
313
  }
@@ -447,8 +454,18 @@ export class CloudsMaterial extends AtmosphereMaterialBase {
447
454
  @defineInt('MULTI_SCATTERING_OCTAVES', { min: 1, max: 12 })
448
455
  multiScatteringOctaves: number = defaults.clouds.multiScatteringOctaves
449
456
 
450
- @define('ACCURATE_SUN_SKY_IRRADIANCE')
451
- accurateSunSkyIrradiance: boolean = defaults.clouds.accurateSunSkyIrradiance
457
+ /** @deprecated Use accurateSunSkyLight instead. */
458
+ get accurateSunSkyIrradiance(): boolean {
459
+ return this.accurateSunSkyLight
460
+ }
461
+
462
+ /** @deprecated Use accurateSunSkyLight instead. */
463
+ set accurateSunSkyIrradiance(value: boolean) {
464
+ this.accurateSunSkyLight = value
465
+ }
466
+
467
+ @define('ACCURATE_SUN_SKY_LIGHT')
468
+ accurateSunSkyLight: boolean = defaults.clouds.accurateSunSkyLight
452
469
 
453
470
  @define('ACCURATE_PHASE_FUNCTION')
454
471
  accuratePhaseFunction: boolean = defaults.clouds.accuratePhaseFunction
package/src/CloudsPass.ts CHANGED
@@ -12,16 +12,16 @@ import {
12
12
  type WebGLRenderer
13
13
  } from 'three'
14
14
 
15
- import { type AtmosphereParameters } from '@takram/three-atmosphere'
15
+ import type { AtmosphereParameters } from '@takram/three-atmosphere'
16
16
 
17
17
  import { CloudsMaterial } from './CloudsMaterial'
18
18
  import { CloudsResolveMaterial } from './CloudsResolveMaterial'
19
19
  import { PassBase, type PassBaseOptions } from './PassBase'
20
20
  import { defaults } from './qualityPresets'
21
- import {
22
- type AtmosphereUniforms,
23
- type CloudLayerUniforms,
24
- type CloudParameterUniforms
21
+ import type {
22
+ AtmosphereUniforms,
23
+ CloudLayerUniforms,
24
+ CloudParameterUniforms
25
25
  } from './uniforms'
26
26
 
27
27
  type RenderTarget = WebGLRenderTarget & {
@@ -43,7 +43,6 @@ function createRenderTarget(
43
43
  shadowLength?: Texture
44
44
  } = new WebGLRenderTarget(1, 1, {
45
45
  depthBuffer: false,
46
- stencilBuffer: false,
47
46
  type: HalfFloatType
48
47
  })
49
48
  renderTarget.texture.minFilter = LinearFilter
package/src/PassBase.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Pass } from 'postprocessing'
2
2
  import { Camera } from 'three'
3
3
 
4
- import { type CascadedShadowMaps } from './CascadedShadowMaps'
4
+ import type { CascadedShadowMaps } from './CascadedShadowMaps'
5
5
 
6
6
  export interface PassBaseOptions {
7
7
  shadow: CascadedShadowMaps
@@ -14,7 +14,7 @@ import {
14
14
  type WebGLRenderer
15
15
  } from 'three'
16
16
 
17
- import { type ProceduralTexture } from './ProceduralTexture'
17
+ import type { ProceduralTexture } from './ProceduralTexture'
18
18
 
19
19
  export type Procedural3DTexture = ProceduralTexture<Data3DTexture>
20
20
 
@@ -53,7 +53,6 @@ export class Procedural3DTextureBase implements Procedural3DTexture {
53
53
 
54
54
  this.renderTarget = new WebGL3DRenderTarget(size, size, size, {
55
55
  depthBuffer: false,
56
- stencilBuffer: false,
57
56
  format: RedFormat
58
57
  })
59
58
  const texture = this.renderTarget.texture
@@ -79,13 +78,12 @@ export class Procedural3DTextureBase implements Procedural3DTexture {
79
78
 
80
79
  // Unfortunately, rendering into 3D target requires as many draw calls as
81
80
  // the value of "size".
82
- const renderTarget = renderer.getRenderTarget()
83
81
  for (let layer = 0; layer < this.size; ++layer) {
84
82
  this.material.uniforms.layer.value = layer / this.size
85
83
  renderer.setRenderTarget(this.renderTarget, layer)
86
84
  renderer.render(this.mesh, this.camera)
87
85
  }
88
- renderer.setRenderTarget(renderTarget)
86
+ renderer.setRenderTarget(null)
89
87
  }
90
88
 
91
89
  get texture(): Data3DTexture {
@@ -58,7 +58,6 @@ export class ProceduralTextureBase implements ProceduralTexture {
58
58
 
59
59
  this.renderTarget = new WebGLRenderTarget(size, size, {
60
60
  depthBuffer: false,
61
- stencilBuffer: false,
62
61
  format: RGBAFormat
63
62
  })
64
63
  const texture = this.renderTarget.texture
@@ -82,10 +81,9 @@ export class ProceduralTextureBase implements ProceduralTexture {
82
81
  }
83
82
  this.needsRender = false
84
83
 
85
- const renderTarget = renderer.getRenderTarget()
86
84
  renderer.setRenderTarget(this.renderTarget)
87
85
  renderer.render(this.mesh, this.camera)
88
- renderer.setRenderTarget(renderTarget)
86
+ renderer.setRenderTarget(null)
89
87
  }
90
88
 
91
89
  get texture(): Texture {
@@ -1,9 +1,9 @@
1
1
  import { ShaderPass, type CopyMaterial } from 'postprocessing'
2
- import {
3
- type Uniform,
4
- type WebGLArrayRenderTarget,
5
- type WebGLRenderer,
6
- type WebGLRenderTarget
2
+ import type {
3
+ Uniform,
4
+ WebGLArrayRenderTarget,
5
+ WebGLRenderer,
6
+ WebGLRenderTarget
7
7
  } from 'three'
8
8
 
9
9
  import { setArrayRenderTargetLayers } from './helpers/setArrayRenderTargetLayers'
@@ -17,10 +17,10 @@ import {
17
17
  import { math, raySphereIntersection } from '@takram/three-geospatial/shaders'
18
18
 
19
19
  import { defaults } from './qualityPresets'
20
- import {
21
- type AtmosphereUniforms,
22
- type CloudLayerUniforms,
23
- type CloudParameterUniforms
20
+ import type {
21
+ AtmosphereUniforms,
22
+ CloudLayerUniforms,
23
+ CloudParameterUniforms
24
24
  } from './uniforms'
25
25
 
26
26
  import clouds from './shaders/clouds.glsl?raw'
package/src/ShadowPass.ts CHANGED
@@ -12,16 +12,15 @@ import { PassBase, type PassBaseOptions } from './PassBase'
12
12
  import { ShaderArrayPass } from './ShaderArrayPass'
13
13
  import { ShadowMaterial } from './ShadowMaterial'
14
14
  import { ShadowResolveMaterial } from './ShadowResolveMaterial'
15
- import {
16
- type AtmosphereUniforms,
17
- type CloudLayerUniforms,
18
- type CloudParameterUniforms
15
+ import type {
16
+ AtmosphereUniforms,
17
+ CloudLayerUniforms,
18
+ CloudParameterUniforms
19
19
  } from './uniforms'
20
20
 
21
21
  function createRenderTarget(name: string): WebGLArrayRenderTarget {
22
22
  const renderTarget = new WebGLArrayRenderTarget(1, 1, 1, {
23
- depthBuffer: false,
24
- stencilBuffer: false
23
+ depthBuffer: false
25
24
  })
26
25
  // Constructor option doesn't work
27
26
  renderTarget.texture.type = HalfFloatType
package/src/constants.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export const CLOUD_SHAPE_TEXTURE_SIZE = 128
2
2
  export const CLOUD_SHAPE_DETAIL_TEXTURE_SIZE = 32
3
3
 
4
+ // Reference to the latest assets.
4
5
  const ref = '45a1c6c1bb9fd38b3680fd120795ff4c32df68ff'
5
6
  export const DEFAULT_LOCAL_WEATHER_URL = `https://media.githubusercontent.com/media/takram-design-engineering/three-geospatial/${ref}/packages/clouds/assets/local_weather.png`
6
7
  export const DEFAULT_SHAPE_URL = `https://media.githubusercontent.com/media/takram-design-engineering/three-geospatial/${ref}/packages/clouds/assets/shape.bin`
@@ -1,15 +1,12 @@
1
- import { type WebGLArrayRenderTarget, type WebGLRenderer } from 'three'
1
+ import type { WebGLArrayRenderTarget, WebGLRenderer } from 'three'
2
2
  import invariant from 'tiny-invariant'
3
3
 
4
4
  export function setArrayRenderTargetLayers(
5
5
  renderer: WebGLRenderer,
6
6
  outputBuffer: WebGLArrayRenderTarget
7
7
  ): void {
8
- const glTexture = (
9
- renderer.properties.get(outputBuffer.texture) as {
10
- __webglTexture?: WebGLTexture
11
- }
12
- ).__webglTexture
8
+ const property: any = renderer.properties.get(outputBuffer.texture)
9
+ const glTexture: WebGLTexture | undefined = property.__webglTexture
13
10
 
14
11
  const gl = renderer.getContext()
15
12
  invariant(gl instanceof WebGL2RenderingContext)
@@ -1,7 +1,7 @@
1
1
  import { Vector2 } from 'three'
2
- import { type PartialDeep, type SharedUnionFieldsDeep } from 'type-fest'
2
+ import type { PartialDeep, SharedUnionFieldsDeep } from 'type-fest'
3
3
 
4
- import { type CloudsEffect } from './CloudsEffect'
4
+ import type { CloudsEffect } from './CloudsEffect'
5
5
 
6
6
  export type QualityPreset = 'low' | 'medium' | 'high' | 'ultra'
7
7
 
@@ -13,7 +13,7 @@ const values = {
13
13
  haze: true,
14
14
  clouds: {
15
15
  multiScatteringOctaves: 8,
16
- accurateSunSkyIrradiance: true,
16
+ accurateSunSkyLight: true,
17
17
  accuratePhaseFunction: false,
18
18
 
19
19
  // Primary raymarch
@@ -67,7 +67,7 @@ export const qualityPresets: Record<QualityPreset, Schema> = {
67
67
  turbulence: false, // Expensive
68
68
  clouds: {
69
69
  ...defaults.clouds,
70
- accurateSunSkyIrradiance: false, // Greatly reduces texel reads.
70
+ accurateSunSkyLight: false, // Greatly reduces texel reads.
71
71
  maxIterationCount: 200,
72
72
  minStepSize: 100,
73
73
  maxRayDistance: 1e5,
@@ -95,7 +95,7 @@ export const qualityPresets: Record<QualityPreset, Schema> = {
95
95
  ...defaults.clouds,
96
96
  minDensity: 1e-4,
97
97
  minExtinction: 1e-4,
98
- accurateSunSkyIrradiance: false,
98
+ accurateSunSkyLight: false,
99
99
  maxIterationCountToSun: 2,
100
100
  maxIterationCountToGround: 1
101
101
  },
@@ -7,7 +7,7 @@ import {
7
7
  type Ref
8
8
  } from 'react'
9
9
 
10
- import { type ExpandNestedProps } from '@takram/three-geospatial/r3f'
10
+ import type { ExpandNestedProps } from '@takram/three-geospatial/r3f'
11
11
 
12
12
  import {
13
13
  CloudLayer as CloudLayerImpl,