@takram/three-atmosphere
Version:
A Three.js and R3F implementation of Precomputed Atmospheric Scattering
76 lines (66 loc) • 2.18 kB
text/typescript
import { Vector3 } from 'three'
import { radians } from '@takram/three-geospatial'
const paramKeys = [
'solarIrradiance',
'sunAngularRadius',
'bottomRadius',
'topRadius',
'rayleighScattering',
'mieScattering',
'miePhaseFunctionG',
'muSMin',
'skyRadianceToLuminance',
'sunRadianceToLuminance',
'luminousEfficiency'
] as const
export interface AtmosphereParametersOptions
extends Partial<Pick<AtmosphereParameters, (typeof paramKeys)[number]>> {}
function applyOptions(
target: AtmosphereParameters,
params?: AtmosphereParametersOptions
): void {
if (params == null) {
return
}
for (const key of paramKeys) {
const value = params[key]
if (value == null) {
continue
}
if (target[key] instanceof Vector3) {
target[key].copy(value as Vector3)
} else {
;(target as any)[key] = value
}
}
}
export class AtmosphereParameters {
static readonly DEFAULT = /*#__PURE__*/ new AtmosphereParameters()
solarIrradiance = new Vector3(1.474, 1.8504, 1.91198)
sunAngularRadius = 0.004675
bottomRadius = 6360000
topRadius = 6420000
rayleighScattering = new Vector3(0.005802, 0.013558, 0.0331)
mieScattering = new Vector3(0.003996, 0.003996, 0.003996)
miePhaseFunctionG = 0.8
muSMin = Math.cos(radians(120))
// Radiance to luminance conversion
// prettier-ignore
skyRadianceToLuminance = new Vector3(114974.916437, 71305.954816, 65310.548555)
sunRadianceToLuminance = new Vector3(98242.786222, 69954.398112, 66475.012354)
luminousEfficiency = new Vector3(0.2126, 0.7152, 0.0722)
skyRadianceToRelativeLuminance = new Vector3()
sunRadianceToRelativeLuminance = new Vector3()
constructor(options?: AtmosphereParametersOptions) {
applyOptions(this, options)
// We could store luminance (cd/m^2) in render buffers, but the illuminance
// values easily saturate.
const luminance = this.luminousEfficiency.dot(this.skyRadianceToLuminance)
this.skyRadianceToRelativeLuminance
.copy(this.skyRadianceToLuminance)
.divideScalar(luminance)
this.sunRadianceToRelativeLuminance
.copy(this.sunRadianceToLuminance)
.divideScalar(luminance)
}
}