@babylonjs/addons 8.34.0 → 8.35.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.
@@ -121,6 +121,9 @@ export class AtmospherePBRMaterialPlugin extends MaterialPluginBase {
121
121
  if (effect) {
122
122
  this._atmosphere.bindUniformBufferToEffect(effect);
123
123
  }
124
+ // Need the offset to apply which will take a world space position and convert it to a global space position in the atmosphere.
125
+ // If floating origin mode is enabled, that offset is the floating origin offset.
126
+ // If not, it's an offset up the Y-axis by the planet radius.
124
127
  uniformBuffer.updateVector3(OriginOffsetUniformName, scene.floatingOriginMode
125
128
  ? Vector3ScaleToRef(scene.floatingOriginOffset, 0.001, OriginOffsetKm) // Convert to kilometers
126
129
  : Vector3FromFloatsToRef(0, atmosphere.physicalProperties.planetRadius, 0, OriginOffsetKm) // planetRadius is already in kilometers
@@ -1 +1 @@
1
- {"version":3,"file":"atmospherePBRMaterialPlugin.js","sourceRoot":"","sources":["../../../../dev/addons/src/atmosphere/atmospherePBRMaterialPlugin.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,cAAc;AAKd,OAAO,EAAE,eAAe,EAAE,qDAAuC;AACjE,OAAO,EAAE,kBAAkB,EAAE,wDAA0C;AAGvE,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,uDAAyC;AAE7F,MAAM,4BAA6B,SAAQ,eAAe;IAQtD;;;OAGG;IACH,YAAY,uBAAgC;QACxC,KAAK,EAAE,CAAC;QAVZ,gEAAgE;QACzD,uCAAkC,GAAG,KAAK,CAAC;QAClD,gEAAgE;QACzD,2CAAsC,GAAG,KAAK,CAAC;QAQlD,IAAI,CAAC,0BAA0B,GAAG,uBAAuB,CAAC;IAC9D,CAAC;CACJ;AAED,MAAM,uBAAuB,GAAG,gBAAgB,CAAC;AACjD,MAAM,8BAA8B,GAAG,qBAAqB,CAAC;AAE7D,MAAM,QAAQ,GAAG;IACb,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;IACxD,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;IACpD,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE;CAClE,CAAC;AACF,MAAM,YAAY,GAAG,CAAC,UAAsB,EAAE,EAAE,CAAC,CAAC;IAC9C,GAAG,EAAE,QAAQ;IACb,QAAQ,EAAE,gBAAgB,8BAA8B,mBAAmB,uBAAuB,KAAK;IACvG,gBAAgB,EAAE,UAAU,CAAC,aAAa,CAAC,eAAe,EAAE;CAC/D,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,6BAA6B,CAAC;AACjD,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAE5C;;GAEG;AACH,MAAM,OAAO,2BAA4B,SAAQ,kBAAkB;IAC/D;;;;;OAKG;IACH,YACI,QAAkB,EACD,WAAuB,EACvB,8BAA8B,KAAK;QAEpD,KAAK,CACD,QAAQ,EACR,UAAU,EACV,cAAc,EACd;YACI,gEAAgE;YAChE,qBAAqB,EAAE,WAAW,CAAC,uBAAuB,KAAK,IAAI;YACnE,gEAAgE;YAChE,0BAA0B,EAAE,2BAA2B;YACvD,gEAAgE;YAChE,0BAA0B,EAAE,2BAA2B,IAAI,WAAW,CAAC,6BAA6B;YACpG,gEAAgE;YAChE,kCAAkC,EAAE,2BAA2B,IAAI,WAAW,CAAC,0BAA0B,KAAK,GAAG;YACjH,gEAAgE;YAChE,sCAAsC,EAAE,2BAA2B,IAAI,WAAW,CAAC,6BAA6B,KAAK,GAAG;SAC3H,EACD,KAAK,EAAE,qFAAqF;QAC5F,IAAI,EAAE,SAAS;QACf,IAAI,CAAC,kBAAkB;SAC1B,CAAC;QAtBe,gBAAW,GAAX,WAAW,CAAY;QACvB,gCAA2B,GAA3B,2BAA2B,CAAQ;QAuBpD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAE3B,wFAAwF;QACxF,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACa,sBAAsB,CAAC,KAAe;QAClD,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC;QACrD,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;IAED;;OAEG;IACa,WAAW;QACvB,OAAO,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACa,iBAAiB;QAC7B,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,IAAI,CAAC,2BAA2B,IAAI,UAAU,CAAC,6BAA6B,EAAE,CAAC;YAC/E,MAAM,gCAAgC,GAAG,UAAU,CAAC,gCAAgC,CAAC;YACrF,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,gCAAgC,EAAE,OAAO,EAAE,CAAC;QACvE,CAAC;QACD,MAAM,4BAA4B,GAAG,UAAU,CAAC,gBAAgB,EAAE,YAAY,IAAI,IAAI,CAAC;QACvF,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,4BAA4B,EAAE,OAAO,EAAE,CAAC;QAC/D,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;OAEG;IACa,iBAAiB,CAAC,eAA8B;QAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,IAAI,CAAC,2BAA2B,IAAI,UAAU,CAAC,6BAA6B,EAAE,CAAC;YAC/E,MAAM,gCAAgC,GAAG,UAAU,CAAC,gCAAgC,CAAC;YACrF,IAAI,gCAAgC,EAAE,CAAC;gBACnC,eAAe,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAC3D,CAAC;QACL,CAAC;QAED,MAAM,4BAA4B,GAAG,UAAU,CAAC,gBAAgB,EAAE,YAAY,IAAI,IAAI,CAAC;QACvF,IAAI,4BAA4B,EAAE,CAAC;YAC/B,eAAe,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACvD,CAAC;IACL,CAAC;IAED;;OAEG;IACa,cAAc,CAAC,aAA4B;QACvD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QAEjC,sDAAsD;QACtD,MAAM,MAAM,GAAG,aAAa,CAAC,aAAa,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACT,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACvD,CAAC;QAED,aAAa,CAAC,aAAa,CACvB,uBAAuB,EACvB,KAAK,CAAC,kBAAkB;YACpB,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,wBAAwB;YAC/F,CAAC,CAAC,sBAAsB,CAAC,CAAC,EAAE,UAAU,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC,wCAAwC;SAC1I,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;QACxC,aAAa,CAAC,YAAY,CAAC,8BAA8B,EAAE,GAAG,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,CAAC,CAAC;QAEtF,IAAI,IAAI,CAAC,2BAA2B,IAAI,UAAU,CAAC,6BAA6B,EAAE,CAAC;YAC/E,MAAM,gCAAgC,GAAG,UAAU,CAAC,gCAAgC,CAAC;YACrF,aAAa,CAAC,UAAU,CAAC,sBAAsB,EAAE,gCAAgC,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,4BAA4B,GAAG,UAAU,CAAC,gBAAgB,EAAE,YAAY,IAAI,IAAI,CAAC;QACvF,aAAa,CAAC,UAAU,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;IAC/E,CAAC;IAED;;OAEG;IACa,cAAc,CAAC,OAAqC;QAChE,MAAM,2BAA2B,GAAG,OAAO,CAAC,0BAA0B,CAAC;QACvE,MAAM,mCAAmC,GAAG,OAAO,CAAC,kCAAkC,CAAC;QACvF,MAAM,sCAAsC,GAAG,OAAO,CAAC,sCAAsC,CAAC;QAC9F,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,2BAA2B,IAAI,IAAI,CAAC,WAAW,CAAC,6BAA6B,CAAC;QACxH,OAAO,CAAC,kCAAkC,GAAG,IAAI,CAAC,2BAA2B,IAAI,IAAI,CAAC,WAAW,CAAC,0BAA0B,KAAK,GAAG,CAAC;QACrI,OAAO,CAAC,sCAAsC,GAAG,IAAI,CAAC,2BAA2B,IAAI,IAAI,CAAC,WAAW,CAAC,6BAA6B,KAAK,GAAG,CAAC;QAC5I,IACI,2BAA2B,KAAK,OAAO,CAAC,0BAA0B;YAClE,mCAAmC,KAAK,OAAO,CAAC,kCAAkC;YAClF,sCAAsC,KAAK,OAAO,CAAC,sCAAsC,EAC3F,CAAC;YACC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAED;;OAEG;IACa,WAAW,CAAC,QAAkB;QAC1C,QAAQ,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,2BAA2B,IAAI,IAAI,CAAC,WAAW,CAAC,6BAA6B,EAAE,CAAC;YACrF,QAAQ,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;IACL,CAAC;IAED;;OAEG;IACa,aAAa,CAAC,UAAkB;QAC5C,kDAAkD;QAClD,qCAAqC;QACrC,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,sBAAsB,CAAC;QACzE,MAAM,uBAAuB,GAAG,MAAM,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,kBAAkB,CAAC;QAEvF,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC;QAC/D,MAAM,uBAAuB,GAAG,gBAAgB,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,yCAAyC,CAAC;QAEpI,OAAO;YACH,2BAA2B,EACvB,IAAI,CAAC,2BAA2B,IAAI,IAAI,CAAC,WAAW,CAAC,6BAA6B;gBAC9E,CAAC,CAAC,6HAA6H,uBAAuB,mCAAmC;gBACzL,CAAC,CAAC,0CAA0C,uBAAuB,mCAAmC;YAC9G,mBAAmB,EAAE;;6DAE4B,uBAAuB;;;0CAG1C,uBAAuB;;;;CAIhE;YACW,iBAAiB,EAAE;;8DAE+B,uBAAuB;;;;0CAI3C,uBAAuB;;;;;;;;;;;;;;;;;;;;;;CAsBhE;YACW,6EAA6E;YAC7E,0BAA0B,EAAE;;;;;;4CAMI,8BAA8B;;;;;;;;;;;CAWzE;SACQ,CAAC;IACN,CAAC;CACJ","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { Vector3FromFloatsToRef, Vector3ScaleToRef } from \"core/Maths/math.vector.functions\";\r\n\r\nclass AtmospherePBRMaterialDefines extends MaterialDefines {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public USE_AERIAL_PERSPECTIVE_LUT: boolean;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public APPLY_AERIAL_PERSPECTIVE_INTENSITY = false;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS = false;\r\n\r\n /**\r\n * Constructs the {@link AtmospherePBRMaterialDefines}.\r\n * @param useAerialPerspectiveLut - Whether to use the aerial perspective LUT.\r\n */\r\n constructor(useAerialPerspectiveLut: boolean) {\r\n super();\r\n this.USE_AERIAL_PERSPECTIVE_LUT = useAerialPerspectiveLut;\r\n }\r\n}\r\n\r\nconst OriginOffsetUniformName = \"originOffsetKm\";\r\nconst InverseViewportSizeUniformName = \"inverseViewportSize\";\r\n\r\nconst UboArray = [\r\n { name: OriginOffsetUniformName, size: 3, type: \"vec3\" },\r\n { name: \"_atmoPbrPadding1\", size: 1, type: \"float\" },\r\n { name: InverseViewportSizeUniformName, size: 2, type: \"vec2\" },\r\n];\r\nconst MakeUniforms = (atmosphere: Atmosphere) => ({\r\n ubo: UboArray,\r\n fragment: `uniform vec2 ${InverseViewportSizeUniformName};\\nuniform vec3 ${OriginOffsetUniformName};\\n`,\r\n externalUniforms: atmosphere.uniformBuffer.getUniformNames(),\r\n});\r\n\r\nconst PluginName = \"AtmospherePBRMaterialPlugin\";\r\nconst PluginPriority = 600;\r\nconst OriginOffsetKm = { x: 0, y: 0, z: 0 };\r\n\r\n/**\r\n * Adds shading logic to a PBRMaterial that provides radiance, diffuse sky irradiance, and aerial perspective from the atmosphere.\r\n */\r\nexport class AtmospherePBRMaterialPlugin extends MaterialPluginBase {\r\n /**\r\n * Constructs the {@link AtmospherePBRMaterialPlugin}.\r\n * @param material - The material to apply the plugin to.\r\n * @param _atmosphere - The atmosphere to use for shading.\r\n * @param _isAerialPerspectiveEnabled - Whether to apply aerial perspective.\r\n */\r\n constructor(\r\n material: Material,\r\n private readonly _atmosphere: Atmosphere,\r\n private readonly _isAerialPerspectiveEnabled = false\r\n ) {\r\n super(\r\n material,\r\n PluginName,\r\n PluginPriority,\r\n {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n USE_CUSTOM_REFLECTION: _atmosphere.diffuseSkyIrradianceLut !== null,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n CUSTOM_FRAGMENT_BEFORE_FOG: _isAerialPerspectiveEnabled,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n USE_AERIAL_PERSPECTIVE_LUT: _isAerialPerspectiveEnabled && _atmosphere.isAerialPerspectiveLutEnabled,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPLY_AERIAL_PERSPECTIVE_INTENSITY: _isAerialPerspectiveEnabled && _atmosphere.aerialPerspectiveIntensity !== 1.0,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS: _isAerialPerspectiveEnabled && _atmosphere.aerialPerspectiveRadianceBias !== 0.0,\r\n },\r\n false, // addPluginToList -- false because we need to control when this is added to the list\r\n true, // enable\r\n true // resolveIncludes\r\n );\r\n\r\n this.doNotSerialize = true;\r\n\r\n // This calls `getCode` so we need to do this after having initialized the class fields.\r\n this._pluginManager._addPlugin(this);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getUniformBuffersNames(_ubos: string[]): void {\r\n const uniformBuffer = this._atmosphere.uniformBuffer;\r\n if (uniformBuffer.useUbo) {\r\n _ubos.push(uniformBuffer.name);\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getUniforms() {\r\n return MakeUniforms(this._atmosphere);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override isReadyForSubMesh(): boolean {\r\n let isReady = true;\r\n const atmosphere = this._atmosphere;\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n isReady = isReady && !!aerialPerspectiveLutRenderTarget?.isReady();\r\n }\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n isReady = isReady && !!transmittanceLutRenderTarget?.isReady();\r\n return isReady;\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getActiveTextures(_activeTextures: BaseTexture[]): void {\r\n const atmosphere = this._atmosphere;\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n if (aerialPerspectiveLutRenderTarget) {\r\n _activeTextures.push(aerialPerspectiveLutRenderTarget);\r\n }\r\n }\r\n\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n if (transmittanceLutRenderTarget) {\r\n _activeTextures.push(transmittanceLutRenderTarget);\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override bindForSubMesh(uniformBuffer: UniformBuffer): void {\r\n const atmosphere = this._atmosphere;\r\n const scene = atmosphere.scene;\r\n const engine = scene.getEngine();\r\n\r\n // Bind the atmosphere's uniform buffer to the effect.\r\n const effect = uniformBuffer.currentEffect;\r\n if (effect) {\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n }\r\n\r\n uniformBuffer.updateVector3(\r\n OriginOffsetUniformName,\r\n scene.floatingOriginMode\r\n ? Vector3ScaleToRef(scene.floatingOriginOffset, 0.001, OriginOffsetKm) // Convert to kilometers\r\n : Vector3FromFloatsToRef(0, atmosphere.physicalProperties.planetRadius, 0, OriginOffsetKm) // planetRadius is already in kilometers\r\n );\r\n\r\n const width = engine.getRenderWidth();\r\n const height = engine.getRenderHeight();\r\n uniformBuffer.updateFloat2(InverseViewportSizeUniformName, 1.0 / width, 1.0 / height);\r\n\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n uniformBuffer.setTexture(\"aerialPerspectiveLut\", aerialPerspectiveLutRenderTarget);\r\n }\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n uniformBuffer.setTexture(\"transmittanceLut\", transmittanceLutRenderTarget);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override prepareDefines(defines: AtmospherePBRMaterialDefines): void {\r\n const lastUseAerialPerspectiveLut = defines.USE_AERIAL_PERSPECTIVE_LUT;\r\n const lastApplyAerialPerspectiveIntensity = defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY;\r\n const lastApplyAerialPerspectiveRadianceBias = defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS;\r\n defines.USE_AERIAL_PERSPECTIVE_LUT = this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled;\r\n defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY = this._isAerialPerspectiveEnabled && this._atmosphere.aerialPerspectiveIntensity !== 1.0;\r\n defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS = this._isAerialPerspectiveEnabled && this._atmosphere.aerialPerspectiveRadianceBias !== 0.0;\r\n if (\r\n lastUseAerialPerspectiveLut !== defines.USE_AERIAL_PERSPECTIVE_LUT ||\r\n lastApplyAerialPerspectiveIntensity !== defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY ||\r\n lastApplyAerialPerspectiveRadianceBias !== defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\r\n ) {\r\n defines.markAllAsDirty();\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getSamplers(samplers: string[]): void {\r\n samplers.push(\"transmittanceLut\");\r\n if (this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled) {\r\n samplers.push(\"aerialPerspectiveLut\");\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getCustomCode(shaderType: string): Nullable<Record<string, string>> {\r\n // Assumed inputs are light0, vPositionW, normalW.\r\n // Only works for directional lights.\r\n if (shaderType !== \"fragment\") {\r\n return null;\r\n }\r\n\r\n const useUbo = this._atmosphere.scene.getEngine().supportsUniformBuffers;\r\n const directionToLightSnippet = useUbo ? \"-light0.vLightData.xyz\" : \"-vLightData0.xyz\";\r\n\r\n const useAtmosphereUbo = this._atmosphere.uniformBuffer.useUbo;\r\n const atmosphereImportSnippet = useAtmosphereUbo ? \"#include<atmosphereUboDeclaration>\" : \"#include<atmosphereFragmentDeclaration>\";\r\n\r\n return {\r\n CUSTOM_FRAGMENT_DEFINITIONS:\r\n this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled\r\n ? `uniform sampler2D transmittanceLut;\\r\\nprecision highp sampler2DArray;\\r\\nuniform sampler2DArray aerialPerspectiveLut;\\r\\n${atmosphereImportSnippet}\\r\\n#include<atmosphereFunctions>`\r\n : `uniform sampler2D transmittanceLut;\\r\\n${atmosphereImportSnippet}\\r\\n#include<atmosphereFunctions>`,\r\n CUSTOM_LIGHT0_COLOR: `\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + ${OriginOffsetUniformName};\r\n float positionRadius = length(positionGlobal);\r\n vec3 geocentricNormal = positionGlobal / positionRadius;\r\n vec3 directionToLight = ${directionToLightSnippet};\r\n float cosAngleLightToZenith = dot(directionToLight, geocentricNormal);\r\n diffuse0 = lightIntensity * sampleTransmittanceLut(transmittanceLut, positionRadius, cosAngleLightToZenith);\r\n }\r\n`,\r\n CUSTOM_REFLECTION: `\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + ${OriginOffsetUniformName};\r\n float positionRadius = length(positionGlobal);\r\n vec3 geocentricNormal = positionGlobal / positionRadius;\r\n\r\n vec3 directionToLight = ${directionToLightSnippet};\r\n float cosAngleLightToZenith = dot(directionToLight, geocentricNormal);\r\n\r\n vec2 uv = vec2(0.5 + 0.5 * cosAngleLightToZenith, (positionRadius - planetRadius) / atmosphereThickness);\r\n float irradianceScaleT = 0.5 * dot(normalW, geocentricNormal) + 0.5;\r\n float irradianceScale = ((-0.6652 * irradianceScaleT) + 1.5927) * irradianceScaleT + 0.1023;\r\n vec3 environmentIrradiance = lightIntensity * sampleReflection(irradianceSampler, uv).rgb;\r\n\r\n // Add a contribution here to estimate indirect lighting.\r\n const float r = 0.2;\r\n float indirect = getLuminance(environmentIrradiance) / max(0.00001, 1. - r);\r\n environmentIrradiance *= irradianceScale;\r\n environmentIrradiance += indirect;\r\n\r\n environmentIrradiance += additionalDiffuseSkyIrradiance;\r\n\r\n const float diffuseBrdf = 1. / PI;\r\n environmentIrradiance *= diffuseBrdf * diffuseSkyIrradianceIntensity;\r\n\r\n reflectionOut.environmentIrradiance = environmentIrradiance;\r\n reflectionOut.environmentRadiance.rgb = reflectionOut.environmentIrradiance;\r\n }\r\n`,\r\n // TODO: Support full ray marching if USE_AERIAL_PERSPECTIVE_LUT is disabled.\r\n CUSTOM_FRAGMENT_BEFORE_FOG: `\r\n #if USE_AERIAL_PERSPECTIVE_LUT\r\n {\r\n float distanceFromCameraKm = 0.001 * distance(vEyePosition.xyz, vPositionW);\r\n vec4 aerialPerspective = vec4(0.);\r\n if (sampleAerialPerspectiveLut(\r\n gl_FragCoord.xy * ${InverseViewportSizeUniformName},\r\n true,\r\n distanceFromCameraKm,\r\n NumAerialPerspectiveLutLayers,\r\n AerialPerspectiveLutKMPerSlice,\r\n AerialPerspectiveLutRangeKM,\r\n aerialPerspective)) {\r\n finalColor = aerialPerspective + (1. - aerialPerspective.a) * finalColor;\r\n }\r\n }\r\n #endif\r\n`,\r\n };\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"atmospherePBRMaterialPlugin.js","sourceRoot":"","sources":["../../../../dev/addons/src/atmosphere/atmospherePBRMaterialPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { MaterialDefines } from \"core/Materials/materialDefines\";\r\nimport { MaterialPluginBase } from \"core/Materials/materialPluginBase\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { UniformBuffer } from \"core/Materials/uniformBuffer\";\r\nimport { Vector3FromFloatsToRef, Vector3ScaleToRef } from \"core/Maths/math.vector.functions\";\r\n\r\nclass AtmospherePBRMaterialDefines extends MaterialDefines {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public USE_AERIAL_PERSPECTIVE_LUT: boolean;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public APPLY_AERIAL_PERSPECTIVE_INTENSITY = false;\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS = false;\r\n\r\n /**\r\n * Constructs the {@link AtmospherePBRMaterialDefines}.\r\n * @param useAerialPerspectiveLut - Whether to use the aerial perspective LUT.\r\n */\r\n constructor(useAerialPerspectiveLut: boolean) {\r\n super();\r\n this.USE_AERIAL_PERSPECTIVE_LUT = useAerialPerspectiveLut;\r\n }\r\n}\r\n\r\nconst OriginOffsetUniformName = \"originOffsetKm\";\r\nconst InverseViewportSizeUniformName = \"inverseViewportSize\";\r\n\r\nconst UboArray = [\r\n { name: OriginOffsetUniformName, size: 3, type: \"vec3\" },\r\n { name: \"_atmoPbrPadding1\", size: 1, type: \"float\" },\r\n { name: InverseViewportSizeUniformName, size: 2, type: \"vec2\" },\r\n];\r\nconst MakeUniforms = (atmosphere: Atmosphere) => ({\r\n ubo: UboArray,\r\n fragment: `uniform vec2 ${InverseViewportSizeUniformName};\\nuniform vec3 ${OriginOffsetUniformName};\\n`,\r\n externalUniforms: atmosphere.uniformBuffer.getUniformNames(),\r\n});\r\n\r\nconst PluginName = \"AtmospherePBRMaterialPlugin\";\r\nconst PluginPriority = 600;\r\nconst OriginOffsetKm = { x: 0, y: 0, z: 0 };\r\n\r\n/**\r\n * Adds shading logic to a PBRMaterial that provides radiance, diffuse sky irradiance, and aerial perspective from the atmosphere.\r\n */\r\nexport class AtmospherePBRMaterialPlugin extends MaterialPluginBase {\r\n /**\r\n * Constructs the {@link AtmospherePBRMaterialPlugin}.\r\n * @param material - The material to apply the plugin to.\r\n * @param _atmosphere - The atmosphere to use for shading.\r\n * @param _isAerialPerspectiveEnabled - Whether to apply aerial perspective.\r\n */\r\n constructor(\r\n material: Material,\r\n private readonly _atmosphere: Atmosphere,\r\n private readonly _isAerialPerspectiveEnabled = false\r\n ) {\r\n super(\r\n material,\r\n PluginName,\r\n PluginPriority,\r\n {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n USE_CUSTOM_REFLECTION: _atmosphere.diffuseSkyIrradianceLut !== null,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n CUSTOM_FRAGMENT_BEFORE_FOG: _isAerialPerspectiveEnabled,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n USE_AERIAL_PERSPECTIVE_LUT: _isAerialPerspectiveEnabled && _atmosphere.isAerialPerspectiveLutEnabled,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPLY_AERIAL_PERSPECTIVE_INTENSITY: _isAerialPerspectiveEnabled && _atmosphere.aerialPerspectiveIntensity !== 1.0,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS: _isAerialPerspectiveEnabled && _atmosphere.aerialPerspectiveRadianceBias !== 0.0,\r\n },\r\n false, // addPluginToList -- false because we need to control when this is added to the list\r\n true, // enable\r\n true // resolveIncludes\r\n );\r\n\r\n this.doNotSerialize = true;\r\n\r\n // This calls `getCode` so we need to do this after having initialized the class fields.\r\n this._pluginManager._addPlugin(this);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getUniformBuffersNames(_ubos: string[]): void {\r\n const uniformBuffer = this._atmosphere.uniformBuffer;\r\n if (uniformBuffer.useUbo) {\r\n _ubos.push(uniformBuffer.name);\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getUniforms() {\r\n return MakeUniforms(this._atmosphere);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override isReadyForSubMesh(): boolean {\r\n let isReady = true;\r\n const atmosphere = this._atmosphere;\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n isReady = isReady && !!aerialPerspectiveLutRenderTarget?.isReady();\r\n }\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n isReady = isReady && !!transmittanceLutRenderTarget?.isReady();\r\n return isReady;\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getActiveTextures(_activeTextures: BaseTexture[]): void {\r\n const atmosphere = this._atmosphere;\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n if (aerialPerspectiveLutRenderTarget) {\r\n _activeTextures.push(aerialPerspectiveLutRenderTarget);\r\n }\r\n }\r\n\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n if (transmittanceLutRenderTarget) {\r\n _activeTextures.push(transmittanceLutRenderTarget);\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override bindForSubMesh(uniformBuffer: UniformBuffer): void {\r\n const atmosphere = this._atmosphere;\r\n const scene = atmosphere.scene;\r\n const engine = scene.getEngine();\r\n\r\n // Bind the atmosphere's uniform buffer to the effect.\r\n const effect = uniformBuffer.currentEffect;\r\n if (effect) {\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n }\r\n\r\n // Need the offset to apply which will take a world space position and convert it to a global space position in the atmosphere.\r\n // If floating origin mode is enabled, that offset is the floating origin offset.\r\n // If not, it's an offset up the Y-axis by the planet radius.\r\n uniformBuffer.updateVector3(\r\n OriginOffsetUniformName,\r\n scene.floatingOriginMode\r\n ? Vector3ScaleToRef(scene.floatingOriginOffset, 0.001, OriginOffsetKm) // Convert to kilometers\r\n : Vector3FromFloatsToRef(0, atmosphere.physicalProperties.planetRadius, 0, OriginOffsetKm) // planetRadius is already in kilometers\r\n );\r\n\r\n const width = engine.getRenderWidth();\r\n const height = engine.getRenderHeight();\r\n uniformBuffer.updateFloat2(InverseViewportSizeUniformName, 1.0 / width, 1.0 / height);\r\n\r\n if (this._isAerialPerspectiveEnabled && atmosphere.isAerialPerspectiveLutEnabled) {\r\n const aerialPerspectiveLutRenderTarget = atmosphere.aerialPerspectiveLutRenderTarget;\r\n uniformBuffer.setTexture(\"aerialPerspectiveLut\", aerialPerspectiveLutRenderTarget);\r\n }\r\n const transmittanceLutRenderTarget = atmosphere.transmittanceLut?.renderTarget ?? null;\r\n uniformBuffer.setTexture(\"transmittanceLut\", transmittanceLutRenderTarget);\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override prepareDefines(defines: AtmospherePBRMaterialDefines): void {\r\n const lastUseAerialPerspectiveLut = defines.USE_AERIAL_PERSPECTIVE_LUT;\r\n const lastApplyAerialPerspectiveIntensity = defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY;\r\n const lastApplyAerialPerspectiveRadianceBias = defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS;\r\n defines.USE_AERIAL_PERSPECTIVE_LUT = this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled;\r\n defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY = this._isAerialPerspectiveEnabled && this._atmosphere.aerialPerspectiveIntensity !== 1.0;\r\n defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS = this._isAerialPerspectiveEnabled && this._atmosphere.aerialPerspectiveRadianceBias !== 0.0;\r\n if (\r\n lastUseAerialPerspectiveLut !== defines.USE_AERIAL_PERSPECTIVE_LUT ||\r\n lastApplyAerialPerspectiveIntensity !== defines.APPLY_AERIAL_PERSPECTIVE_INTENSITY ||\r\n lastApplyAerialPerspectiveRadianceBias !== defines.APPLY_AERIAL_PERSPECTIVE_RADIANCE_BIAS\r\n ) {\r\n defines.markAllAsDirty();\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getSamplers(samplers: string[]): void {\r\n samplers.push(\"transmittanceLut\");\r\n if (this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled) {\r\n samplers.push(\"aerialPerspectiveLut\");\r\n }\r\n }\r\n\r\n /**\r\n * @override\r\n */\r\n public override getCustomCode(shaderType: string): Nullable<Record<string, string>> {\r\n // Assumed inputs are light0, vPositionW, normalW.\r\n // Only works for directional lights.\r\n if (shaderType !== \"fragment\") {\r\n return null;\r\n }\r\n\r\n const useUbo = this._atmosphere.scene.getEngine().supportsUniformBuffers;\r\n const directionToLightSnippet = useUbo ? \"-light0.vLightData.xyz\" : \"-vLightData0.xyz\";\r\n\r\n const useAtmosphereUbo = this._atmosphere.uniformBuffer.useUbo;\r\n const atmosphereImportSnippet = useAtmosphereUbo ? \"#include<atmosphereUboDeclaration>\" : \"#include<atmosphereFragmentDeclaration>\";\r\n\r\n return {\r\n CUSTOM_FRAGMENT_DEFINITIONS:\r\n this._isAerialPerspectiveEnabled && this._atmosphere.isAerialPerspectiveLutEnabled\r\n ? `uniform sampler2D transmittanceLut;\\r\\nprecision highp sampler2DArray;\\r\\nuniform sampler2DArray aerialPerspectiveLut;\\r\\n${atmosphereImportSnippet}\\r\\n#include<atmosphereFunctions>`\r\n : `uniform sampler2D transmittanceLut;\\r\\n${atmosphereImportSnippet}\\r\\n#include<atmosphereFunctions>`,\r\n CUSTOM_LIGHT0_COLOR: `\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + ${OriginOffsetUniformName};\r\n float positionRadius = length(positionGlobal);\r\n vec3 geocentricNormal = positionGlobal / positionRadius;\r\n vec3 directionToLight = ${directionToLightSnippet};\r\n float cosAngleLightToZenith = dot(directionToLight, geocentricNormal);\r\n diffuse0 = lightIntensity * sampleTransmittanceLut(transmittanceLut, positionRadius, cosAngleLightToZenith);\r\n }\r\n`,\r\n CUSTOM_REFLECTION: `\r\n {\r\n vec3 positionGlobal = 0.001 * vPositionW + ${OriginOffsetUniformName};\r\n float positionRadius = length(positionGlobal);\r\n vec3 geocentricNormal = positionGlobal / positionRadius;\r\n\r\n vec3 directionToLight = ${directionToLightSnippet};\r\n float cosAngleLightToZenith = dot(directionToLight, geocentricNormal);\r\n\r\n vec2 uv = vec2(0.5 + 0.5 * cosAngleLightToZenith, (positionRadius - planetRadius) / atmosphereThickness);\r\n float irradianceScaleT = 0.5 * dot(normalW, geocentricNormal) + 0.5;\r\n float irradianceScale = ((-0.6652 * irradianceScaleT) + 1.5927) * irradianceScaleT + 0.1023;\r\n vec3 environmentIrradiance = lightIntensity * sampleReflection(irradianceSampler, uv).rgb;\r\n\r\n // Add a contribution here to estimate indirect lighting.\r\n const float r = 0.2;\r\n float indirect = getLuminance(environmentIrradiance) / max(0.00001, 1. - r);\r\n environmentIrradiance *= irradianceScale;\r\n environmentIrradiance += indirect;\r\n\r\n environmentIrradiance += additionalDiffuseSkyIrradiance;\r\n\r\n const float diffuseBrdf = 1. / PI;\r\n environmentIrradiance *= diffuseBrdf * diffuseSkyIrradianceIntensity;\r\n\r\n reflectionOut.environmentIrradiance = environmentIrradiance;\r\n reflectionOut.environmentRadiance.rgb = reflectionOut.environmentIrradiance;\r\n }\r\n`,\r\n // TODO: Support full ray marching if USE_AERIAL_PERSPECTIVE_LUT is disabled.\r\n CUSTOM_FRAGMENT_BEFORE_FOG: `\r\n #if USE_AERIAL_PERSPECTIVE_LUT\r\n {\r\n float distanceFromCameraKm = 0.001 * distance(vEyePosition.xyz, vPositionW);\r\n vec4 aerialPerspective = vec4(0.);\r\n if (sampleAerialPerspectiveLut(\r\n gl_FragCoord.xy * ${InverseViewportSizeUniformName},\r\n true,\r\n distanceFromCameraKm,\r\n NumAerialPerspectiveLutLayers,\r\n AerialPerspectiveLutKMPerSlice,\r\n AerialPerspectiveLutRangeKM,\r\n aerialPerspective)) {\r\n finalColor = aerialPerspective + (1. - aerialPerspective.a) * finalColor;\r\n }\r\n }\r\n #endif\r\n`,\r\n };\r\n }\r\n}\r\n"]}
@@ -55,10 +55,15 @@ export declare class AtmospherePerCameraVariables {
55
55
  get clampedCameraHeight(): number;
56
56
  /**
57
57
  * The camera position in global space kilometers.
58
+ *
59
+ * The behavior of this value depends on whether floating origin mode is enabled:
60
+ * - If floating origin mode is enabled, this is simply the camera's global position scaled to kilometers. The atmosphere's origin height is used to offset the camera position along its geocentric normal.
61
+ * - If floating origin mode is disabled, the camera's y position is offset by the planet radius plus any origin height.
58
62
  */
59
63
  get cameraPositionGlobal(): IVector3Like;
60
64
  /**
61
65
  * The camera position, clamped to the planet radius offset, in global space kilometers.
66
+ * See {@link cameraPositionGlobal} for details on how the value is computed.
62
67
  */
63
68
  get clampedCameraPositionGlobal(): IVector3Like;
64
69
  /**
@@ -71,6 +76,7 @@ export declare class AtmospherePerCameraVariables {
71
76
  get sinCameraAtmosphereHorizonAngleFromNadir(): number;
72
77
  /**
73
78
  * The geocentric normal of the camera in global space i.e., the normalization of {@link cameraPositionGlobal}.
79
+ * Note the behavior of this value depends on whether floating origin mode is enabled. See {@link cameraPositionGlobal} for details.
74
80
  */
75
81
  get cameraGeocentricNormal(): IVector3Like;
76
82
  /**
@@ -75,12 +75,17 @@ export class AtmospherePerCameraVariables {
75
75
  }
76
76
  /**
77
77
  * The camera position in global space kilometers.
78
+ *
79
+ * The behavior of this value depends on whether floating origin mode is enabled:
80
+ * - If floating origin mode is enabled, this is simply the camera's global position scaled to kilometers. The atmosphere's origin height is used to offset the camera position along its geocentric normal.
81
+ * - If floating origin mode is disabled, the camera's y position is offset by the planet radius plus any origin height.
78
82
  */
79
83
  get cameraPositionGlobal() {
80
84
  return this._cameraPositionGlobal;
81
85
  }
82
86
  /**
83
87
  * The camera position, clamped to the planet radius offset, in global space kilometers.
88
+ * See {@link cameraPositionGlobal} for details on how the value is computed.
84
89
  */
85
90
  get clampedCameraPositionGlobal() {
86
91
  return this._clampedCameraPositionGlobal;
@@ -99,6 +104,7 @@ export class AtmospherePerCameraVariables {
99
104
  }
100
105
  /**
101
106
  * The geocentric normal of the camera in global space i.e., the normalization of {@link cameraPositionGlobal}.
107
+ * Note the behavior of this value depends on whether floating origin mode is enabled. See {@link cameraPositionGlobal} for details.
102
108
  */
103
109
  get cameraGeocentricNormal() {
104
110
  return this._cameraGeocentricNormal;
@@ -139,34 +145,47 @@ export class AtmospherePerCameraVariables {
139
145
  update(camera, planetRadius, planetRadiusWithOffset, atmosphereRadius, directionToLight, originHeight) {
140
146
  this._cameraNearPlane = camera.minZ;
141
147
  this._cameraForward.copyFrom(camera.getForwardRayToRef(TempRay, 1).direction);
142
- const engine = camera.getScene().getEngine();
148
+ const scene = camera.getScene();
149
+ const engine = scene.getEngine();
143
150
  this._viewport.copyFromFloats(0.0, 0.0, engine.getRenderWidth(), engine.getRenderHeight());
144
151
  // Compute inverse view projection matrix, but remove the translational component to increase precision.
145
152
  const viewMatrix = camera.getViewMatrix();
146
153
  const projectionMatrix = camera.getProjectionMatrix();
147
- if (!this._lastViewMatrix.equals(viewMatrix) || !this._lastProjectionMatrix.equals(projectionMatrix)) {
148
- this._lastViewMatrix.copyFrom(viewMatrix);
149
- this._lastViewMatrix.setTranslation(Vector3.ZeroReadOnly);
150
- this._lastViewMatrix.invertToRef(this._inverseViewMatrixWithoutTranslation);
151
- this._lastProjectionMatrix.copyFrom(projectionMatrix);
152
- this._lastProjectionMatrix.invertToRef(this._inverseProjectionMatrix);
154
+ const lastViewMatrix = this._lastViewMatrix;
155
+ const lastProjectionMatrix = this._lastProjectionMatrix;
156
+ if (!lastViewMatrix.equals(viewMatrix) || !lastProjectionMatrix.equals(projectionMatrix)) {
157
+ lastViewMatrix.copyFrom(viewMatrix);
158
+ lastViewMatrix.setTranslation(Vector3.ZeroReadOnly);
159
+ lastViewMatrix.invertToRef(this._inverseViewMatrixWithoutTranslation);
160
+ lastProjectionMatrix.copyFrom(projectionMatrix);
161
+ lastProjectionMatrix.invertToRef(this._inverseProjectionMatrix);
153
162
  this._inverseProjectionMatrix.multiplyToRef(this._inverseViewMatrixWithoutTranslation, this._inverseViewProjectionMatrixWithoutTranslation);
154
163
  }
155
164
  // Compute the global space position of the camera in kilometers.
156
- this._cameraPosition.copyFrom(camera.globalPosition);
157
- this._cameraPosition.scaleToRef(1.0 / 1000.0, this._cameraPositionGlobal);
158
- this._cameraPositionGlobal.y += planetRadius + originHeight;
159
- this._cameraHeight = this._cameraPositionGlobal.y - planetRadius;
165
+ const cameraPositionGlobal = this._cameraPosition.copyFrom(camera.globalPosition).scaleToRef(0.001, this._cameraPositionGlobal); // scale to kilometers
166
+ // Apply the origin height to the camera position, and in doing so, compute the camera geocentric normal.
167
+ if (scene.floatingOriginMode) {
168
+ // When in floating origin mode, assume world space origin is at the planet center.
169
+ // Therefore "up" is away from the planet center (0, 0, 0).
170
+ cameraPositionGlobal.normalizeToRef(this._cameraGeocentricNormal);
171
+ this._cameraGeocentricNormal.scaleAndAddToRef(originHeight, cameraPositionGlobal);
172
+ }
173
+ else {
174
+ // If not in floating origin mode, offset the camera position by the origin height.
175
+ // Assume the origin is directly above the planet surface along the up axis (y axis).
176
+ cameraPositionGlobal.y += planetRadius + originHeight;
177
+ cameraPositionGlobal.normalizeToRef(this._cameraGeocentricNormal);
178
+ }
179
+ this._cameraRadius = cameraPositionGlobal.length(); // distance from planet center
180
+ this._cameraHeight = this._cameraRadius - planetRadius; // height above planet surface
160
181
  // Clamp the camera parameters.
161
- this._cameraRadius = this._cameraPositionGlobal.length();
162
182
  this._clampedCameraRadius = this._cameraRadius;
163
- this._cameraPositionGlobal.normalizeToRef(this._cameraGeocentricNormal);
164
183
  if (this._clampedCameraRadius < planetRadiusWithOffset) {
165
184
  this._clampedCameraRadius = planetRadiusWithOffset;
166
185
  this._cameraGeocentricNormal.scaleToRef(planetRadiusWithOffset, this._clampedCameraPositionGlobal);
167
186
  }
168
187
  else {
169
- this._clampedCameraPositionGlobal.copyFrom(this._cameraPositionGlobal);
188
+ this._clampedCameraPositionGlobal.copyFrom(cameraPositionGlobal);
170
189
  }
171
190
  this._cosCameraHorizonAngleFromZenith = ComputeCosHorizonAngleFromZenith(planetRadius, this._clampedCameraRadius);
172
191
  this._sinCameraAtmosphereHorizonAngleFromNadir = Math.min(1.0, atmosphereRadius / this._clampedCameraRadius);
@@ -1 +1 @@
1
- {"version":3,"file":"atmospherePerCameraVariables.js","sourceRoot":"","sources":["../../../../dev/addons/src/atmosphere/atmospherePerCameraVariables.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Camera } from \"core/Cameras/camera\";\r\nimport type { IMatrixLike, IVector3Like, IVector4Like } from \"core/Maths/math.like\";\r\nimport { Matrix, Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Ray } from \"core/Culling/ray.core\";\r\nimport { Vector3Dot } from \"core/Maths/math.vector.functions\";\r\n\r\nconst TempRay = new Ray(Vector3.Zero(), Vector3.Zero());\r\n\r\n/**\r\n * Variables that are used to render the atmosphere and are computed per-camera.\r\n */\r\nexport class AtmospherePerCameraVariables {\r\n private _inverseViewProjectionMatrixWithoutTranslation = Matrix.Identity();\r\n private _directionToLightRelativeToCameraGeocentricNormal = Vector3.Up();\r\n private _cosAngleLightToZenith = 0;\r\n private _cameraRadius = 0;\r\n private _clampedCameraRadius = 0;\r\n private _cameraHeight = 0;\r\n private _clampedCameraHeight = 0;\r\n private _cameraPositionGlobal = new Vector3();\r\n private _clampedCameraPositionGlobal = new Vector3();\r\n private _cosCameraHorizonAngleFromZenith = 0;\r\n private _sinCameraAtmosphereHorizonAngleFromNadir = 0;\r\n private _cameraGeocentricNormal = Vector3.Up();\r\n private _cameraForward = Vector3.Down();\r\n private _cameraNearPlane = 0;\r\n private _cameraPosition = new Vector3();\r\n private _viewport = new Vector4();\r\n private _lastViewMatrix = Matrix.Identity();\r\n private _lastProjectionMatrix = Matrix.Identity();\r\n private _inverseViewMatrixWithoutTranslation = Matrix.Identity();\r\n private _inverseProjectionMatrix = Matrix.Identity();\r\n\r\n /**\r\n * The inverse view projection matrix is used to unproject rays.\r\n * To avoid precision issues, the translation part of the matrix has been removed.\r\n */\r\n public get inverseViewProjectionMatrixWithoutTranslation(): IMatrixLike {\r\n return this._inverseViewProjectionMatrixWithoutTranslation;\r\n }\r\n\r\n /**\r\n * The direction to the light relative to the geocentric normal under the camera.\r\n */\r\n public get directionToLightRelativeToCameraGeocentricNormal(): IVector3Like {\r\n return this._directionToLightRelativeToCameraGeocentricNormal;\r\n }\r\n\r\n /**\r\n * The cosine of the angle between the light direction and zenith.\r\n */\r\n public get cosAngleLightToZenith(): number {\r\n return this._cosAngleLightToZenith;\r\n }\r\n\r\n /**\r\n * The distance from the camera to the planet origin in kilometers.\r\n */\r\n public get cameraRadius(): number {\r\n return this._cameraRadius;\r\n }\r\n\r\n /**\r\n * The distance from the camera to the planet origin, clamped to the planet radius offset, in kilometers.\r\n */\r\n public get clampedCameraRadius(): number {\r\n return this._clampedCameraRadius;\r\n }\r\n\r\n /**\r\n * The height of the camera above the planet surface in kilometers.\r\n */\r\n public get cameraHeight(): number {\r\n return this._cameraHeight;\r\n }\r\n\r\n /**\r\n * The height of the camera above the planet surface, clamped to the planet radius offset, in kilometers.\r\n */\r\n public get clampedCameraHeight(): number {\r\n return this._clampedCameraHeight;\r\n }\r\n\r\n /**\r\n * The camera position in global space kilometers.\r\n */\r\n public get cameraPositionGlobal(): IVector3Like {\r\n return this._cameraPositionGlobal;\r\n }\r\n\r\n /**\r\n * The camera position, clamped to the planet radius offset, in global space kilometers.\r\n */\r\n public get clampedCameraPositionGlobal(): IVector3Like {\r\n return this._clampedCameraPositionGlobal;\r\n }\r\n\r\n /**\r\n * The cosine of the angle from the zenith to the horizon of the planet, measured from the camera position.\r\n */\r\n public get cosCameraHorizonAngleFromZenith(): number {\r\n return this._cosCameraHorizonAngleFromZenith;\r\n }\r\n\r\n /**\r\n * The sine of the angle from the nadir to the horizon of the atmosphere, measured from the camera position.\r\n */\r\n public get sinCameraAtmosphereHorizonAngleFromNadir(): number {\r\n return this._sinCameraAtmosphereHorizonAngleFromNadir;\r\n }\r\n\r\n /**\r\n * The geocentric normal of the camera in global space i.e., the normalization of {@link cameraPositionGlobal}.\r\n */\r\n public get cameraGeocentricNormal(): IVector3Like {\r\n return this._cameraGeocentricNormal;\r\n }\r\n\r\n /**\r\n * The camera's forward direction in world space.\r\n */\r\n public get cameraForward(): IVector3Like {\r\n return this._cameraForward;\r\n }\r\n\r\n /**\r\n * The distance to the near plane of the camera.\r\n */\r\n public get cameraNearPlane(): number {\r\n return this._cameraNearPlane;\r\n }\r\n\r\n /**\r\n * The camera's position in world space.\r\n */\r\n public get cameraPosition(): IVector3Like {\r\n return this._cameraPosition;\r\n }\r\n\r\n /**\r\n * The viewport for the camera.\r\n */\r\n public get viewport(): IVector4Like {\r\n return this._viewport;\r\n }\r\n\r\n /**\r\n * Updates the variables.\r\n * @param camera - The camera to update the variables for.\r\n * @param planetRadius - The radius of the planet in kilometers.\r\n * @param planetRadiusWithOffset - The radius of the planet with the offset in kilometers.\r\n * @param atmosphereRadius - The radius of the atmosphere in kilometers.\r\n * @param directionToLight - The direction to the light in world space.\r\n * @param originHeight - The height of the origin (distance from planet's surface) in kilometers.\r\n */\r\n public update(camera: Camera, planetRadius: number, planetRadiusWithOffset: number, atmosphereRadius: number, directionToLight: IVector3Like, originHeight: number): void {\r\n this._cameraNearPlane = camera.minZ;\r\n this._cameraForward.copyFrom(camera.getForwardRayToRef(TempRay, 1).direction);\r\n\r\n const engine = camera.getScene().getEngine();\r\n this._viewport.copyFromFloats(0.0, 0.0, engine.getRenderWidth(), engine.getRenderHeight());\r\n\r\n // Compute inverse view projection matrix, but remove the translational component to increase precision.\r\n const viewMatrix = camera.getViewMatrix();\r\n const projectionMatrix = camera.getProjectionMatrix();\r\n if (!this._lastViewMatrix.equals(viewMatrix) || !this._lastProjectionMatrix.equals(projectionMatrix)) {\r\n this._lastViewMatrix.copyFrom(viewMatrix);\r\n this._lastViewMatrix.setTranslation(Vector3.ZeroReadOnly);\r\n this._lastViewMatrix.invertToRef(this._inverseViewMatrixWithoutTranslation);\r\n\r\n this._lastProjectionMatrix.copyFrom(projectionMatrix);\r\n this._lastProjectionMatrix.invertToRef(this._inverseProjectionMatrix);\r\n this._inverseProjectionMatrix.multiplyToRef(this._inverseViewMatrixWithoutTranslation, this._inverseViewProjectionMatrixWithoutTranslation);\r\n }\r\n\r\n // Compute the global space position of the camera in kilometers.\r\n this._cameraPosition.copyFrom(camera.globalPosition);\r\n this._cameraPosition.scaleToRef(1.0 / 1000.0, this._cameraPositionGlobal);\r\n this._cameraPositionGlobal.y += planetRadius + originHeight;\r\n this._cameraHeight = this._cameraPositionGlobal.y - planetRadius;\r\n\r\n // Clamp the camera parameters.\r\n this._cameraRadius = this._cameraPositionGlobal.length();\r\n this._clampedCameraRadius = this._cameraRadius;\r\n this._cameraPositionGlobal.normalizeToRef(this._cameraGeocentricNormal);\r\n if (this._clampedCameraRadius < planetRadiusWithOffset) {\r\n this._clampedCameraRadius = planetRadiusWithOffset;\r\n this._cameraGeocentricNormal.scaleToRef(planetRadiusWithOffset, this._clampedCameraPositionGlobal);\r\n } else {\r\n this._clampedCameraPositionGlobal.copyFrom(this._cameraPositionGlobal);\r\n }\r\n\r\n this._cosCameraHorizonAngleFromZenith = ComputeCosHorizonAngleFromZenith(planetRadius, this._clampedCameraRadius);\r\n this._sinCameraAtmosphereHorizonAngleFromNadir = Math.min(1.0, atmosphereRadius / this._clampedCameraRadius);\r\n this._clampedCameraHeight = this._clampedCameraRadius - planetRadius;\r\n\r\n // Compute the direction to the light relative to the camera's geocentric normal.\r\n {\r\n this._cosAngleLightToZenith = Vector3Dot(directionToLight, this._cameraGeocentricNormal);\r\n const lightZenithSinAngle = Math.sqrt(Math.max(0.0, 1.0 - this._cosAngleLightToZenith * this._cosAngleLightToZenith));\r\n this._directionToLightRelativeToCameraGeocentricNormal.copyFromFloats(lightZenithSinAngle, this._cosAngleLightToZenith, 0.0);\r\n this._directionToLightRelativeToCameraGeocentricNormal.normalize();\r\n }\r\n }\r\n}\r\n\r\nconst ComputeCosHorizonAngleFromZenith = (planetRadius: number, radius: number): number => {\r\n const sinHorizonAngleFromNadir = Math.min(1, planetRadius / radius);\r\n const cosHorizonAngleFromNadir = Math.sqrt(1 - sinHorizonAngleFromNadir * sinHorizonAngleFromNadir);\r\n const cosHorizonAngleFromZenith = -cosHorizonAngleFromNadir;\r\n return cosHorizonAngleFromZenith;\r\n};\r\n"]}
1
+ {"version":3,"file":"atmospherePerCameraVariables.js","sourceRoot":"","sources":["../../../../dev/addons/src/atmosphere/atmospherePerCameraVariables.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Camera } from \"core/Cameras/camera\";\r\nimport type { IMatrixLike, IVector3Like, IVector4Like } from \"core/Maths/math.like\";\r\nimport { Matrix, Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Ray } from \"core/Culling/ray.core\";\r\nimport { Vector3Dot } from \"core/Maths/math.vector.functions\";\r\n\r\nconst TempRay = new Ray(Vector3.Zero(), Vector3.Zero());\r\n\r\n/**\r\n * Variables that are used to render the atmosphere and are computed per-camera.\r\n */\r\nexport class AtmospherePerCameraVariables {\r\n private _inverseViewProjectionMatrixWithoutTranslation = Matrix.Identity();\r\n private _directionToLightRelativeToCameraGeocentricNormal = Vector3.Up();\r\n private _cosAngleLightToZenith = 0;\r\n private _cameraRadius = 0;\r\n private _clampedCameraRadius = 0;\r\n private _cameraHeight = 0;\r\n private _clampedCameraHeight = 0;\r\n private _cameraPositionGlobal = new Vector3();\r\n private _clampedCameraPositionGlobal = new Vector3();\r\n private _cosCameraHorizonAngleFromZenith = 0;\r\n private _sinCameraAtmosphereHorizonAngleFromNadir = 0;\r\n private _cameraGeocentricNormal = Vector3.Up();\r\n private _cameraForward = Vector3.Down();\r\n private _cameraNearPlane = 0;\r\n private _cameraPosition = new Vector3();\r\n private _viewport = new Vector4();\r\n private _lastViewMatrix = Matrix.Identity();\r\n private _lastProjectionMatrix = Matrix.Identity();\r\n private _inverseViewMatrixWithoutTranslation = Matrix.Identity();\r\n private _inverseProjectionMatrix = Matrix.Identity();\r\n\r\n /**\r\n * The inverse view projection matrix is used to unproject rays.\r\n * To avoid precision issues, the translation part of the matrix has been removed.\r\n */\r\n public get inverseViewProjectionMatrixWithoutTranslation(): IMatrixLike {\r\n return this._inverseViewProjectionMatrixWithoutTranslation;\r\n }\r\n\r\n /**\r\n * The direction to the light relative to the geocentric normal under the camera.\r\n */\r\n public get directionToLightRelativeToCameraGeocentricNormal(): IVector3Like {\r\n return this._directionToLightRelativeToCameraGeocentricNormal;\r\n }\r\n\r\n /**\r\n * The cosine of the angle between the light direction and zenith.\r\n */\r\n public get cosAngleLightToZenith(): number {\r\n return this._cosAngleLightToZenith;\r\n }\r\n\r\n /**\r\n * The distance from the camera to the planet origin in kilometers.\r\n */\r\n public get cameraRadius(): number {\r\n return this._cameraRadius;\r\n }\r\n\r\n /**\r\n * The distance from the camera to the planet origin, clamped to the planet radius offset, in kilometers.\r\n */\r\n public get clampedCameraRadius(): number {\r\n return this._clampedCameraRadius;\r\n }\r\n\r\n /**\r\n * The height of the camera above the planet surface in kilometers.\r\n */\r\n public get cameraHeight(): number {\r\n return this._cameraHeight;\r\n }\r\n\r\n /**\r\n * The height of the camera above the planet surface, clamped to the planet radius offset, in kilometers.\r\n */\r\n public get clampedCameraHeight(): number {\r\n return this._clampedCameraHeight;\r\n }\r\n\r\n /**\r\n * The camera position in global space kilometers.\r\n *\r\n * The behavior of this value depends on whether floating origin mode is enabled:\r\n * - If floating origin mode is enabled, this is simply the camera's global position scaled to kilometers. The atmosphere's origin height is used to offset the camera position along its geocentric normal.\r\n * - If floating origin mode is disabled, the camera's y position is offset by the planet radius plus any origin height.\r\n */\r\n public get cameraPositionGlobal(): IVector3Like {\r\n return this._cameraPositionGlobal;\r\n }\r\n\r\n /**\r\n * The camera position, clamped to the planet radius offset, in global space kilometers.\r\n * See {@link cameraPositionGlobal} for details on how the value is computed.\r\n */\r\n public get clampedCameraPositionGlobal(): IVector3Like {\r\n return this._clampedCameraPositionGlobal;\r\n }\r\n\r\n /**\r\n * The cosine of the angle from the zenith to the horizon of the planet, measured from the camera position.\r\n */\r\n public get cosCameraHorizonAngleFromZenith(): number {\r\n return this._cosCameraHorizonAngleFromZenith;\r\n }\r\n\r\n /**\r\n * The sine of the angle from the nadir to the horizon of the atmosphere, measured from the camera position.\r\n */\r\n public get sinCameraAtmosphereHorizonAngleFromNadir(): number {\r\n return this._sinCameraAtmosphereHorizonAngleFromNadir;\r\n }\r\n\r\n /**\r\n * The geocentric normal of the camera in global space i.e., the normalization of {@link cameraPositionGlobal}.\r\n * Note the behavior of this value depends on whether floating origin mode is enabled. See {@link cameraPositionGlobal} for details.\r\n */\r\n public get cameraGeocentricNormal(): IVector3Like {\r\n return this._cameraGeocentricNormal;\r\n }\r\n\r\n /**\r\n * The camera's forward direction in world space.\r\n */\r\n public get cameraForward(): IVector3Like {\r\n return this._cameraForward;\r\n }\r\n\r\n /**\r\n * The distance to the near plane of the camera.\r\n */\r\n public get cameraNearPlane(): number {\r\n return this._cameraNearPlane;\r\n }\r\n\r\n /**\r\n * The camera's position in world space.\r\n */\r\n public get cameraPosition(): IVector3Like {\r\n return this._cameraPosition;\r\n }\r\n\r\n /**\r\n * The viewport for the camera.\r\n */\r\n public get viewport(): IVector4Like {\r\n return this._viewport;\r\n }\r\n\r\n /**\r\n * Updates the variables.\r\n * @param camera - The camera to update the variables for.\r\n * @param planetRadius - The radius of the planet in kilometers.\r\n * @param planetRadiusWithOffset - The radius of the planet with the offset in kilometers.\r\n * @param atmosphereRadius - The radius of the atmosphere in kilometers.\r\n * @param directionToLight - The direction to the light in world space.\r\n * @param originHeight - The height of the origin (distance from planet's surface) in kilometers.\r\n */\r\n public update(camera: Camera, planetRadius: number, planetRadiusWithOffset: number, atmosphereRadius: number, directionToLight: IVector3Like, originHeight: number): void {\r\n this._cameraNearPlane = camera.minZ;\r\n this._cameraForward.copyFrom(camera.getForwardRayToRef(TempRay, 1).direction);\r\n\r\n const scene = camera.getScene();\r\n const engine = scene.getEngine();\r\n this._viewport.copyFromFloats(0.0, 0.0, engine.getRenderWidth(), engine.getRenderHeight());\r\n\r\n // Compute inverse view projection matrix, but remove the translational component to increase precision.\r\n const viewMatrix = camera.getViewMatrix();\r\n const projectionMatrix = camera.getProjectionMatrix();\r\n const lastViewMatrix = this._lastViewMatrix;\r\n const lastProjectionMatrix = this._lastProjectionMatrix;\r\n if (!lastViewMatrix.equals(viewMatrix) || !lastProjectionMatrix.equals(projectionMatrix)) {\r\n lastViewMatrix.copyFrom(viewMatrix);\r\n lastViewMatrix.setTranslation(Vector3.ZeroReadOnly);\r\n lastViewMatrix.invertToRef(this._inverseViewMatrixWithoutTranslation);\r\n\r\n lastProjectionMatrix.copyFrom(projectionMatrix);\r\n lastProjectionMatrix.invertToRef(this._inverseProjectionMatrix);\r\n this._inverseProjectionMatrix.multiplyToRef(this._inverseViewMatrixWithoutTranslation, this._inverseViewProjectionMatrixWithoutTranslation);\r\n }\r\n\r\n // Compute the global space position of the camera in kilometers.\r\n const cameraPositionGlobal = this._cameraPosition.copyFrom(camera.globalPosition).scaleToRef(0.001, this._cameraPositionGlobal); // scale to kilometers\r\n\r\n // Apply the origin height to the camera position, and in doing so, compute the camera geocentric normal.\r\n if (scene.floatingOriginMode) {\r\n // When in floating origin mode, assume world space origin is at the planet center.\r\n // Therefore \"up\" is away from the planet center (0, 0, 0).\r\n cameraPositionGlobal.normalizeToRef(this._cameraGeocentricNormal);\r\n this._cameraGeocentricNormal.scaleAndAddToRef(originHeight, cameraPositionGlobal);\r\n } else {\r\n // If not in floating origin mode, offset the camera position by the origin height.\r\n // Assume the origin is directly above the planet surface along the up axis (y axis).\r\n cameraPositionGlobal.y += planetRadius + originHeight;\r\n cameraPositionGlobal.normalizeToRef(this._cameraGeocentricNormal);\r\n }\r\n\r\n this._cameraRadius = cameraPositionGlobal.length(); // distance from planet center\r\n this._cameraHeight = this._cameraRadius - planetRadius; // height above planet surface\r\n\r\n // Clamp the camera parameters.\r\n this._clampedCameraRadius = this._cameraRadius;\r\n if (this._clampedCameraRadius < planetRadiusWithOffset) {\r\n this._clampedCameraRadius = planetRadiusWithOffset;\r\n this._cameraGeocentricNormal.scaleToRef(planetRadiusWithOffset, this._clampedCameraPositionGlobal);\r\n } else {\r\n this._clampedCameraPositionGlobal.copyFrom(cameraPositionGlobal);\r\n }\r\n\r\n this._cosCameraHorizonAngleFromZenith = ComputeCosHorizonAngleFromZenith(planetRadius, this._clampedCameraRadius);\r\n this._sinCameraAtmosphereHorizonAngleFromNadir = Math.min(1.0, atmosphereRadius / this._clampedCameraRadius);\r\n this._clampedCameraHeight = this._clampedCameraRadius - planetRadius;\r\n\r\n // Compute the direction to the light relative to the camera's geocentric normal.\r\n {\r\n this._cosAngleLightToZenith = Vector3Dot(directionToLight, this._cameraGeocentricNormal);\r\n const lightZenithSinAngle = Math.sqrt(Math.max(0.0, 1.0 - this._cosAngleLightToZenith * this._cosAngleLightToZenith));\r\n this._directionToLightRelativeToCameraGeocentricNormal.copyFromFloats(lightZenithSinAngle, this._cosAngleLightToZenith, 0.0);\r\n this._directionToLightRelativeToCameraGeocentricNormal.normalize();\r\n }\r\n }\r\n}\r\n\r\nconst ComputeCosHorizonAngleFromZenith = (planetRadius: number, radius: number): number => {\r\n const sinHorizonAngleFromNadir = Math.min(1, planetRadius / radius);\r\n const cosHorizonAngleFromNadir = Math.sqrt(1 - sinHorizonAngleFromNadir * sinHorizonAngleFromNadir);\r\n const cosHorizonAngleFromZenith = -cosHorizonAngleFromNadir;\r\n return cosHorizonAngleFromZenith;\r\n};\r\n"]}
@@ -6,6 +6,7 @@ import { EffectRenderer, EffectWrapper } from "@babylonjs/core/Materials/effectR
6
6
  import { FromHalfFloat } from "@babylonjs/core/Misc/textureTools.js";
7
7
  import { RenderTargetTexture } from "@babylonjs/core/Materials/Textures/renderTargetTexture.js";
8
8
  import { Sample2DRgbaToRef } from "./sampling.js";
9
+ import { Vector3Dot } from "@babylonjs/core/Maths/math.vector.functions.js";
9
10
  import "./Shaders/diffuseSkyIrradiance.fragment.js";
10
11
  import "./Shaders/fullscreenTriangle.vertex.js";
11
12
  const RaySamples = 128;
@@ -132,7 +133,7 @@ export class DiffuseSkyIrradianceLut {
132
133
  result.b = additionalDiffuseSkyIrradiance.b;
133
134
  return result;
134
135
  }
135
- const cosAngleLightToZenith = directionToLight.x * cameraGeocentricNormal.x + directionToLight.y * cameraGeocentricNormal.y + directionToLight.z * cameraGeocentricNormal.z;
136
+ const cosAngleLightToZenith = Vector3Dot(directionToLight, cameraGeocentricNormal);
136
137
  ComputeLutUVToRef(properties, radius, cosAngleLightToZenith, UvTemp);
137
138
  Sample2DRgbaToRef(UvTemp.x, UvTemp.y, LutWidthPx, LutHeightPx, this._lutData, Color4Temp, FromHalfFloat);
138
139
  const intensity = atmosphere.diffuseSkyIrradianceIntensity;
@@ -1 +1 @@
1
- {"version":3,"file":"diffuseSkyIrradianceLut.js","sourceRoot":"","sources":["../../../../dev/addons/src/atmosphere/diffuseSkyIrradianceLut.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,cAAc;AAId,OAAO,EAAE,KAAK,EAAE,uDAAyC;AACzD,OAAO,EAAE,SAAS,EAAE,6CAA+B;AACnD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,oDAAsC;AAC9E,OAAO,EAAE,aAAa,EAAE,6CAA+B;AAGvD,OAAO,EAAE,mBAAmB,EAAE,kEAAoD;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,yCAAyC,CAAC;AACjD,OAAO,qCAAqC,CAAC;AAE7C,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,GAAG,GAAG,UAAU,EAAE,CAAC,EAAE,GAAG,GAAG,WAAW,EAAE,CAAC;AACpE,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,WAAW,EAAE,CAAC;AACnG,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;AAChD,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAiB,CAAC;AAEjG,MAAM,iBAAiB,GAAG,CAAC,UAAwC,EAAE,MAAc,EAAE,qBAA6B,EAAE,MAAoB,EAAQ,EAAE;IAC9I,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,qBAAqB,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;IACzF,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,aAAa,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IACrD,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,aAAa,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,uBAAuB;IAShC;;OAEG;IACH,IAAW,OAAO;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,IAAW,UAAU;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,IAAW,YAAY;QACnB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,EAAE,CAAC;QACtB,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,IAAW,UAAU;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,YAAY,UAAsB;QA3C1B,kBAAa,GAAkC,IAAI,CAAC;QACpD,mBAAc,GAA4B,IAAI,CAAC;QAC/C,oBAAe,GAA6B,IAAI,CAAC;QACjD,aAAQ,GAAG,IAAI,CAAC;QAChB,gBAAW,GAAG,KAAK,CAAC;QACpB,aAAQ,GAA6B,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAuC5D,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QAEjC,MAAM,IAAI,GAAG,2BAA2B,CAAC;QACzC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC;QACzH,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,mBAAmB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE;YACxH,eAAe,EAAE,KAAK;YACtB,IAAI,EAAE,WAAW;YACjB,YAAY,EAAE,SAAS,CAAC,6BAA6B;YACrD,mBAAmB,EAAE,KAAK;YAC1B,UAAU,EAAE,KAAK;SACpB,CAAC,CAAC,CAAC;QACJ,YAAY,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;QACzD,YAAY,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;QACzD,YAAY,CAAC,yBAAyB,GAAG,CAAC,CAAC;QAC3C,YAAY,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAErC,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC;QAE/C,IAAI,CAAC,cAAc,GAAG,IAAI,aAAa,CAAC;YACpC,MAAM;YACN,IAAI;YACJ,YAAY,EAAE,oBAAoB;YAClC,cAAc,EAAE,sBAAsB;YACtC,cAAc,EAAE,CAAC,UAAU,CAAC;YAC5B,YAAY,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC,CAAC;YACtF,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7D,OAAO,EAAE;gBACL,uBAAuB;gBACvB,uBAAuB,UAAU,GAAG;gBACpC,uDAAuD,EAAE,8FAA8F;gBACvJ,gEAAgE;gBAChE,qHAAqH;aACxH;YACD,QAAQ,EAAE,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;YACpD,cAAc,EAAE,IAAI;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE;YAC9C,wBAAwB;YACxB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAClB,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SACpC,CAAC,CAAC;QAEH,oEAAoE;QACpE,KAAK,CAAC,kBAAkB,GAAG,YAAY,CAAC;QACxC,KAAK,CAAC,kBAAkB,CAAC,iBAAiB,GAAG,YAAY,CAAC;QAC1D,KAAK,CAAC,oBAAoB,GAAG,GAAG,CAAC;QAEjC,4FAA4F;QAC5F,KAAK,CAAC,kBAAkB,CAAC,cAAc,GAAG,KAAK,CAAC;IACpD,CAAC;IAED;;;;;;;;;OASG;IACI,4BAA4B,CAC/B,gBAA8B,EAC9B,MAAc,EACd,sBAAoC,EACpC,eAAuB,EACvB,MAAS;QAET,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,MAAM,8BAA8B,GAAG,UAAU,CAAC,8BAA8B,CAAC;QAEjF,MAAM,UAAU,GAAG,UAAU,CAAC,kBAAkB,CAAC;QACjD,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,MAAM,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAC;YACzE,MAAM,CAAC,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC;YAC5C,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC;QAC5K,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACrE,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QAEzG,MAAM,SAAS,GAAG,UAAU,CAAC,6BAA6B,CAAC;QAC3D,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,eAAe,GAAG,UAAU,CAAC,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC,CAAC;QAC3F,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,eAAe,GAAG,UAAU,CAAC,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC,CAAC;QAC3F,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,eAAe,GAAG,UAAU,CAAC,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC,CAAC;QAE3F,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;OAGG;IACI,MAAM;QACT,oCAAoC;QACpC,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,CAAC;YAChF,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAElD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,YAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAE/F,MAAM,cAAc,GAAG,IAAI,CAAC,eAAgB,CAAC;QAC7C,cAAc,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAEjD,cAAc,CAAC,UAAU,EAAE,CAAC;QAC5B,cAAc,CAAC,WAAW,EAAE,CAAC;QAE7B,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;QACpC,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAEnC,MAAM,CAAC,UAAU,CAAC,kBAAkB,EAAE,IAAI,CAAC,WAAW,CAAC,gBAAiB,CAAC,YAAY,CAAC,CAAC;QACvF,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,IAAI,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC;QAEzF,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAEnD,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE9B,cAAc,CAAC,IAAI,EAAE,CAAC;QAEtB,cAAc,CAAC,aAAa,EAAE,CAAC;QAC/B,MAAM,CAAC,yBAAyB,EAAE,CAAC;QAEnC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAEtB,0CAA0C;QAC1C,KAAK,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,sBAAsB,CAAC,EAAE,IAAI,CAAC,CAAC,KAAsB,EAAE,EAAE;YACxH,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,OAAO;YACX,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,KAAiC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,SAAS;QACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,OAAO;QACV,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,aAAa,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC5C,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,CAAC;CACJ","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport { Clamp } from \"core/Maths/math.scalar.functions\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { FromHalfFloat } from \"core/Misc/textureTools\";\r\nimport type { IColor3Like, IColor4Like, IVector2Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { Sample2DRgbaToRef } from \"./sampling\";\r\nimport \"./Shaders/diffuseSkyIrradiance.fragment\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\n\r\nconst RaySamples = 128;\r\nconst LutWidthPx = 64;\r\nconst LutHeightPx = 16;\r\nconst HalfTexelSize = { x: 0.5 / LutWidthPx, y: 0.5 / LutHeightPx };\r\nconst UnitToUVScale = { x: (LutWidthPx - 1.0) / LutWidthPx, y: (LutHeightPx - 1.0) / LutHeightPx };\r\nconst UvTemp = { x: Number.NaN, y: Number.NaN };\r\nconst Color4Temp = { r: Number.NaN, g: Number.NaN, b: Number.NaN, a: Number.NaN } as IColor4Like;\r\n\r\nconst ComputeLutUVToRef = (properties: AtmospherePhysicalProperties, radius: number, cosAngleLightToZenith: number, result: IVector2Like): void => {\r\n const unitX = Clamp(0.5 + 0.5 * cosAngleLightToZenith);\r\n const unitY = Clamp((radius - properties.planetRadius) / properties.atmosphereThickness);\r\n result.x = unitX * UnitToUVScale.x + HalfTexelSize.x;\r\n result.y = unitY * UnitToUVScale.y + HalfTexelSize.y;\r\n};\r\n\r\n/**\r\n * The diffuse sky irradiance LUT is used to query the diffuse irradiance at a specified position.\r\n */\r\nexport class DiffuseSkyIrradianceLut {\r\n private readonly _atmosphere: Atmosphere;\r\n private _renderTarget: Nullable<RenderTargetTexture> = null;\r\n private _effectWrapper: Nullable<EffectWrapper> = null;\r\n private _effectRenderer: Nullable<EffectRenderer> = null;\r\n private _isDirty = true;\r\n private _isDisposed = false;\r\n private _lutData: Uint8Array | Uint16Array = new Uint16Array(0);\r\n\r\n /**\r\n * True if the LUT needs to be rendered.\r\n */\r\n public get isDirty() {\r\n return this._isDirty;\r\n }\r\n\r\n /**\r\n * True if the LUT has been disposed.\r\n */\r\n public get isDisposed(): boolean {\r\n return this._isDisposed;\r\n }\r\n\r\n /**\r\n * The render target used for this LUT.\r\n * @throws if the LUT has been disposed.\r\n */\r\n public get renderTarget(): RenderTargetTexture {\r\n if (this._isDisposed || this._renderTarget === null) {\r\n throw new Error();\r\n }\r\n return this._renderTarget;\r\n }\r\n\r\n /**\r\n * True if the LUT data has been read back from the GPU.\r\n */\r\n public get hasLutData(): boolean {\r\n return this._lutData[0] !== undefined;\r\n }\r\n\r\n /**\r\n * Constructs the {@link DiffuseSkyIrradianceLut}.\r\n * @param atmosphere - The atmosphere to use.\r\n */\r\n constructor(atmosphere: Atmosphere) {\r\n this._atmosphere = atmosphere;\r\n const scene = atmosphere.scene;\r\n const engine = scene.getEngine();\r\n\r\n const name = \"atmo-diffuseSkyIrradiance\";\r\n const caps = engine.getCaps();\r\n const textureType = caps.textureHalfFloatRender ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {\r\n generateMipMaps: false,\r\n type: textureType,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n gammaSpace: false,\r\n }));\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n\r\n const useUbo = atmosphere.uniformBuffer.useUbo;\r\n\r\n this._effectWrapper = new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"diffuseSkyIrradiance\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : atmosphere.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [atmosphere.uniformBuffer.name] : [],\r\n defines: [\r\n \"#define POSITION_VEC2\",\r\n `#define NUM_SAMPLES ${RaySamples}u`,\r\n \"#define CUSTOM_IRRADIANCE_FILTERING_INPUT /* empty */\", // empty, no input texture needed as the radiance is procedurally generated from ray marching.\r\n // The following ray marches the atmosphere to get the radiance.\r\n \"#define CUSTOM_IRRADIANCE_FILTERING_FUNCTION vec3 c = integrateForIrradiance(n, Ls, vec3(0., filteringInfo.x, 0.));\",\r\n ],\r\n samplers: [\"transmittanceLut\", \"multiScatteringLut\"],\r\n useShaderStore: true,\r\n });\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n\r\n // The sky irradiance will also be used for the environment texture.\r\n scene.environmentTexture = renderTarget;\r\n scene.environmentTexture.irradianceTexture = renderTarget;\r\n scene.environmentIntensity = 1.0;\r\n\r\n // Prevent the irradiance LUT from being rendered redundantly at the beginning of the frame.\r\n scene.environmentTexture.isRenderTarget = false;\r\n }\r\n\r\n /**\r\n * Gets the diffuse sky irradiance for a surface oriented along the geocentric normal.\r\n * Resulting color is always in linear space.\r\n * @param directionToLight - The direction to the light in world space.\r\n * @param radius - The position's distance to the planet origin.\r\n * @param cameraGeocentricNormal - The geocentric normal of the camera.\r\n * @param lightIrradiance - The irradiance of the light.\r\n * @param result - The color to store the result in.\r\n * @returns The result color.\r\n */\r\n public getDiffuseSkyIrradianceToRef<T extends IColor3Like>(\r\n directionToLight: IVector3Like,\r\n radius: number,\r\n cameraGeocentricNormal: IVector3Like,\r\n lightIrradiance: number,\r\n result: T\r\n ): T {\r\n const atmosphere = this._atmosphere;\r\n const additionalDiffuseSkyIrradiance = atmosphere.additionalDiffuseSkyIrradiance;\r\n\r\n const properties = atmosphere.physicalProperties;\r\n if (this._lutData[0] === undefined || radius > properties.atmosphereRadius) {\r\n result.r = additionalDiffuseSkyIrradiance.r;\r\n result.g = additionalDiffuseSkyIrradiance.g;\r\n result.b = additionalDiffuseSkyIrradiance.b;\r\n return result;\r\n }\r\n\r\n const cosAngleLightToZenith = directionToLight.x * cameraGeocentricNormal.x + directionToLight.y * cameraGeocentricNormal.y + directionToLight.z * cameraGeocentricNormal.z;\r\n ComputeLutUVToRef(properties, radius, cosAngleLightToZenith, UvTemp);\r\n Sample2DRgbaToRef(UvTemp.x, UvTemp.y, LutWidthPx, LutHeightPx, this._lutData, Color4Temp, FromHalfFloat);\r\n\r\n const intensity = atmosphere.diffuseSkyIrradianceIntensity;\r\n result.r = intensity * (lightIrradiance * Color4Temp.r + additionalDiffuseSkyIrradiance.r);\r\n result.g = intensity * (lightIrradiance * Color4Temp.g + additionalDiffuseSkyIrradiance.g);\r\n result.b = intensity * (lightIrradiance * Color4Temp.b + additionalDiffuseSkyIrradiance.b);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Renders the LUT.\r\n * @returns True if the LUT was rendered.\r\n */\r\n public render(): boolean {\r\n // Only need to render the LUT once.\r\n const effectWrapper = this._effectWrapper;\r\n if (!this._isDirty || !effectWrapper?.isReady() || !this._renderTarget?.isReady()) {\r\n return false;\r\n }\r\n\r\n const engine = this._atmosphere.scene.getEngine();\r\n\r\n engine.bindFramebuffer(this.renderTarget.renderTarget!, undefined, undefined, undefined, true);\r\n\r\n const effectRenderer = this._effectRenderer!;\r\n effectRenderer.applyEffectWrapper(effectWrapper);\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n\r\n const effect = effectWrapper.effect;\r\n effectRenderer.bindBuffers(effect);\r\n\r\n effect.setTexture(\"transmittanceLut\", this._atmosphere.transmittanceLut!.renderTarget);\r\n effect.setTexture(\"multiScatteringLut\", this._atmosphere.multiScatteringLutRenderTarget);\r\n\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n\r\n effect.setFloat(\"depth\", 0.0);\r\n\r\n effectRenderer.draw();\r\n\r\n effectRenderer.restoreStates();\r\n engine.restoreDefaultFramebuffer();\r\n\r\n this._isDirty = false;\r\n\r\n // eslint-disable-next-line github/no-then\r\n void this.renderTarget.readPixels(0, 0, undefined, undefined, true /* noDataConversion */)?.then((value: ArrayBufferView) => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._lutData = value as Uint8Array | Uint16Array;\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Marks the LUT as needing to be rendered.\r\n */\r\n public markDirty(): void {\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Disposes the LUT.\r\n */\r\n public dispose() {\r\n if (this._renderTarget) {\r\n this._renderTarget.irradianceTexture = null;\r\n this._renderTarget.dispose();\r\n }\r\n this._renderTarget = null;\r\n this._effectWrapper?.dispose();\r\n this._effectWrapper = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._isDisposed = true;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"diffuseSkyIrradianceLut.js","sourceRoot":"","sources":["../../../../dev/addons/src/atmosphere/diffuseSkyIrradianceLut.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport { Clamp } from \"core/Maths/math.scalar.functions\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { FromHalfFloat } from \"core/Misc/textureTools\";\r\nimport type { IColor3Like, IColor4Like, IVector2Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { Sample2DRgbaToRef } from \"./sampling\";\r\nimport { Vector3Dot } from \"core/Maths/math.vector.functions\";\r\nimport \"./Shaders/diffuseSkyIrradiance.fragment\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\n\r\nconst RaySamples = 128;\r\nconst LutWidthPx = 64;\r\nconst LutHeightPx = 16;\r\nconst HalfTexelSize = { x: 0.5 / LutWidthPx, y: 0.5 / LutHeightPx };\r\nconst UnitToUVScale = { x: (LutWidthPx - 1.0) / LutWidthPx, y: (LutHeightPx - 1.0) / LutHeightPx };\r\nconst UvTemp = { x: Number.NaN, y: Number.NaN };\r\nconst Color4Temp = { r: Number.NaN, g: Number.NaN, b: Number.NaN, a: Number.NaN } as IColor4Like;\r\n\r\nconst ComputeLutUVToRef = (properties: AtmospherePhysicalProperties, radius: number, cosAngleLightToZenith: number, result: IVector2Like): void => {\r\n const unitX = Clamp(0.5 + 0.5 * cosAngleLightToZenith);\r\n const unitY = Clamp((radius - properties.planetRadius) / properties.atmosphereThickness);\r\n result.x = unitX * UnitToUVScale.x + HalfTexelSize.x;\r\n result.y = unitY * UnitToUVScale.y + HalfTexelSize.y;\r\n};\r\n\r\n/**\r\n * The diffuse sky irradiance LUT is used to query the diffuse irradiance at a specified position.\r\n */\r\nexport class DiffuseSkyIrradianceLut {\r\n private readonly _atmosphere: Atmosphere;\r\n private _renderTarget: Nullable<RenderTargetTexture> = null;\r\n private _effectWrapper: Nullable<EffectWrapper> = null;\r\n private _effectRenderer: Nullable<EffectRenderer> = null;\r\n private _isDirty = true;\r\n private _isDisposed = false;\r\n private _lutData: Uint8Array | Uint16Array = new Uint16Array(0);\r\n\r\n /**\r\n * True if the LUT needs to be rendered.\r\n */\r\n public get isDirty() {\r\n return this._isDirty;\r\n }\r\n\r\n /**\r\n * True if the LUT has been disposed.\r\n */\r\n public get isDisposed(): boolean {\r\n return this._isDisposed;\r\n }\r\n\r\n /**\r\n * The render target used for this LUT.\r\n * @throws if the LUT has been disposed.\r\n */\r\n public get renderTarget(): RenderTargetTexture {\r\n if (this._isDisposed || this._renderTarget === null) {\r\n throw new Error();\r\n }\r\n return this._renderTarget;\r\n }\r\n\r\n /**\r\n * True if the LUT data has been read back from the GPU.\r\n */\r\n public get hasLutData(): boolean {\r\n return this._lutData[0] !== undefined;\r\n }\r\n\r\n /**\r\n * Constructs the {@link DiffuseSkyIrradianceLut}.\r\n * @param atmosphere - The atmosphere to use.\r\n */\r\n constructor(atmosphere: Atmosphere) {\r\n this._atmosphere = atmosphere;\r\n const scene = atmosphere.scene;\r\n const engine = scene.getEngine();\r\n\r\n const name = \"atmo-diffuseSkyIrradiance\";\r\n const caps = engine.getCaps();\r\n const textureType = caps.textureHalfFloatRender ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {\r\n generateMipMaps: false,\r\n type: textureType,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n gammaSpace: false,\r\n }));\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n\r\n const useUbo = atmosphere.uniformBuffer.useUbo;\r\n\r\n this._effectWrapper = new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"diffuseSkyIrradiance\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : atmosphere.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [atmosphere.uniformBuffer.name] : [],\r\n defines: [\r\n \"#define POSITION_VEC2\",\r\n `#define NUM_SAMPLES ${RaySamples}u`,\r\n \"#define CUSTOM_IRRADIANCE_FILTERING_INPUT /* empty */\", // empty, no input texture needed as the radiance is procedurally generated from ray marching.\r\n // The following ray marches the atmosphere to get the radiance.\r\n \"#define CUSTOM_IRRADIANCE_FILTERING_FUNCTION vec3 c = integrateForIrradiance(n, Ls, vec3(0., filteringInfo.x, 0.));\",\r\n ],\r\n samplers: [\"transmittanceLut\", \"multiScatteringLut\"],\r\n useShaderStore: true,\r\n });\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n\r\n // The sky irradiance will also be used for the environment texture.\r\n scene.environmentTexture = renderTarget;\r\n scene.environmentTexture.irradianceTexture = renderTarget;\r\n scene.environmentIntensity = 1.0;\r\n\r\n // Prevent the irradiance LUT from being rendered redundantly at the beginning of the frame.\r\n scene.environmentTexture.isRenderTarget = false;\r\n }\r\n\r\n /**\r\n * Gets the diffuse sky irradiance for a surface oriented along the geocentric normal.\r\n * Resulting color is always in linear space.\r\n * @param directionToLight - The direction to the light in world space.\r\n * @param radius - The position's distance to the planet origin.\r\n * @param cameraGeocentricNormal - The geocentric normal of the camera.\r\n * @param lightIrradiance - The irradiance of the light.\r\n * @param result - The color to store the result in.\r\n * @returns The result color.\r\n */\r\n public getDiffuseSkyIrradianceToRef<T extends IColor3Like>(\r\n directionToLight: IVector3Like,\r\n radius: number,\r\n cameraGeocentricNormal: IVector3Like,\r\n lightIrradiance: number,\r\n result: T\r\n ): T {\r\n const atmosphere = this._atmosphere;\r\n const additionalDiffuseSkyIrradiance = atmosphere.additionalDiffuseSkyIrradiance;\r\n\r\n const properties = atmosphere.physicalProperties;\r\n if (this._lutData[0] === undefined || radius > properties.atmosphereRadius) {\r\n result.r = additionalDiffuseSkyIrradiance.r;\r\n result.g = additionalDiffuseSkyIrradiance.g;\r\n result.b = additionalDiffuseSkyIrradiance.b;\r\n return result;\r\n }\r\n\r\n const cosAngleLightToZenith = Vector3Dot(directionToLight, cameraGeocentricNormal);\r\n ComputeLutUVToRef(properties, radius, cosAngleLightToZenith, UvTemp);\r\n Sample2DRgbaToRef(UvTemp.x, UvTemp.y, LutWidthPx, LutHeightPx, this._lutData, Color4Temp, FromHalfFloat);\r\n\r\n const intensity = atmosphere.diffuseSkyIrradianceIntensity;\r\n result.r = intensity * (lightIrradiance * Color4Temp.r + additionalDiffuseSkyIrradiance.r);\r\n result.g = intensity * (lightIrradiance * Color4Temp.g + additionalDiffuseSkyIrradiance.g);\r\n result.b = intensity * (lightIrradiance * Color4Temp.b + additionalDiffuseSkyIrradiance.b);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Renders the LUT.\r\n * @returns True if the LUT was rendered.\r\n */\r\n public render(): boolean {\r\n // Only need to render the LUT once.\r\n const effectWrapper = this._effectWrapper;\r\n if (!this._isDirty || !effectWrapper?.isReady() || !this._renderTarget?.isReady()) {\r\n return false;\r\n }\r\n\r\n const engine = this._atmosphere.scene.getEngine();\r\n\r\n engine.bindFramebuffer(this.renderTarget.renderTarget!, undefined, undefined, undefined, true);\r\n\r\n const effectRenderer = this._effectRenderer!;\r\n effectRenderer.applyEffectWrapper(effectWrapper);\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n\r\n const effect = effectWrapper.effect;\r\n effectRenderer.bindBuffers(effect);\r\n\r\n effect.setTexture(\"transmittanceLut\", this._atmosphere.transmittanceLut!.renderTarget);\r\n effect.setTexture(\"multiScatteringLut\", this._atmosphere.multiScatteringLutRenderTarget);\r\n\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n\r\n effect.setFloat(\"depth\", 0.0);\r\n\r\n effectRenderer.draw();\r\n\r\n effectRenderer.restoreStates();\r\n engine.restoreDefaultFramebuffer();\r\n\r\n this._isDirty = false;\r\n\r\n // eslint-disable-next-line github/no-then\r\n void this.renderTarget.readPixels(0, 0, undefined, undefined, true /* noDataConversion */)?.then((value: ArrayBufferView) => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._lutData = value as Uint8Array | Uint16Array;\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Marks the LUT as needing to be rendered.\r\n */\r\n public markDirty(): void {\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Disposes the LUT.\r\n */\r\n public dispose() {\r\n if (this._renderTarget) {\r\n this._renderTarget.irradianceTexture = null;\r\n this._renderTarget.dispose();\r\n }\r\n this._renderTarget = null;\r\n this._effectWrapper?.dispose();\r\n this._effectWrapper = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._isDisposed = true;\r\n }\r\n}\r\n"]}
@@ -7,6 +7,7 @@ import { FromHalfFloat } from "@babylonjs/core/Misc/textureTools.js";
7
7
  import { Observable } from "@babylonjs/core/Misc/observable.js";
8
8
  import { RenderTargetTexture } from "@babylonjs/core/Materials/Textures/renderTargetTexture.js";
9
9
  import { Sample2DRgbaToRef } from "./sampling.js";
10
+ import { Vector3Dot } from "@babylonjs/core/Maths/math.vector.functions.js";
10
11
  import "./Shaders/fullscreenTriangle.vertex.js";
11
12
  import "./Shaders/transmittance.fragment.js";
12
13
  const LutWidthPx = 256;
@@ -125,7 +126,7 @@ export class TransmittanceLut {
125
126
  */
126
127
  getTransmittedColorToRef(directionToLight, pointRadius, pointGeocentricNormal, result) {
127
128
  if (this._lutData[0] !== undefined) {
128
- const cosAngleLightToZenith = directionToLight.x * pointGeocentricNormal.x + directionToLight.y * pointGeocentricNormal.y + directionToLight.z * pointGeocentricNormal.z;
129
+ const cosAngleLightToZenith = Vector3Dot(directionToLight, pointGeocentricNormal);
129
130
  SampleLutToRef(this._atmosphere.physicalProperties, this._lutData, pointRadius, cosAngleLightToZenith, Color4Temp);
130
131
  result.r = Color4Temp.r;
131
132
  result.g = Color4Temp.g;
@@ -1 +1 @@
1
- {"version":3,"file":"transmittanceLut.js","sourceRoot":"","sources":["../../../../dev/addons/src/atmosphere/transmittanceLut.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,cAAc;AAId,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,uDAAyC;AACrE,OAAO,EAAE,SAAS,EAAE,6CAA+B;AAEnD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,oDAAsC;AAC9E,OAAO,EAAE,aAAa,EAAE,6CAA+B;AAGvD,OAAO,EAAE,UAAU,EAAE,2CAA6B;AAClD,OAAO,EAAE,mBAAmB,EAAE,kEAAoD;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,kCAAkC,CAAC;AAE1C,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,wBAAwB,GAAG,EAAE,CAAC,EAAE,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,WAAW,EAAE,CAAC;AAC9G,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,GAAG,GAAG,UAAU,EAAE,CAAC,EAAE,GAAG,GAAG,WAAW,EAAE,CAAC;AACpE,MAAM,yBAAyB,GAAG,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC;AACxD,MAAM,2BAA2B,GAAG,GAAG,GAAG,GAAG,GAAG,yBAAyB,CAAC;AAE1E,MAAM,YAAY,GAAG,KAAK,CAAC;AAE3B,qBAAqB;AACrB,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAkB,CAAC;AAC5D,MAAM,cAAc,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAiB,CAAC;AACtF,MAAM,oBAAoB,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAkB,CAAC;AAC7F,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,GAAG,EAAiB,CAAC;AAEjG,MAAM,iBAAiB,GAAG,CAAC,UAAwC,EAAE,MAAc,EAAE,qBAA6B,EAAE,EAAgB,EAAQ,EAAE;IAC1I,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAEnG,MAAM,uBAAuB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;IAC9E,MAAM,YAAY,GAAG,aAAa,GAAG,CAAC,uBAAuB,GAAG,GAAG,CAAC,GAAG,UAAU,CAAC,uBAAuB,CAAC;IAC1G,MAAM,wBAAwB,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAEzH,MAAM,2BAA2B,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,gBAAgB,GAAG,MAAM,CAAC,CAAC;IACxF,MAAM,2BAA2B,GAAG,iBAAiB,GAAG,UAAU,CAAC,+BAA+B,CAAC;IACnG,MAAM,+BAA+B,GACjC,CAAC,wBAAwB,GAAG,2BAA2B,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,2BAA2B,GAAG,2BAA2B,CAAC,CAAC;IAC7I,MAAM,2BAA2B,GAAG,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,+BAA+B,CAAC,CAAC;IAEvH,cAAc;IACd,EAAE,CAAC,CAAC,GAAG,wBAAwB,CAAC,CAAC,GAAG,+BAA+B,GAAG,aAAa,CAAC,CAAC,CAAC;IACtF,EAAE,CAAC,CAAC,GAAG,wBAAwB,CAAC,CAAC,GAAG,2BAA2B,GAAG,aAAa,CAAC,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACnB,UAAwC,EACxC,OAAiC,EACjC,wBAAgC,EAChC,qBAA6B,EAC7B,MAAmB,EACf,EAAE;IACN,IAAI,wBAAwB,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACzD,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC;QAChD,OAAO;IACX,CAAC;IAED,iBAAiB,CAAC,UAAU,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;IACnF,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IAEjI,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,2BAA2B,CAAC,GAAG,yBAAyB,CAAC,CAAC,CAAC,CAAC;IACpH,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC;IACnB,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC;IACnB,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC;IACnB,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC;AACvB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAezB;;OAEG;IACH,IAAW,OAAO;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,IAAW,YAAY;QACnB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,EAAE,CAAC;QACtB,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,YAAY,UAAsB;QApClC;;;WAGG;QACa,wBAAmB,GAAG,IAAI,UAAU,EAAQ,CAAC;QAGrD,aAAQ,GAA6B,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAIvD,aAAQ,GAAG,IAAI,CAAC;QAChB,gBAAW,GAAG,KAAK,CAAC;QAyBxB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAE9B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;QACrC,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,YAAY,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,sBAAsB,CAAC;QAE7E,MAAM,IAAI,GAAG,oBAAoB,CAAC;QAClC,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,mBAAmB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE;YACxH,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,SAAS,CAAC,yBAAyB;YAC3F,YAAY,EAAE,SAAS,CAAC,6BAA6B;YACrD,mBAAmB,EAAE,KAAK;YAC1B,UAAU,EAAE,KAAK;SACpB,CAAC,CAAC,CAAC;QACJ,YAAY,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;QACzD,YAAY,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;QACzD,YAAY,CAAC,yBAAyB,GAAG,CAAC,CAAC;QAC3C,YAAY,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAErC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC;QACrD,IAAI,CAAC,cAAc,GAAG,IAAI,aAAa,CAAC;YACpC,MAAM;YACN,IAAI;YACJ,YAAY,EAAE,oBAAoB;YAClC,cAAc,EAAE,eAAe;YAC/B,cAAc,EAAE,CAAC,UAAU,CAAC;YAC5B,YAAY,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC,CAAC;YAC5F,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;YACnE,OAAO,EAAE,CAAC,uBAAuB,CAAC;YAClC,cAAc,EAAE,IAAI;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE;YAC9C,wBAAwB;YACxB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAClB,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SACpC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;;OAQG;IACI,wBAAwB,CAAwB,gBAA8B,EAAE,WAAmB,EAAE,qBAAmC,EAAE,MAAS;QACtJ,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,qBAAqB,GACvB,gBAAgB,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC;YAC/I,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAC;YACnH,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACJ,YAAY;YACZ,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC;QACzC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACI,qBAAqB,CAAC,KAAuB,EAAE,WAAmB,EAAE,qBAAmC;QAC1G,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,CAAC;QACvC,oBAAoB,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;QAC3C,oBAAoB,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;QAC3C,oBAAoB,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,wBAAwB,CAAC,oBAAoB,EAAE,WAAW,EAAE,qBAAqB,EAAE,cAAc,CAAC,CAAC;QAExG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;QACnF,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACxF,CAAC;IAED;;;OAGG;IACI,MAAM;QACT,oCAAoC;QACpC,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,CAAC;YAChF,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAElD,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,YAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAE/F,MAAM,cAAc,GAAG,IAAI,CAAC,eAAgB,CAAC;QAC7C,cAAc,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAEjD,cAAc,CAAC,UAAU,EAAE,CAAC;QAC5B,cAAc,CAAC,WAAW,EAAE,CAAC;QAE7B,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;QACpC,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAEnC,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAEnD,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAE5B,cAAc,CAAC,IAAI,EAAE,CAAC;QAEtB,cAAc,CAAC,aAAa,EAAE,CAAC;QAC/B,MAAM,CAAC,yBAAyB,EAAE,CAAC;QAEnC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAEtB,0CAA0C;QAC1C,KAAK,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,sBAAsB,CAAC,EAAE,IAAI,CAAC,CAAC,KAAsB,EAAE,EAAE;YAChI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,OAAO;YACX,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,KAAiC,CAAC;YAClD,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,SAAS;QACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,OAAO;QACV,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,CAAC;CACJ","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport { Clamp, SmoothStep } from \"core/Maths/math.scalar.functions\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { DirectionalLight } from \"core/Lights/directionalLight\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { FromHalfFloat } from \"core/Misc/textureTools\";\r\nimport type { IColor3Like, IColor4Like, IVector2Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { Sample2DRgbaToRef } from \"./sampling\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\nimport \"./Shaders/transmittance.fragment\";\r\n\r\nconst LutWidthPx = 256;\r\nconst LutHeightPx = 64;\r\nconst EffectiveDomainInUVSpace = { x: (LutWidthPx - 1.0) / LutWidthPx, y: (LutHeightPx - 1.0) / LutHeightPx };\r\nconst HalfTexelSize = { x: 0.5 / LutWidthPx, y: 0.5 / LutHeightPx };\r\nconst TransmittanceHorizonRange = 2.0 * HalfTexelSize.x;\r\nconst TransmittanceMaxUnoccludedU = 1.0 - 0.5 * TransmittanceHorizonRange;\r\n\r\nconst UseHalfFloat = false;\r\n\r\n// Temporary storage.\r\nconst Uv = { x: Number.NaN, y: Number.NaN } as IVector2Like;\r\nconst LightColorTemp = { r: Number.NaN, g: Number.NaN, b: Number.NaN } as IColor3Like;\r\nconst DirectionToLightTemp = { x: Number.NaN, y: Number.NaN, z: Number.NaN } as IVector3Like;\r\nconst Color4Temp = { r: Number.NaN, g: Number.NaN, b: Number.NaN, a: Number.NaN } as IColor4Like;\r\n\r\nconst ComputeLutUVToRef = (properties: AtmospherePhysicalProperties, radius: number, cosAngleLightToZenith: number, uv: IVector2Like): void => {\r\n const radiusSquared = radius * radius;\r\n const distanceToHorizon = Math.sqrt(Math.max(0.0, radiusSquared - properties.planetRadiusSquared));\r\n\r\n const cosAngleLightToZenithSq = cosAngleLightToZenith * cosAngleLightToZenith;\r\n const discriminant = radiusSquared * (cosAngleLightToZenithSq - 1.0) + properties.atmosphereRadiusSquared;\r\n const distanceToAtmosphereEdge = Math.max(0.0, -radius * cosAngleLightToZenith + Math.sqrt(Math.max(0.0, discriminant)));\r\n\r\n const minDistanceToAtmosphereEdge = Math.max(0.0, properties.atmosphereRadius - radius);\r\n const maxDistanceToAtmosphereEdge = distanceToHorizon + properties.horizonDistanceToAtmosphereEdge;\r\n const cosAngleLightToZenithCoordinate =\r\n (distanceToAtmosphereEdge - minDistanceToAtmosphereEdge) / Math.max(0.000001, maxDistanceToAtmosphereEdge - minDistanceToAtmosphereEdge);\r\n const distanceToHorizonCoordinate = distanceToHorizon / Math.max(0.000001, properties.horizonDistanceToAtmosphereEdge);\r\n\r\n // Unit to UV.\r\n uv.x = EffectiveDomainInUVSpace.x * cosAngleLightToZenithCoordinate + HalfTexelSize.x;\r\n uv.y = EffectiveDomainInUVSpace.y * distanceToHorizonCoordinate + HalfTexelSize.y;\r\n};\r\n\r\nconst SampleLutToRef = (\r\n properties: AtmospherePhysicalProperties,\r\n lutData: Uint8Array | Uint16Array,\r\n positionDistanceToOrigin: number,\r\n cosAngleLightToZenith: number,\r\n result: IColor4Like\r\n): void => {\r\n if (positionDistanceToOrigin > properties.atmosphereRadius) {\r\n result.r = result.g = result.b = result.a = 1.0;\r\n return;\r\n }\r\n\r\n ComputeLutUVToRef(properties, positionDistanceToOrigin, cosAngleLightToZenith, Uv);\r\n Sample2DRgbaToRef(Uv.x, Uv.y, LutWidthPx, LutHeightPx, lutData, result, UseHalfFloat ? FromHalfFloat : (value) => value / 255.0);\r\n\r\n const weight = Clamp(SmoothStep(1.0, 0.0, Clamp((Uv.x - TransmittanceMaxUnoccludedU) / TransmittanceHorizonRange)));\r\n result.r *= weight;\r\n result.g *= weight;\r\n result.b *= weight;\r\n result.a *= weight;\r\n};\r\n\r\n/**\r\n * The transmittance LUT can be used to get the radiance from an external light source arriving a given point, accounting for atmospheric scattering.\r\n */\r\nexport class TransmittanceLut {\r\n /**\r\n * Listen to this observer to know when the LUT data has been updated.\r\n * This is typically infrequent (once at startup), but also happens whenever the atmosphere's properties change.\r\n */\r\n public readonly onUpdatedObservable = new Observable<void>();\r\n\r\n private readonly _atmosphere: Atmosphere;\r\n private _lutData: Uint8Array | Uint16Array = new Uint8Array(0);\r\n private _renderTarget: Nullable<RenderTargetTexture>;\r\n private _effectWrapper: Nullable<EffectWrapper>;\r\n private _effectRenderer: Nullable<EffectRenderer>;\r\n private _isDirty = true;\r\n private _isDisposed = false;\r\n\r\n /**\r\n * True if the LUT has been rendered.\r\n */\r\n public get isDirty(): boolean {\r\n return this._isDirty;\r\n }\r\n\r\n /**\r\n * The render target that contains the transmittance LUT.\r\n * @throws if the LUT has been disposed.\r\n */\r\n public get renderTarget(): RenderTargetTexture {\r\n if (this._isDisposed || this._renderTarget === null) {\r\n throw new Error();\r\n }\r\n return this._renderTarget;\r\n }\r\n\r\n /**\r\n * Constructs the {@link TransmittanceLut}.\r\n * @param atmosphere - The atmosphere that owns this LUT.\r\n */\r\n constructor(atmosphere: Atmosphere) {\r\n this._atmosphere = atmosphere;\r\n\r\n const scene = this._atmosphere.scene;\r\n const engine = scene.getEngine();\r\n const useHalfFloat = UseHalfFloat && engine.getCaps().textureHalfFloatRender;\r\n\r\n const name = \"atmo-transmittance\";\r\n const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {\r\n type: useHalfFloat ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n gammaSpace: false,\r\n }));\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n\r\n const useUbo = this._atmosphere.uniformBuffer.useUbo;\r\n this._effectWrapper = new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"transmittance\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : this._atmosphere.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [this._atmosphere.uniformBuffer.name] : [],\r\n defines: [\"#define POSITION_VEC2\"],\r\n useShaderStore: true,\r\n });\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n }\r\n\r\n /**\r\n * Gets the transmittance of an external light through the atmosphere to a point specified by its distance to the planet center and its geocentric normal.\r\n * The result is always a linear space color.\r\n * @param directionToLight - The direction to the light source.\r\n * @param pointRadius - The distance from the origin to the point.\r\n * @param pointGeocentricNormal - The normal of the point.\r\n * @param result - The color to write the result to.\r\n * @returns The result color.\r\n */\r\n public getTransmittedColorToRef<T extends IColor3Like>(directionToLight: IVector3Like, pointRadius: number, pointGeocentricNormal: IVector3Like, result: T): T {\r\n if (this._lutData[0] !== undefined) {\r\n const cosAngleLightToZenith =\r\n directionToLight.x * pointGeocentricNormal.x + directionToLight.y * pointGeocentricNormal.y + directionToLight.z * pointGeocentricNormal.z;\r\n SampleLutToRef(this._atmosphere.physicalProperties, this._lutData, pointRadius, cosAngleLightToZenith, Color4Temp);\r\n result.r = Color4Temp.r;\r\n result.g = Color4Temp.g;\r\n result.b = Color4Temp.b;\r\n } else {\r\n // Fallback.\r\n result.r = result.g = result.b = 1.0;\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Derives light color from the transmittance at a point specified by its distance to the planet center and its geocentric normal.\r\n * @param light - The light to update.\r\n * @param pointRadius - The distance from the origin to the point.\r\n * @param pointGeocentricNormal - The normal of the point.\r\n */\r\n public updateLightParameters(light: DirectionalLight, pointRadius: number, pointGeocentricNormal: IVector3Like): void {\r\n const lightDirection = light.direction;\r\n DirectionToLightTemp.x = -lightDirection.x;\r\n DirectionToLightTemp.y = -lightDirection.y;\r\n DirectionToLightTemp.z = -lightDirection.z;\r\n this.getTransmittedColorToRef(DirectionToLightTemp, pointRadius, pointGeocentricNormal, LightColorTemp);\r\n\r\n light.diffuse.copyFromFloats(LightColorTemp.r, LightColorTemp.g, LightColorTemp.b);\r\n light.specular.copyFromFloats(LightColorTemp.r, LightColorTemp.g, LightColorTemp.b);\r\n }\r\n\r\n /**\r\n * Renders the LUT if needed.\r\n * @returns true if the LUT was rendered.\r\n */\r\n public render(): boolean {\r\n // Only need to render the LUT once.\r\n const effectWrapper = this._effectWrapper;\r\n if (!this._isDirty || !effectWrapper?.isReady() || !this._renderTarget?.isReady()) {\r\n return false;\r\n }\r\n\r\n const engine = this._atmosphere.scene.getEngine();\r\n\r\n engine.bindFramebuffer(this.renderTarget.renderTarget!, undefined, undefined, undefined, true);\r\n\r\n const effectRenderer = this._effectRenderer!;\r\n effectRenderer.applyEffectWrapper(effectWrapper);\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n\r\n const effect = effectWrapper.effect;\r\n effectRenderer.bindBuffers(effect);\r\n\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n\r\n effect.setFloat(\"depth\", 0);\r\n\r\n effectRenderer.draw();\r\n\r\n effectRenderer.restoreStates();\r\n engine.restoreDefaultFramebuffer();\r\n\r\n this._isDirty = false;\r\n\r\n // eslint-disable-next-line github/no-then\r\n void this.renderTarget.readPixels(0, 0, undefined, undefined, UseHalfFloat /* noDataConversion */)?.then((value: ArrayBufferView) => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._lutData = value as Uint8Array | Uint16Array;\r\n this.onUpdatedObservable.notifyObservers();\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Marks the LUT as needing to be rendered.\r\n */\r\n public markDirty(): void {\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Disposes the LUT and its resources.\r\n */\r\n public dispose(): void {\r\n this._renderTarget?.dispose();\r\n this._renderTarget = null;\r\n this._effectWrapper?.dispose();\r\n this._effectWrapper = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._isDisposed = true;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"transmittanceLut.js","sourceRoot":"","sources":["../../../../dev/addons/src/atmosphere/transmittanceLut.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\r\n// MIT License\r\n\r\nimport type { Atmosphere } from \"./atmosphere\";\r\nimport type { AtmospherePhysicalProperties } from \"./atmospherePhysicalProperties\";\r\nimport { Clamp, SmoothStep } from \"core/Maths/math.scalar.functions\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport type { DirectionalLight } from \"core/Lights/directionalLight\";\r\nimport { EffectRenderer, EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { FromHalfFloat } from \"core/Misc/textureTools\";\r\nimport type { IColor3Like, IColor4Like, IVector2Like, IVector3Like } from \"core/Maths/math.like\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Observable } from \"core/Misc/observable\";\r\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\r\nimport { Sample2DRgbaToRef } from \"./sampling\";\r\nimport { Vector3Dot } from \"core/Maths/math.vector.functions\";\r\nimport \"./Shaders/fullscreenTriangle.vertex\";\r\nimport \"./Shaders/transmittance.fragment\";\r\n\r\nconst LutWidthPx = 256;\r\nconst LutHeightPx = 64;\r\nconst EffectiveDomainInUVSpace = { x: (LutWidthPx - 1.0) / LutWidthPx, y: (LutHeightPx - 1.0) / LutHeightPx };\r\nconst HalfTexelSize = { x: 0.5 / LutWidthPx, y: 0.5 / LutHeightPx };\r\nconst TransmittanceHorizonRange = 2.0 * HalfTexelSize.x;\r\nconst TransmittanceMaxUnoccludedU = 1.0 - 0.5 * TransmittanceHorizonRange;\r\n\r\nconst UseHalfFloat = false;\r\n\r\n// Temporary storage.\r\nconst Uv = { x: Number.NaN, y: Number.NaN } as IVector2Like;\r\nconst LightColorTemp = { r: Number.NaN, g: Number.NaN, b: Number.NaN } as IColor3Like;\r\nconst DirectionToLightTemp = { x: Number.NaN, y: Number.NaN, z: Number.NaN } as IVector3Like;\r\nconst Color4Temp = { r: Number.NaN, g: Number.NaN, b: Number.NaN, a: Number.NaN } as IColor4Like;\r\n\r\nconst ComputeLutUVToRef = (properties: AtmospherePhysicalProperties, radius: number, cosAngleLightToZenith: number, uv: IVector2Like): void => {\r\n const radiusSquared = radius * radius;\r\n const distanceToHorizon = Math.sqrt(Math.max(0.0, radiusSquared - properties.planetRadiusSquared));\r\n\r\n const cosAngleLightToZenithSq = cosAngleLightToZenith * cosAngleLightToZenith;\r\n const discriminant = radiusSquared * (cosAngleLightToZenithSq - 1.0) + properties.atmosphereRadiusSquared;\r\n const distanceToAtmosphereEdge = Math.max(0.0, -radius * cosAngleLightToZenith + Math.sqrt(Math.max(0.0, discriminant)));\r\n\r\n const minDistanceToAtmosphereEdge = Math.max(0.0, properties.atmosphereRadius - radius);\r\n const maxDistanceToAtmosphereEdge = distanceToHorizon + properties.horizonDistanceToAtmosphereEdge;\r\n const cosAngleLightToZenithCoordinate =\r\n (distanceToAtmosphereEdge - minDistanceToAtmosphereEdge) / Math.max(0.000001, maxDistanceToAtmosphereEdge - minDistanceToAtmosphereEdge);\r\n const distanceToHorizonCoordinate = distanceToHorizon / Math.max(0.000001, properties.horizonDistanceToAtmosphereEdge);\r\n\r\n // Unit to UV.\r\n uv.x = EffectiveDomainInUVSpace.x * cosAngleLightToZenithCoordinate + HalfTexelSize.x;\r\n uv.y = EffectiveDomainInUVSpace.y * distanceToHorizonCoordinate + HalfTexelSize.y;\r\n};\r\n\r\nconst SampleLutToRef = (\r\n properties: AtmospherePhysicalProperties,\r\n lutData: Uint8Array | Uint16Array,\r\n positionDistanceToOrigin: number,\r\n cosAngleLightToZenith: number,\r\n result: IColor4Like\r\n): void => {\r\n if (positionDistanceToOrigin > properties.atmosphereRadius) {\r\n result.r = result.g = result.b = result.a = 1.0;\r\n return;\r\n }\r\n\r\n ComputeLutUVToRef(properties, positionDistanceToOrigin, cosAngleLightToZenith, Uv);\r\n Sample2DRgbaToRef(Uv.x, Uv.y, LutWidthPx, LutHeightPx, lutData, result, UseHalfFloat ? FromHalfFloat : (value) => value / 255.0);\r\n\r\n const weight = Clamp(SmoothStep(1.0, 0.0, Clamp((Uv.x - TransmittanceMaxUnoccludedU) / TransmittanceHorizonRange)));\r\n result.r *= weight;\r\n result.g *= weight;\r\n result.b *= weight;\r\n result.a *= weight;\r\n};\r\n\r\n/**\r\n * The transmittance LUT can be used to get the radiance from an external light source arriving a given point, accounting for atmospheric scattering.\r\n */\r\nexport class TransmittanceLut {\r\n /**\r\n * Listen to this observer to know when the LUT data has been updated.\r\n * This is typically infrequent (once at startup), but also happens whenever the atmosphere's properties change.\r\n */\r\n public readonly onUpdatedObservable = new Observable<void>();\r\n\r\n private readonly _atmosphere: Atmosphere;\r\n private _lutData: Uint8Array | Uint16Array = new Uint8Array(0);\r\n private _renderTarget: Nullable<RenderTargetTexture>;\r\n private _effectWrapper: Nullable<EffectWrapper>;\r\n private _effectRenderer: Nullable<EffectRenderer>;\r\n private _isDirty = true;\r\n private _isDisposed = false;\r\n\r\n /**\r\n * True if the LUT has been rendered.\r\n */\r\n public get isDirty(): boolean {\r\n return this._isDirty;\r\n }\r\n\r\n /**\r\n * The render target that contains the transmittance LUT.\r\n * @throws if the LUT has been disposed.\r\n */\r\n public get renderTarget(): RenderTargetTexture {\r\n if (this._isDisposed || this._renderTarget === null) {\r\n throw new Error();\r\n }\r\n return this._renderTarget;\r\n }\r\n\r\n /**\r\n * Constructs the {@link TransmittanceLut}.\r\n * @param atmosphere - The atmosphere that owns this LUT.\r\n */\r\n constructor(atmosphere: Atmosphere) {\r\n this._atmosphere = atmosphere;\r\n\r\n const scene = this._atmosphere.scene;\r\n const engine = scene.getEngine();\r\n const useHalfFloat = UseHalfFloat && engine.getCaps().textureHalfFloatRender;\r\n\r\n const name = \"atmo-transmittance\";\r\n const renderTarget = (this._renderTarget = new RenderTargetTexture(name, { width: LutWidthPx, height: LutHeightPx }, scene, {\r\n type: useHalfFloat ? Constants.TEXTURETYPE_HALF_FLOAT : Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n gammaSpace: false,\r\n }));\r\n renderTarget.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n renderTarget.anisotropicFilteringLevel = 1;\r\n renderTarget.skipInitialClear = true;\r\n\r\n const useUbo = this._atmosphere.uniformBuffer.useUbo;\r\n this._effectWrapper = new EffectWrapper({\r\n engine,\r\n name,\r\n vertexShader: \"fullscreenTriangle\",\r\n fragmentShader: \"transmittance\",\r\n attributeNames: [\"position\"],\r\n uniformNames: [\"depth\", ...(useUbo ? [] : this._atmosphere.uniformBuffer.getUniformNames())],\r\n uniformBuffers: useUbo ? [this._atmosphere.uniformBuffer.name] : [],\r\n defines: [\"#define POSITION_VEC2\"],\r\n useShaderStore: true,\r\n });\r\n\r\n this._effectRenderer = new EffectRenderer(engine, {\r\n // Full screen triangle.\r\n indices: [0, 2, 1],\r\n positions: [-1, -1, -1, 3, 3, -1],\r\n });\r\n }\r\n\r\n /**\r\n * Gets the transmittance of an external light through the atmosphere to a point specified by its distance to the planet center and its geocentric normal.\r\n * The result is always a linear space color.\r\n * @param directionToLight - The direction to the light source.\r\n * @param pointRadius - The distance from the origin to the point.\r\n * @param pointGeocentricNormal - The normal of the point.\r\n * @param result - The color to write the result to.\r\n * @returns The result color.\r\n */\r\n public getTransmittedColorToRef<T extends IColor3Like>(directionToLight: IVector3Like, pointRadius: number, pointGeocentricNormal: IVector3Like, result: T): T {\r\n if (this._lutData[0] !== undefined) {\r\n const cosAngleLightToZenith = Vector3Dot(directionToLight, pointGeocentricNormal);\r\n SampleLutToRef(this._atmosphere.physicalProperties, this._lutData, pointRadius, cosAngleLightToZenith, Color4Temp);\r\n result.r = Color4Temp.r;\r\n result.g = Color4Temp.g;\r\n result.b = Color4Temp.b;\r\n } else {\r\n // Fallback.\r\n result.r = result.g = result.b = 1.0;\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Derives light color from the transmittance at a point specified by its distance to the planet center and its geocentric normal.\r\n * @param light - The light to update.\r\n * @param pointRadius - The distance from the origin to the point.\r\n * @param pointGeocentricNormal - The normal of the point.\r\n */\r\n public updateLightParameters(light: DirectionalLight, pointRadius: number, pointGeocentricNormal: IVector3Like): void {\r\n const lightDirection = light.direction;\r\n DirectionToLightTemp.x = -lightDirection.x;\r\n DirectionToLightTemp.y = -lightDirection.y;\r\n DirectionToLightTemp.z = -lightDirection.z;\r\n this.getTransmittedColorToRef(DirectionToLightTemp, pointRadius, pointGeocentricNormal, LightColorTemp);\r\n\r\n light.diffuse.copyFromFloats(LightColorTemp.r, LightColorTemp.g, LightColorTemp.b);\r\n light.specular.copyFromFloats(LightColorTemp.r, LightColorTemp.g, LightColorTemp.b);\r\n }\r\n\r\n /**\r\n * Renders the LUT if needed.\r\n * @returns true if the LUT was rendered.\r\n */\r\n public render(): boolean {\r\n // Only need to render the LUT once.\r\n const effectWrapper = this._effectWrapper;\r\n if (!this._isDirty || !effectWrapper?.isReady() || !this._renderTarget?.isReady()) {\r\n return false;\r\n }\r\n\r\n const engine = this._atmosphere.scene.getEngine();\r\n\r\n engine.bindFramebuffer(this.renderTarget.renderTarget!, undefined, undefined, undefined, true);\r\n\r\n const effectRenderer = this._effectRenderer!;\r\n effectRenderer.applyEffectWrapper(effectWrapper);\r\n\r\n effectRenderer.saveStates();\r\n effectRenderer.setViewport();\r\n\r\n const effect = effectWrapper.effect;\r\n effectRenderer.bindBuffers(effect);\r\n\r\n this._atmosphere.bindUniformBufferToEffect(effect);\r\n\r\n effect.setFloat(\"depth\", 0);\r\n\r\n effectRenderer.draw();\r\n\r\n effectRenderer.restoreStates();\r\n engine.restoreDefaultFramebuffer();\r\n\r\n this._isDirty = false;\r\n\r\n // eslint-disable-next-line github/no-then\r\n void this.renderTarget.readPixels(0, 0, undefined, undefined, UseHalfFloat /* noDataConversion */)?.then((value: ArrayBufferView) => {\r\n if (this._isDisposed) {\r\n return;\r\n }\r\n this._lutData = value as Uint8Array | Uint16Array;\r\n this.onUpdatedObservable.notifyObservers();\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Marks the LUT as needing to be rendered.\r\n */\r\n public markDirty(): void {\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Disposes the LUT and its resources.\r\n */\r\n public dispose(): void {\r\n this._renderTarget?.dispose();\r\n this._renderTarget = null;\r\n this._effectWrapper?.dispose();\r\n this._effectWrapper = null;\r\n this._effectRenderer?.dispose();\r\n this._effectRenderer = null;\r\n this._isDisposed = true;\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babylonjs/addons",
3
- "version": "8.34.0",
3
+ "version": "8.35.0",
4
4
  "main": "index.js",
5
5
  "module": "index.js",
6
6
  "types": "index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "postcompile": "build-tools -c add-js-to-es6"
19
19
  },
20
20
  "devDependencies": {
21
- "@babylonjs/core": "^8.34.0",
21
+ "@babylonjs/core": "^8.35.0",
22
22
  "@dev/addons": "^1.0.0",
23
23
  "@dev/build-tools": "^1.0.0"
24
24
  },