procedural-terrains 2.0.0 → 2.0.1

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.
Files changed (43) hide show
  1. package/dist/{FiniteTerrain-B34WMz5S.js → FiniteTerrain-B5_3y6xX.js} +3 -3
  2. package/dist/{FiniteTerrain-B34WMz5S.js.map → FiniteTerrain-B5_3y6xX.js.map} +1 -1
  3. package/dist/{InfiniteTerrain-SgoJz3qJ.js → InfiniteTerrain-jeCy6RED.js} +5 -5
  4. package/dist/{InfiniteTerrain-SgoJz3qJ.js.map → InfiniteTerrain-jeCy6RED.js.map} +1 -1
  5. package/dist/{MiniTerrain-Blt0H1S0.js → MiniTerrain-Bb5VYkZU.js} +8 -8
  6. package/dist/MiniTerrain-Bb5VYkZU.js.map +1 -0
  7. package/dist/{PlanetMaterial-B1_ZPlx5.js → PlanetMaterial-Cs-_x6vr.js} +4 -4
  8. package/dist/{PlanetMaterial-B1_ZPlx5.js.map → PlanetMaterial-Cs-_x6vr.js.map} +1 -1
  9. package/dist/{PlanetTerrain-DCvxS1Q8.js → PlanetTerrain-Bsfx7YA6.js} +5 -5
  10. package/dist/{PlanetTerrain-DCvxS1Q8.js.map → PlanetTerrain-Bsfx7YA6.js.map} +1 -1
  11. package/dist/{RevisionScope-J__6V9I_.js → RevisionScope-Dl4yjj-0.js} +2 -2
  12. package/dist/{RevisionScope-J__6V9I_.js.map → RevisionScope-Dl4yjj-0.js.map} +1 -1
  13. package/dist/{TerrainClouds-BuKvwnWw.js → TerrainClouds-DV6ny7P1.js} +31 -19
  14. package/dist/TerrainClouds-DV6ny7P1.js.map +1 -0
  15. package/dist/{TerrainHeightCache-Dsde6EDL.js → TerrainHeightCache-DIZxi9jz.js} +2 -2
  16. package/dist/{TerrainHeightCache-Dsde6EDL.js.map → TerrainHeightCache-DIZxi9jz.js.map} +1 -1
  17. package/dist/{TerrainParameters-A3fcNJTR.js → TerrainParameters-DMCjnnxz.js} +10 -8
  18. package/dist/TerrainParameters-DMCjnnxz.js.map +1 -0
  19. package/dist/{TerrainWater-Cil7waG3.js → TerrainWater-CX4XdwA0.js} +17 -11
  20. package/dist/TerrainWater-CX4XdwA0.js.map +1 -0
  21. package/dist/{WaterMaterial-BUsAp0SS.js → WaterMaterial-C9h1xm9E.js} +7 -5
  22. package/dist/WaterMaterial-C9h1xm9E.js.map +1 -0
  23. package/dist/{biomeGLSL-CIkhxIlH.js → biomeGLSL-DWGDDBqT.js} +6 -3
  24. package/dist/{biomeGLSL-CIkhxIlH.js.map → biomeGLSL-DWGDDBqT.js.map} +1 -1
  25. package/dist/clouds.js +1 -1
  26. package/dist/documents.js +6 -6
  27. package/dist/export.js +2 -2
  28. package/dist/index.js +1 -1
  29. package/dist/infinite.js +1 -1
  30. package/dist/mini.js +1 -1
  31. package/dist/planet.js +1 -1
  32. package/dist/{planetGLSL-2xas0f3o.js → planetGLSL-D9Zy2IAw.js} +2 -2
  33. package/dist/{planetGLSL-2xas0f3o.js.map → planetGLSL-D9Zy2IAw.js.map} +1 -1
  34. package/dist/real-world.js +1 -1
  35. package/dist/render.js +1 -1
  36. package/dist/viewer.js +1 -1
  37. package/dist/water.js +1 -1
  38. package/package.json +1 -1
  39. package/dist/MiniTerrain-Blt0H1S0.js.map +0 -1
  40. package/dist/TerrainClouds-BuKvwnWw.js.map +0 -1
  41. package/dist/TerrainParameters-A3fcNJTR.js.map +0 -1
  42. package/dist/TerrainWater-Cil7waG3.js.map +0 -1
  43. package/dist/WaterMaterial-BUsAp0SS.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TerrainHeightCache-Dsde6EDL.js","sources":["../../../src/engine/terrain/TerrainHeightBaker.js","../../../src/runtime/effects/TerrainHeightCache.js"],"sourcesContent":["import * as THREE from 'three';\nimport { COMMON_UNIFORMS_GLSL, NOISE_GLSL, buildHeightGLSL } from './terrainGLSL.js';\nimport { BIOME_GLSL } from './biomeGLSL.js';\nimport { generateStackGLSL } from './noise/noiseStackCodegen.js';\nimport { defaultLegacyStack } from './noise/NoiseStack.js';\n\nconst DEFAULT_STACK_GLSL = generateStackGLSL(defaultLegacyStack());\n\n// ============================================================================\n// Studio (flat board) height/normal baker — the 2D analog of\n// PlanetHeightBaker. The studio terrain + water fragment shaders re-evaluate\n// the full ~46-octave height field FOR EVERY PIXEL, EVERY FRAME (the terrain\n// fragment does it three times to build the analytic normal). Whenever the\n// camera orbits or the player walks, that per-pixel cost — not the triangle\n// count — is what drops the framerate on weak GPUs.\n//\n// This baker evaluates the field once into a 2D texture whenever it actually\n// changes (seed / shape / biome / paint edits, tracked by the engine's terrain\n// generation counter). Packed representation (RGBA16F, signed):\n// R,G = geometric surface normal x,z (y is positive and implied)\n// B = curvature ((hX + hZ) / 2 - hC) / eps (concavity AO / ridge accent)\n// A = height / heightScale\n// Baking the exact finite-difference normal keeps terrain lighting identical to\n// the live field. Reconstructing it later from a filtered height-only texture\n// visibly flattened the terrain and moved material/shore signals.\n//\n// The board spans world XZ in [-uBoardHalf, uBoardHalf]; the bake maps the\n// fullscreen quad UV straight onto that range, so a later fetch by world XZ\n// (uv = (xz - uBakeOrigin) / uBakeSpan) lines up automatically. Half-float keeps\n// h01 precise and is linearly filterable in WebGL2.\n//\n// Vertex displacement stays analytic (matching PlanetMaterial), since vertex\n// texture fetch is unreliable on mobile and the vertex stage is a tiny\n// fraction of the per-pixel cost this removes.\n// ============================================================================\n\nconst BAKE_VERTEX = /* glsl */ `\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = vec4(position.xy, 0.0, 1.0); // fullscreen clip-space quad\n}\n`;\n\nconst buildBakeFragment = (heightGLSL) => /* glsl */ `\nprecision highp float;\n\n${COMMON_UNIFORMS_GLSL}\n${NOISE_GLSL}\n${BIOME_GLSL}\n${heightGLSL}\n\nvarying vec2 vUv;\nuniform vec4 uBakeUvTransform;\nuniform float uEps;\nuniform int uBakeSampleCount; // always 3; a uniform bound keeps ONE inlined heightAt\n\nvoid main() {\n vec2 bakeUv = uBakeUvTransform.xy + vUv * uBakeUvTransform.zw;\n vec2 xz = uBakeOrigin + bakeUv * max(uBakeSpan, vec2(1.0));\n float eps = uEps;\n // Same sample order and offsets as the live terrain fragment, so a texel\n // centre stores exactly the values the live path computes at that point.\n vec3 samples = vec3(0.0);\n for (int sampleIndex = 0; sampleIndex < uBakeSampleCount; sampleIndex++) {\n vec2 offset = sampleIndex == 1 ? vec2(eps, 0.0) : sampleIndex == 2 ? vec2(0.0, eps) : vec2(0.0);\n samples[sampleIndex] = heightAt(xz + offset);\n }\n float hC = samples.x;\n float hX = samples.y;\n float hZ = samples.z;\n vec3 nGeo = normalize(vec3(-(hX - hC) / eps, 1.0, -(hZ - hC) / eps));\n float curvature = ((hX + hZ) * 0.5 - hC) / eps;\n float h01 = hC / max(uHeightScale, 1e-3);\n // R,G = normal x,z (y implied, always positive), B = curvature, A = height.\n gl_FragColor = vec4(nGeo.x, nGeo.z, curvature, h01);\n}\n`;\n\n// Climate changes over hundreds of world units, so it does not need the\n// high-resolution height target. The four slowly varying fields (temperature,\n// moisture, continentalness, erosion) are baked in half float, exact at texel\n// centres; the medium-scale region jitter (~0.7 cycles per noise unit) is too\n// fine for this grid and stays live in the shaders that read the bake.\nconst BIOME_BAKE_FRAGMENT = /* glsl */ `\nprecision highp float;\n\n${COMMON_UNIFORMS_GLSL}\n${NOISE_GLSL}\n${BIOME_GLSL}\n\nvarying vec2 vUv;\nuniform vec4 uBakeUvTransform;\n\nvoid main() {\n vec2 bakeUv = uBakeUvTransform.xy + vUv * uBakeUvTransform.zw;\n vec2 xz = uBakeOrigin + bakeUv * max(uBakeSpan, vec2(1.0));\n Climate climate = climateAt(xz * uFrequency + uSeedOffset);\n gl_FragColor = vec4(\n climate.temp,\n climate.moist,\n climate.cont,\n climate.erosion\n );\n}\n`;\n\nexport class TerrainHeightBaker {\n /**\n * @param {object} opts\n * @param {THREE.WebGLRenderer} opts.renderer\n * @param {object} opts.uniforms shared terrain uniforms (live objects)\n * @param {number} [opts.size] per-cell texture resolution (default 2048)\n * @param {number} [opts.maxSize] multi-cell atlas cap (default 4096)\n */\n constructor({\n renderer,\n uniforms,\n size = 2048,\n maxSize = 4096,\n requirePrepared = false,\n }) {\n this.renderer = renderer;\n this.uniforms = uniforms;\n this._baseSize = size;\n this._maxSize = maxSize;\n this._requirePrepared = requirePrepared;\n this._texW = size;\n this._texH = size;\n this._biomeW = 512;\n this._biomeH = 512;\n this._activeJob = null;\n this._jobSerial = 0;\n this._bakeUvTransform = { value: new THREE.Vector4(0, 0, 1, 1) };\n\n // Double-buffer both outputs. Visible water samples `target` directly even\n // while uUseTerrainHeightTex is disabled, so progressive stripes must render\n // into a private back buffer and become visible only after both passes finish.\n this.target = this._makeTarget(size, size);\n this._writeTarget = this._makeTarget(size, size);\n this.biomeTarget = this._makeBiomeTarget(this._biomeW, this._biomeH);\n this._writeBiomeTarget = this._makeBiomeTarget(this._biomeW, this._biomeH);\n\n this.scene = new THREE.Scene();\n this.material = null; // built on first bake so OCTAVES matches the params\n this.biomeMaterial = new THREE.ShaderMaterial({\n uniforms: {\n ...this.uniforms,\n uBakeUvTransform: this._bakeUvTransform,\n },\n // NOISE_GLSL declares FBM helpers with an OCTAVES loop even though this\n // climate-only pass only calls vnoise(). Keep the unused helpers valid.\n defines: { OCTAVES: 1 },\n vertexShader: BAKE_VERTEX,\n fragmentShader: BIOME_BAKE_FRAGMENT,\n depthTest: false,\n depthWrite: false,\n });\n this.mesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2));\n this.mesh.frustumCulled = false;\n this.scene.add(this.mesh);\n this.cam = new THREE.Camera(); // identity — the quad is already in clip space\n\n this._octaves = -1;\n this._stackSig = null;\n this._programSerial = 0;\n this._biomeProgramPrepared = false;\n }\n\n get texture() { return this.target?.texture ?? null; }\n get biomeTexture() { return this.biomeTarget?.texture ?? null; }\n\n /**\n * Free every render target (front and back) while keeping the compiled bake\n * program. Used when Tile mode is left: the bake is board-local, so other\n * world modes should not pay its VRAM. The next begin() reallocates.\n */\n releaseTargets() {\n this.cancel();\n this.target?.dispose();\n this.biomeTarget?.dispose();\n this.target = null;\n this.biomeTarget = null;\n this._releaseWriteTargets();\n }\n\n /** World units covered by one texel of the published bake. */\n texelWorldSize(span) {\n const t = this.target ?? { width: this._texW, height: this._texH };\n return Math.max(\n (span?.x ?? 1) / Math.max(1, t.width),\n (span?.y ?? 1) / Math.max(1, t.height),\n );\n }\n\n // The back buffers only exist while a bake is in flight: they are released\n // right after the swap (the front pair stays published) and recreated on\n // the next bake, which halves the steady-state VRAM of the studio cache.\n _ensureWriteTargets() {\n if (!this._writeTarget) this._writeTarget = this._makeTarget(this._texW, this._texH);\n if (!this._writeBiomeTarget) this._writeBiomeTarget = this._makeBiomeTarget(this._biomeW, this._biomeH);\n }\n\n _releaseWriteTargets() {\n this._writeTarget?.dispose();\n this._writeBiomeTarget?.dispose();\n this._writeTarget = null;\n this._writeBiomeTarget = null;\n }\n\n _makeTarget(w, h, name = 'TerrainHeightNormalRGBA16F') {\n const target = new THREE.WebGLRenderTarget(w, h, {\n type: THREE.HalfFloatType,\n format: THREE.RGBAFormat,\n magFilter: THREE.LinearFilter,\n minFilter: THREE.LinearFilter,\n depthBuffer: false,\n generateMipmaps: false,\n });\n target.texture.colorSpace = THREE.NoColorSpace;\n target.texture.name = name;\n return target;\n }\n\n _makeBiomeTarget(w, h, name = 'TerrainBiomeClimate') {\n const target = new THREE.WebGLRenderTarget(w, h, {\n // half float: 8-bit climate quantized biome thresholds into visible steps\n type: THREE.HalfFloatType,\n format: THREE.RGBAFormat,\n magFilter: THREE.LinearFilter,\n minFilter: THREE.LinearFilter,\n depthBuffer: false,\n generateMipmaps: false,\n });\n target.texture.colorSpace = THREE.NoColorSpace;\n target.texture.name = name;\n return target;\n }\n\n /** Resize the bake target to cover a multi-cell union (cols × rows cells). */\n _ensureTargetSize(cols, rows) {\n const cap = Math.max(this._baseSize, this._maxSize || 4096);\n const w = Math.min(cap, this._baseSize * Math.max(1, cols));\n const h = Math.min(cap, this._baseSize * Math.max(1, rows));\n // Keep the published front target alive because visible water may still be\n // sampling it. Only resize the hidden target used by the pending bake.\n if (this._writeTarget && (this._writeTarget.width !== w || this._writeTarget.height !== h)) {\n this._writeTarget.dispose();\n this._writeTarget = null;\n }\n this._texW = w;\n this._texH = h;\n\n const maxCells = Math.max(1, cols, rows);\n const biomeW = Math.max(128, Math.round(512 * cols / maxCells));\n const biomeH = Math.max(128, Math.round(512 * rows / maxCells));\n if (this._writeBiomeTarget && (this._writeBiomeTarget.width !== biomeW\n || this._writeBiomeTarget.height !== biomeH)) {\n this._writeBiomeTarget.dispose();\n this._writeBiomeTarget = null;\n }\n this._biomeW = biomeW;\n this._biomeH = biomeH;\n this._ensureWriteTargets();\n\n }\n\n _makeProgramMaterial(octaves, stackGLSL) {\n return new THREE.ShaderMaterial({\n uniforms: {\n ...this.uniforms,\n uBakeUvTransform: this._bakeUvTransform,\n uBakeSampleCount: { value: 3 },\n },\n defines: { OCTAVES: octaves },\n vertexShader: BAKE_VERTEX,\n fragmentShader: buildBakeFragment(buildHeightGLSL(stackGLSL.body2d)),\n depthTest: false,\n depthWrite: false,\n });\n }\n\n _ensureMaterial(octaves, stackGLSL) {\n const programSig = stackGLSL.heightSig || stackGLSL.sig;\n if (this.material && this._octaves === octaves && this._stackSig === programSig) return;\n const next = this._makeProgramMaterial(octaves, stackGLSL);\n if (this.material) this.material.dispose();\n this.material = next;\n this.mesh.material = this.material;\n this._octaves = octaves;\n this._stackSig = programSig;\n this._programSerial++;\n }\n\n prepareProgram(octaves, stackGLSL = DEFAULT_STACK_GLSL, cols = 1, rows = 1) {\n this._ensureTargetSize(cols, rows);\n const serial = ++this._programSerial;\n const programSig = stackGLSL.heightSig || stackGLSL.sig;\n const current = !!this.material\n && this._octaves === octaves\n && this._stackSig === programSig\n && this._biomeProgramPrepared;\n if (current) return { serial, current: true, octaves, stackSig: programSig, passes: [] };\n const material = this._makeProgramMaterial(octaves, stackGLSL);\n return {\n serial, current: false, material, octaves, stackSig: programSig,\n passes: [\n { scene: this.scene, camera: this.cam, mesh: this.mesh, material, renderTarget: this._writeTarget },\n { scene: this.scene, camera: this.cam, mesh: this.mesh, material: this.biomeMaterial, renderTarget: this._writeBiomeTarget },\n ],\n };\n }\n\n publishPrepared(handle) {\n if (!handle || handle.serial !== this._programSerial) return false;\n if (handle.current) return true;\n const previous = this.material;\n this.material = handle.material;\n this.mesh.material = this.material;\n this._octaves = handle.octaves;\n this._stackSig = handle.stackSig;\n this._biomeProgramPrepared = true;\n handle.published = true;\n previous?.dispose();\n return true;\n }\n\n discardPrepared(handle) {\n if (handle?.material && !handle.published && handle.material !== this.material) {\n handle.material.dispose();\n }\n }\n\n get programKey() {\n return this.material ? this._octaves + ':' + this._stackSig : null;\n }\n /**\n * Start a progressive bake without submitting GPU work. Published front\n * textures remain unchanged until every height and climate stripe completes.\n */\n begin(octaves, stackGLSL = DEFAULT_STACK_GLSL, cols = 1, rows = 1) {\n const programSig = stackGLSL.heightSig || stackGLSL.sig;\n if (this._requirePrepared && (!this._biomeProgramPrepared\n || !this.material || this._octaves !== octaves || this._stackSig !== programSig)) {\n return null;\n }\n this._ensureTargetSize(cols, rows);\n this._ensureMaterial(octaves, stackGLSL);\n this._bakeUvTransform.value.set(0, 0, 1, 1);\n this._activeJob = {\n id: ++this._jobSerial,\n pass: 'height',\n row: 0,\n };\n return this._activeJob.id;\n }\n\n get isBaking() { return !!this._activeJob; }\n\n /**\n * Render at most maxRows from the current pass. A 1536px bake split into\n * 64-row stripes yields to the browser instead of issuing one long command.\n */\n step(maxRows = 64) {\n const job = this._activeJob;\n if (!job) return { complete: true, progress: 1 };\n\n const isHeight = job.pass === 'height';\n const width = isHeight ? this._texW : this._biomeW;\n const height = isHeight ? this._texH : this._biomeH;\n const target = isHeight ? this._writeTarget : this._writeBiomeTarget;\n const material = isHeight ? this.material : this.biomeMaterial;\n const rows = Math.min(Math.max(1, Math.round(maxRows)), height - job.row);\n this._renderStripe(target, material, width, height, job.row, rows);\n job.row += rows;\n\n if (job.row >= height) {\n if (isHeight) {\n job.pass = 'biome';\n job.row = 0;\n } else {\n this._activeJob = null;\n this._bakeUvTransform.value.set(0, 0, 1, 1);\n // Publish the complete height and climate pair in one frame. The\n // caller repoints every sampler at the new front pair immediately, so\n // the previous pair can be released now.\n [this.target, this._writeTarget] = [this._writeTarget, this.target];\n [this.biomeTarget, this._writeBiomeTarget] =\n [this._writeBiomeTarget, this.biomeTarget];\n this._releaseWriteTargets();\n return { complete: true, progress: 1 };\n }\n }\n\n const heightShare = 0.85;\n const progress = job.pass === 'height'\n ? heightShare * (job.row / this._texH)\n : heightShare + (1 - heightShare) * (job.row / this._biomeH);\n return { complete: false, progress, pass: job.pass };\n }\n\n _renderStripe(target, material, width, height, row, rows) {\n const r = this.renderer;\n const prevTarget = r.getRenderTarget();\n this.mesh.material = material;\n this._bakeUvTransform.value.set(0, row / height, 1, rows / height);\n try {\n // Render-target rectangles use physical texels. Renderer.setViewport /\n // setScissor scale their arguments by the canvas pixel ratio, which\n // shifts and stretches bake stripes on HiDPI screens. Binding the target\n // applies its rectangles directly and leaves the canvas state untouched.\n target.viewport.set(0, row, width, rows);\n target.scissor.set(0, row, width, rows);\n target.scissorTest = true;\n r.setRenderTarget(target);\n r.render(this.scene, this.cam);\n } finally {\n r.setRenderTarget(prevTarget);\n this.mesh.material = this.material;\n }\n }\n\n /**\n * Render the published height program once over a whole small `target`,\n * with a caller uv transform (same convention as the stripes). One sample\n * per texel: only A (height / heightScale) is meaningful. Consumers that\n * must follow edits in the very frame they happen (the Mini light map) use\n * it for a coarse vertex-aligned grid instead of waiting for the\n * progressive full bake. Reuses the compiled program; never compiles.\n */\n renderHeightGrid(target, uvTransform) {\n const material = this.material;\n if (!material || !target) return false;\n const r = this.renderer;\n const prevTarget = r.getRenderTarget();\n const prevTransform = this._bakeUvTransform.value.clone();\n const count = material.uniforms.uBakeSampleCount;\n const prevCount = count.value;\n this.mesh.material = material;\n this._bakeUvTransform.value.copy(uvTransform);\n count.value = 1;\n try {\n target.viewport.set(0, 0, target.width, target.height);\n target.scissorTest = false;\n r.setRenderTarget(target);\n r.render(this.scene, this.cam);\n } finally {\n r.setRenderTarget(prevTarget);\n this._bakeUvTransform.value.copy(prevTransform);\n count.value = prevCount;\n }\n return true;\n }\n\n /** Synchronous compatibility path used by exports and focused tests. */\n bake(octaves, stackGLSL = DEFAULT_STACK_GLSL, cols = 1, rows = 1) {\n this.begin(octaves, stackGLSL, cols, rows);\n while (this._activeJob) this.step(Number.MAX_SAFE_INTEGER);\n }\n\n cancel() {\n this._activeJob = null;\n this._bakeUvTransform.value.set(0, 0, 1, 1);\n }\n\n dispose() {\n this.target?.dispose();\n this._writeTarget?.dispose();\n this.biomeTarget?.dispose();\n this._writeBiomeTarget?.dispose();\n this.mesh.geometry.dispose();\n if (this.material) this.material.dispose();\n this.biomeMaterial.dispose();\n this.material = null;\n this._activeJob = null;\n }\n}\n","import { TerrainHeightBaker } from '../../engine/terrain/TerrainHeightBaker.js';\nimport { compileMaterial } from '../resources/CompileMaterial.js';\nimport { withRendererState } from '../resources/RendererState.js';\n\n/** Optional finite GPU cache. Reuses the studio's double-buffered bake path. */\nexport class TerrainHeightCache {\n constructor({ terrain, resolution = 512, attach = true }) {\n if (terrain.mode !== 'finite') throw new TypeError('Height cache requires finite terrain');\n if (!Number.isInteger(resolution) || resolution < 16 || resolution > 2048)\n throw new RangeError('Cache resolution must be 16..2048');\n this.terrain = terrain;\n this.serial = 0;\n this.disposed = false;\n this.baker = new TerrainHeightBaker({\n renderer: terrain._renderer,\n uniforms: terrain._uniforms,\n size: resolution,\n maxSize: 2048,\n requirePrepared: true,\n });\n this._detach = attach ? terrain.addLayer(this) : () => {};\n }\n async prepare(camera, { signal } = {}) {\n if (this.disposed) throw new Error('Height cache disposed');\n this.terrain._assertAlive();\n const serial = ++this.serial,\n t = this.terrain,\n revision = t._revision,\n b = this.baker,\n h = b.prepareProgram(t.configuration.source.octaves, t._stackGLSL);\n try {\n for (const p of h.passes)\n await compileMaterial(t._renderer, p.material, p.camera, {\n geometry: p.mesh.geometry.clone(),\n });\n signal?.throwIfAborted();\n t._assertAlive();\n if (this.disposed || serial !== this.serial || revision !== t._revision)\n throw Object.assign(new Error('Height cache superseded'), { code: 'TERRAIN_SUPERSEDED' });\n if (!b.publishPrepared(h)) throw new Error('Height cache program superseded');\n withRendererState(t._renderer, () => b.bake(t.configuration.source.octaves, t._stackGLSL));\n const u = t._uniforms;\n u.uTerrainHeightTex.value = b.texture;\n u.uTerrainBiomeTex.value = b.biomeTexture;\n u.uUseTerrainHeightTex.value = 1;\n u.uUseTerrainBiomeTex.value = 1;\n u.uWaterTerrainHeightTex.value = b.texture;\n u.uWaterTerrainBiomeTex.value = b.biomeTexture;\n u.uUseWaterTerrainBiomeTex.value = 1;\n u.uBakeTexelWorld.value =\n (t.configuration.layout.chunkCount * t.configuration.layout.chunkSize) / b.target.width;\n } catch (error) {\n b.discardPrepared(h);\n throw error;\n }\n }\n onTerrainChanged(options) {\n if (options?.sourceChanged === false) return;\n return this.prepare(this.terrain._viewCamera, options);\n }\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n ++this.serial;\n this._detach();\n const u = this.terrain._uniforms;\n if (u.uTerrainHeightTex.value === this.baker.texture) {\n u.uUseTerrainHeightTex.value = 0;\n u.uUseTerrainBiomeTex.value = 0;\n u.uUseWaterTerrainBiomeTex.value = 0;\n u.uTerrainHeightTex.value = null;\n u.uTerrainBiomeTex.value = null;\n u.uWaterTerrainHeightTex.value = null;\n u.uWaterTerrainBiomeTex.value = null;\n }\n this.baker.dispose();\n }\n}\nexport function createHeightCache(options) {\n return new TerrainHeightCache(options);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TerrainHeightCache-DIZxi9jz.js","sources":["../../../src/engine/terrain/TerrainHeightBaker.js","../../../src/runtime/effects/TerrainHeightCache.js"],"sourcesContent":["import * as THREE from 'three';\nimport { COMMON_UNIFORMS_GLSL, NOISE_GLSL, buildHeightGLSL } from './terrainGLSL.js';\nimport { BIOME_GLSL } from './biomeGLSL.js';\nimport { generateStackGLSL } from './noise/noiseStackCodegen.js';\nimport { defaultLegacyStack } from './noise/NoiseStack.js';\n\nconst DEFAULT_STACK_GLSL = generateStackGLSL(defaultLegacyStack());\n\n// ============================================================================\n// Studio (flat board) height/normal baker — the 2D analog of\n// PlanetHeightBaker. The studio terrain + water fragment shaders re-evaluate\n// the full ~46-octave height field FOR EVERY PIXEL, EVERY FRAME (the terrain\n// fragment does it three times to build the analytic normal). Whenever the\n// camera orbits or the player walks, that per-pixel cost — not the triangle\n// count — is what drops the framerate on weak GPUs.\n//\n// This baker evaluates the field once into a 2D texture whenever it actually\n// changes (seed / shape / biome / paint edits, tracked by the engine's terrain\n// generation counter). Packed representation (RGBA16F, signed):\n// R,G = geometric surface normal x,z (y is positive and implied)\n// B = curvature ((hX + hZ) / 2 - hC) / eps (concavity AO / ridge accent)\n// A = height / heightScale\n// Baking the exact finite-difference normal keeps terrain lighting identical to\n// the live field. Reconstructing it later from a filtered height-only texture\n// visibly flattened the terrain and moved material/shore signals.\n//\n// The board spans world XZ in [-uBoardHalf, uBoardHalf]; the bake maps the\n// fullscreen quad UV straight onto that range, so a later fetch by world XZ\n// (uv = (xz - uBakeOrigin) / uBakeSpan) lines up automatically. Half-float keeps\n// h01 precise and is linearly filterable in WebGL2.\n//\n// Vertex displacement stays analytic (matching PlanetMaterial), since vertex\n// texture fetch is unreliable on mobile and the vertex stage is a tiny\n// fraction of the per-pixel cost this removes.\n// ============================================================================\n\nconst BAKE_VERTEX = /* glsl */ `\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = vec4(position.xy, 0.0, 1.0); // fullscreen clip-space quad\n}\n`;\n\nconst buildBakeFragment = (heightGLSL) => /* glsl */ `\nprecision highp float;\n\n${COMMON_UNIFORMS_GLSL}\n${NOISE_GLSL}\n${BIOME_GLSL}\n${heightGLSL}\n\nvarying vec2 vUv;\nuniform vec4 uBakeUvTransform;\nuniform float uEps;\nuniform int uBakeSampleCount; // always 3; a uniform bound keeps ONE inlined heightAt\n\nvoid main() {\n vec2 bakeUv = uBakeUvTransform.xy + vUv * uBakeUvTransform.zw;\n vec2 xz = uBakeOrigin + bakeUv * max(uBakeSpan, vec2(1.0));\n float eps = uEps;\n // Same sample order and offsets as the live terrain fragment, so a texel\n // centre stores exactly the values the live path computes at that point.\n vec3 samples = vec3(0.0);\n for (int sampleIndex = 0; sampleIndex < uBakeSampleCount; sampleIndex++) {\n vec2 offset = sampleIndex == 1 ? vec2(eps, 0.0) : sampleIndex == 2 ? vec2(0.0, eps) : vec2(0.0);\n samples[sampleIndex] = heightAt(xz + offset);\n }\n float hC = samples.x;\n float hX = samples.y;\n float hZ = samples.z;\n vec3 nGeo = normalize(vec3(-(hX - hC) / eps, 1.0, -(hZ - hC) / eps));\n float curvature = ((hX + hZ) * 0.5 - hC) / eps;\n float h01 = hC / max(uHeightScale, 1e-3);\n // R,G = normal x,z (y implied, always positive), B = curvature, A = height.\n gl_FragColor = vec4(nGeo.x, nGeo.z, curvature, h01);\n}\n`;\n\n// Climate changes over hundreds of world units, so it does not need the\n// high-resolution height target. The four slowly varying fields (temperature,\n// moisture, continentalness, erosion) are baked in half float, exact at texel\n// centres; the medium-scale region jitter (~0.7 cycles per noise unit) is too\n// fine for this grid and stays live in the shaders that read the bake.\nconst BIOME_BAKE_FRAGMENT = /* glsl */ `\nprecision highp float;\n\n${COMMON_UNIFORMS_GLSL}\n${NOISE_GLSL}\n${BIOME_GLSL}\n\nvarying vec2 vUv;\nuniform vec4 uBakeUvTransform;\n\nvoid main() {\n vec2 bakeUv = uBakeUvTransform.xy + vUv * uBakeUvTransform.zw;\n vec2 xz = uBakeOrigin + bakeUv * max(uBakeSpan, vec2(1.0));\n Climate climate = climateAt(xz * uFrequency + uSeedOffset);\n gl_FragColor = vec4(\n climate.temp,\n climate.moist,\n climate.cont,\n climate.erosion\n );\n}\n`;\n\nexport class TerrainHeightBaker {\n /**\n * @param {object} opts\n * @param {THREE.WebGLRenderer} opts.renderer\n * @param {object} opts.uniforms shared terrain uniforms (live objects)\n * @param {number} [opts.size] per-cell texture resolution (default 2048)\n * @param {number} [opts.maxSize] multi-cell atlas cap (default 4096)\n */\n constructor({\n renderer,\n uniforms,\n size = 2048,\n maxSize = 4096,\n requirePrepared = false,\n }) {\n this.renderer = renderer;\n this.uniforms = uniforms;\n this._baseSize = size;\n this._maxSize = maxSize;\n this._requirePrepared = requirePrepared;\n this._texW = size;\n this._texH = size;\n this._biomeW = 512;\n this._biomeH = 512;\n this._activeJob = null;\n this._jobSerial = 0;\n this._bakeUvTransform = { value: new THREE.Vector4(0, 0, 1, 1) };\n\n // Double-buffer both outputs. Visible water samples `target` directly even\n // while uUseTerrainHeightTex is disabled, so progressive stripes must render\n // into a private back buffer and become visible only after both passes finish.\n this.target = this._makeTarget(size, size);\n this._writeTarget = this._makeTarget(size, size);\n this.biomeTarget = this._makeBiomeTarget(this._biomeW, this._biomeH);\n this._writeBiomeTarget = this._makeBiomeTarget(this._biomeW, this._biomeH);\n\n this.scene = new THREE.Scene();\n this.material = null; // built on first bake so OCTAVES matches the params\n this.biomeMaterial = new THREE.ShaderMaterial({\n uniforms: {\n ...this.uniforms,\n uBakeUvTransform: this._bakeUvTransform,\n },\n // NOISE_GLSL declares FBM helpers with an OCTAVES loop even though this\n // climate-only pass only calls vnoise(). Keep the unused helpers valid.\n defines: { OCTAVES: 1 },\n vertexShader: BAKE_VERTEX,\n fragmentShader: BIOME_BAKE_FRAGMENT,\n depthTest: false,\n depthWrite: false,\n });\n this.mesh = new THREE.Mesh(new THREE.PlaneGeometry(2, 2));\n this.mesh.frustumCulled = false;\n this.scene.add(this.mesh);\n this.cam = new THREE.Camera(); // identity — the quad is already in clip space\n\n this._octaves = -1;\n this._stackSig = null;\n this._programSerial = 0;\n this._biomeProgramPrepared = false;\n }\n\n get texture() { return this.target?.texture ?? null; }\n get biomeTexture() { return this.biomeTarget?.texture ?? null; }\n\n /**\n * Free every render target (front and back) while keeping the compiled bake\n * program. Used when Tile mode is left: the bake is board-local, so other\n * world modes should not pay its VRAM. The next begin() reallocates.\n */\n releaseTargets() {\n this.cancel();\n this.target?.dispose();\n this.biomeTarget?.dispose();\n this.target = null;\n this.biomeTarget = null;\n this._releaseWriteTargets();\n }\n\n /** World units covered by one texel of the published bake. */\n texelWorldSize(span) {\n const t = this.target ?? { width: this._texW, height: this._texH };\n return Math.max(\n (span?.x ?? 1) / Math.max(1, t.width),\n (span?.y ?? 1) / Math.max(1, t.height),\n );\n }\n\n // The back buffers only exist while a bake is in flight: they are released\n // right after the swap (the front pair stays published) and recreated on\n // the next bake, which halves the steady-state VRAM of the studio cache.\n _ensureWriteTargets() {\n if (!this._writeTarget) this._writeTarget = this._makeTarget(this._texW, this._texH);\n if (!this._writeBiomeTarget) this._writeBiomeTarget = this._makeBiomeTarget(this._biomeW, this._biomeH);\n }\n\n _releaseWriteTargets() {\n this._writeTarget?.dispose();\n this._writeBiomeTarget?.dispose();\n this._writeTarget = null;\n this._writeBiomeTarget = null;\n }\n\n _makeTarget(w, h, name = 'TerrainHeightNormalRGBA16F') {\n const target = new THREE.WebGLRenderTarget(w, h, {\n type: THREE.HalfFloatType,\n format: THREE.RGBAFormat,\n magFilter: THREE.LinearFilter,\n minFilter: THREE.LinearFilter,\n depthBuffer: false,\n generateMipmaps: false,\n });\n target.texture.colorSpace = THREE.NoColorSpace;\n target.texture.name = name;\n return target;\n }\n\n _makeBiomeTarget(w, h, name = 'TerrainBiomeClimate') {\n const target = new THREE.WebGLRenderTarget(w, h, {\n // half float: 8-bit climate quantized biome thresholds into visible steps\n type: THREE.HalfFloatType,\n format: THREE.RGBAFormat,\n magFilter: THREE.LinearFilter,\n minFilter: THREE.LinearFilter,\n depthBuffer: false,\n generateMipmaps: false,\n });\n target.texture.colorSpace = THREE.NoColorSpace;\n target.texture.name = name;\n return target;\n }\n\n /** Resize the bake target to cover a multi-cell union (cols × rows cells). */\n _ensureTargetSize(cols, rows) {\n const cap = Math.max(this._baseSize, this._maxSize || 4096);\n const w = Math.min(cap, this._baseSize * Math.max(1, cols));\n const h = Math.min(cap, this._baseSize * Math.max(1, rows));\n // Keep the published front target alive because visible water may still be\n // sampling it. Only resize the hidden target used by the pending bake.\n if (this._writeTarget && (this._writeTarget.width !== w || this._writeTarget.height !== h)) {\n this._writeTarget.dispose();\n this._writeTarget = null;\n }\n this._texW = w;\n this._texH = h;\n\n const maxCells = Math.max(1, cols, rows);\n const biomeW = Math.max(128, Math.round(512 * cols / maxCells));\n const biomeH = Math.max(128, Math.round(512 * rows / maxCells));\n if (this._writeBiomeTarget && (this._writeBiomeTarget.width !== biomeW\n || this._writeBiomeTarget.height !== biomeH)) {\n this._writeBiomeTarget.dispose();\n this._writeBiomeTarget = null;\n }\n this._biomeW = biomeW;\n this._biomeH = biomeH;\n this._ensureWriteTargets();\n\n }\n\n _makeProgramMaterial(octaves, stackGLSL) {\n return new THREE.ShaderMaterial({\n uniforms: {\n ...this.uniforms,\n uBakeUvTransform: this._bakeUvTransform,\n uBakeSampleCount: { value: 3 },\n },\n defines: { OCTAVES: octaves },\n vertexShader: BAKE_VERTEX,\n fragmentShader: buildBakeFragment(buildHeightGLSL(stackGLSL.body2d)),\n depthTest: false,\n depthWrite: false,\n });\n }\n\n _ensureMaterial(octaves, stackGLSL) {\n const programSig = stackGLSL.heightSig || stackGLSL.sig;\n if (this.material && this._octaves === octaves && this._stackSig === programSig) return;\n const next = this._makeProgramMaterial(octaves, stackGLSL);\n if (this.material) this.material.dispose();\n this.material = next;\n this.mesh.material = this.material;\n this._octaves = octaves;\n this._stackSig = programSig;\n this._programSerial++;\n }\n\n prepareProgram(octaves, stackGLSL = DEFAULT_STACK_GLSL, cols = 1, rows = 1) {\n this._ensureTargetSize(cols, rows);\n const serial = ++this._programSerial;\n const programSig = stackGLSL.heightSig || stackGLSL.sig;\n const current = !!this.material\n && this._octaves === octaves\n && this._stackSig === programSig\n && this._biomeProgramPrepared;\n if (current) return { serial, current: true, octaves, stackSig: programSig, passes: [] };\n const material = this._makeProgramMaterial(octaves, stackGLSL);\n return {\n serial, current: false, material, octaves, stackSig: programSig,\n passes: [\n { scene: this.scene, camera: this.cam, mesh: this.mesh, material, renderTarget: this._writeTarget },\n { scene: this.scene, camera: this.cam, mesh: this.mesh, material: this.biomeMaterial, renderTarget: this._writeBiomeTarget },\n ],\n };\n }\n\n publishPrepared(handle) {\n if (!handle || handle.serial !== this._programSerial) return false;\n if (handle.current) return true;\n const previous = this.material;\n this.material = handle.material;\n this.mesh.material = this.material;\n this._octaves = handle.octaves;\n this._stackSig = handle.stackSig;\n this._biomeProgramPrepared = true;\n handle.published = true;\n previous?.dispose();\n return true;\n }\n\n discardPrepared(handle) {\n if (handle?.material && !handle.published && handle.material !== this.material) {\n handle.material.dispose();\n }\n }\n\n get programKey() {\n return this.material ? this._octaves + ':' + this._stackSig : null;\n }\n /**\n * Start a progressive bake without submitting GPU work. Published front\n * textures remain unchanged until every height and climate stripe completes.\n */\n begin(octaves, stackGLSL = DEFAULT_STACK_GLSL, cols = 1, rows = 1) {\n const programSig = stackGLSL.heightSig || stackGLSL.sig;\n if (this._requirePrepared && (!this._biomeProgramPrepared\n || !this.material || this._octaves !== octaves || this._stackSig !== programSig)) {\n return null;\n }\n this._ensureTargetSize(cols, rows);\n this._ensureMaterial(octaves, stackGLSL);\n this._bakeUvTransform.value.set(0, 0, 1, 1);\n this._activeJob = {\n id: ++this._jobSerial,\n pass: 'height',\n row: 0,\n };\n return this._activeJob.id;\n }\n\n get isBaking() { return !!this._activeJob; }\n\n /**\n * Render at most maxRows from the current pass. A 1536px bake split into\n * 64-row stripes yields to the browser instead of issuing one long command.\n */\n step(maxRows = 64) {\n const job = this._activeJob;\n if (!job) return { complete: true, progress: 1 };\n\n const isHeight = job.pass === 'height';\n const width = isHeight ? this._texW : this._biomeW;\n const height = isHeight ? this._texH : this._biomeH;\n const target = isHeight ? this._writeTarget : this._writeBiomeTarget;\n const material = isHeight ? this.material : this.biomeMaterial;\n const rows = Math.min(Math.max(1, Math.round(maxRows)), height - job.row);\n this._renderStripe(target, material, width, height, job.row, rows);\n job.row += rows;\n\n if (job.row >= height) {\n if (isHeight) {\n job.pass = 'biome';\n job.row = 0;\n } else {\n this._activeJob = null;\n this._bakeUvTransform.value.set(0, 0, 1, 1);\n // Publish the complete height and climate pair in one frame. The\n // caller repoints every sampler at the new front pair immediately, so\n // the previous pair can be released now.\n [this.target, this._writeTarget] = [this._writeTarget, this.target];\n [this.biomeTarget, this._writeBiomeTarget] =\n [this._writeBiomeTarget, this.biomeTarget];\n this._releaseWriteTargets();\n return { complete: true, progress: 1 };\n }\n }\n\n const heightShare = 0.85;\n const progress = job.pass === 'height'\n ? heightShare * (job.row / this._texH)\n : heightShare + (1 - heightShare) * (job.row / this._biomeH);\n return { complete: false, progress, pass: job.pass };\n }\n\n _renderStripe(target, material, width, height, row, rows) {\n const r = this.renderer;\n const prevTarget = r.getRenderTarget();\n this.mesh.material = material;\n this._bakeUvTransform.value.set(0, row / height, 1, rows / height);\n try {\n // Render-target rectangles use physical texels. Renderer.setViewport /\n // setScissor scale their arguments by the canvas pixel ratio, which\n // shifts and stretches bake stripes on HiDPI screens. Binding the target\n // applies its rectangles directly and leaves the canvas state untouched.\n target.viewport.set(0, row, width, rows);\n target.scissor.set(0, row, width, rows);\n target.scissorTest = true;\n r.setRenderTarget(target);\n r.render(this.scene, this.cam);\n } finally {\n r.setRenderTarget(prevTarget);\n this.mesh.material = this.material;\n }\n }\n\n /**\n * Render the published height program once over a whole small `target`,\n * with a caller uv transform (same convention as the stripes). One sample\n * per texel: only A (height / heightScale) is meaningful. Consumers that\n * must follow edits in the very frame they happen (the Mini light map) use\n * it for a coarse vertex-aligned grid instead of waiting for the\n * progressive full bake. Reuses the compiled program; never compiles.\n */\n renderHeightGrid(target, uvTransform) {\n const material = this.material;\n if (!material || !target) return false;\n const r = this.renderer;\n const prevTarget = r.getRenderTarget();\n const prevTransform = this._bakeUvTransform.value.clone();\n const count = material.uniforms.uBakeSampleCount;\n const prevCount = count.value;\n this.mesh.material = material;\n this._bakeUvTransform.value.copy(uvTransform);\n count.value = 1;\n try {\n target.viewport.set(0, 0, target.width, target.height);\n target.scissorTest = false;\n r.setRenderTarget(target);\n r.render(this.scene, this.cam);\n } finally {\n r.setRenderTarget(prevTarget);\n this._bakeUvTransform.value.copy(prevTransform);\n count.value = prevCount;\n }\n return true;\n }\n\n /** Synchronous compatibility path used by exports and focused tests. */\n bake(octaves, stackGLSL = DEFAULT_STACK_GLSL, cols = 1, rows = 1) {\n this.begin(octaves, stackGLSL, cols, rows);\n while (this._activeJob) this.step(Number.MAX_SAFE_INTEGER);\n }\n\n cancel() {\n this._activeJob = null;\n this._bakeUvTransform.value.set(0, 0, 1, 1);\n }\n\n dispose() {\n this.target?.dispose();\n this._writeTarget?.dispose();\n this.biomeTarget?.dispose();\n this._writeBiomeTarget?.dispose();\n this.mesh.geometry.dispose();\n if (this.material) this.material.dispose();\n this.biomeMaterial.dispose();\n this.material = null;\n this._activeJob = null;\n }\n}\n","import { TerrainHeightBaker } from '../../engine/terrain/TerrainHeightBaker.js';\nimport { compileMaterial } from '../resources/CompileMaterial.js';\nimport { withRendererState } from '../resources/RendererState.js';\n\n/** Optional finite GPU cache. Reuses the studio's double-buffered bake path. */\nexport class TerrainHeightCache {\n constructor({ terrain, resolution = 512, attach = true }) {\n if (terrain.mode !== 'finite') throw new TypeError('Height cache requires finite terrain');\n if (!Number.isInteger(resolution) || resolution < 16 || resolution > 2048)\n throw new RangeError('Cache resolution must be 16..2048');\n this.terrain = terrain;\n this.serial = 0;\n this.disposed = false;\n this.baker = new TerrainHeightBaker({\n renderer: terrain._renderer,\n uniforms: terrain._uniforms,\n size: resolution,\n maxSize: 2048,\n requirePrepared: true,\n });\n this._detach = attach ? terrain.addLayer(this) : () => {};\n }\n async prepare(camera, { signal } = {}) {\n if (this.disposed) throw new Error('Height cache disposed');\n this.terrain._assertAlive();\n const serial = ++this.serial,\n t = this.terrain,\n revision = t._revision,\n b = this.baker,\n h = b.prepareProgram(t.configuration.source.octaves, t._stackGLSL);\n try {\n for (const p of h.passes)\n await compileMaterial(t._renderer, p.material, p.camera, {\n geometry: p.mesh.geometry.clone(),\n });\n signal?.throwIfAborted();\n t._assertAlive();\n if (this.disposed || serial !== this.serial || revision !== t._revision)\n throw Object.assign(new Error('Height cache superseded'), { code: 'TERRAIN_SUPERSEDED' });\n if (!b.publishPrepared(h)) throw new Error('Height cache program superseded');\n withRendererState(t._renderer, () => b.bake(t.configuration.source.octaves, t._stackGLSL));\n const u = t._uniforms;\n u.uTerrainHeightTex.value = b.texture;\n u.uTerrainBiomeTex.value = b.biomeTexture;\n u.uUseTerrainHeightTex.value = 1;\n u.uUseTerrainBiomeTex.value = 1;\n u.uWaterTerrainHeightTex.value = b.texture;\n u.uWaterTerrainBiomeTex.value = b.biomeTexture;\n u.uUseWaterTerrainBiomeTex.value = 1;\n u.uBakeTexelWorld.value =\n (t.configuration.layout.chunkCount * t.configuration.layout.chunkSize) / b.target.width;\n } catch (error) {\n b.discardPrepared(h);\n throw error;\n }\n }\n onTerrainChanged(options) {\n if (options?.sourceChanged === false) return;\n return this.prepare(this.terrain._viewCamera, options);\n }\n dispose() {\n if (this.disposed) return;\n this.disposed = true;\n ++this.serial;\n this._detach();\n const u = this.terrain._uniforms;\n if (u.uTerrainHeightTex.value === this.baker.texture) {\n u.uUseTerrainHeightTex.value = 0;\n u.uUseTerrainBiomeTex.value = 0;\n u.uUseWaterTerrainBiomeTex.value = 0;\n u.uTerrainHeightTex.value = null;\n u.uTerrainBiomeTex.value = null;\n u.uWaterTerrainHeightTex.value = null;\n u.uWaterTerrainBiomeTex.value = null;\n }\n this.baker.dispose();\n }\n}\nexport function createHeightCache(options) {\n return new TerrainHeightCache(options);\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import * as THREE from "three";
2
2
  import { i as installSurfaceMaterialBackend, M as MINI_BEVEL_GLSL, P as PALETTE_UNIFORMS_GLSL, T as TERRAIN_COLOR_FUNCTIONS_GLSL, S as SURFACE_TEXTURE_UNIFORMS_GLSL, a as SURFACE_TEXTURE_FUNCTIONS_GLSL, n as normalizeTerrainSource } from "./TerrainSources-Bye63rDk.js";
3
- import { C as COMMON_UNIFORMS_GLSL, b as buildHeightGLSL, M as MANUAL_SURFACE_WEIGHTS_GLSL, f as fitNearBake, N as NOISE_GLSL, B as BIOME_GLSL, g as TERRAIN_HEIGHT_TEX_GLSL, c as NEAR_BAKE_BLOCK, h as CLIMATE_CACHE_BLOCK, i as TERRAIN_CLIMATE_CACHE_GLSL, j as INFINITE_CLIMATE_GLSL, e as IMPORTED_IMAGERY_ALBEDO_GLSL, I as INFINITE_FIELD_CACHE_GLSL } from "./biomeGLSL-CIkhxIlH.js";
3
+ import { C as COMMON_UNIFORMS_GLSL, b as buildHeightGLSL, M as MANUAL_SURFACE_WEIGHTS_GLSL, f as fitNearBake, N as NOISE_GLSL, B as BIOME_GLSL, g as TERRAIN_HEIGHT_TEX_GLSL, c as NEAR_BAKE_BLOCK, h as CLIMATE_CACHE_BLOCK, i as TERRAIN_CLIMATE_CACHE_GLSL, j as INFINITE_CLIMATE_GLSL, e as IMPORTED_IMAGERY_ALBEDO_GLSL, I as INFINITE_FIELD_CACHE_GLSL } from "./biomeGLSL-DWGDDBqT.js";
4
4
  import { g as generateStackGLSL, d as defaultLegacyStack, M as MAX_LAYERS } from "./noiseStackCodegen-C4R9Y3L8.js";
5
5
  import { a as SURFACE_TEXTURE_ROWS, b as SURFACE_TEXTURE_ROLE_COUNT } from "./SurfaceTextureRoles-tRGhAZXG.js";
6
6
  import { D as DEFAULT_PARAMS, S as STYLE_DEFAULTS, M as MATERIAL_DEFAULTS, e as MATERIAL_FIELDS } from "./ProgramHealthGate-DS47bUo1.js";
@@ -125,16 +125,18 @@ vec3 cl_formationPoint(vec3 p) {
125
125
  }
126
126
 
127
127
  float cl_formationBase(vec3 p, float base) {
128
+ float result = base;
128
129
  if (uCloudNoiseType > 1.5) {
129
130
  float fibers = cl_vnoise(p * vec3(0.65, 2.4, 1.6) + 19.7);
130
- return base - 0.10 * smoothstep(0.25, 0.75, fibers);
131
- }
132
- if (uCloudNoiseType > 0.5) {
133
- // Fold smooth value noise into rounded billows with fuller centres.
131
+ // Keep coverage centred on the common field; wisps stay thin through
132
+ // their vertical profile and opacity rather than losing the whole layer.
133
+ result = base + 0.04 - 0.08 * smoothstep(0.25, 0.75, fibers);
134
+ } else if (uCloudNoiseType > 0.5) {
135
+ // One initialized return value avoids ANGLE/FXC's branch-return warning.
134
136
  float billows = 0.67 - abs(cl_vnoise(p * 1.5 + 13.7) - 0.5) * 1.4;
135
- return mix(base, billows, 0.65);
137
+ result = mix(base, billows, 0.65);
136
138
  }
137
- return base;
139
+ return result;
138
140
  }
139
141
  `
140
142
  );
@@ -3370,4 +3372,4 @@ export {
3370
3372
  REALISTIC_MAX_STEPS as p,
3371
3373
  renderTerrainCloudShadow as r
3372
3374
  };
3373
- //# sourceMappingURL=TerrainParameters-A3fcNJTR.js.map
3375
+ //# sourceMappingURL=TerrainParameters-DMCjnnxz.js.map