kits/skies.json, materials.json, foliage.json and rocks.json; the same data as JSON is in
kits/worlds.json. Paths are relative to ~/code/assets. Re-run node tools/kits/build-worlds.mjs after a kit changes.../assets/kits/worlds.json
(worlds[i].sky for setEnv, terrain.a/b for buildTerrain layers with tiles = SIZE / repeat_m,
foliage.set.layers and rocks.boulder_field / mountain_chunks for buildForest). Per-kit detail pages:
../assets/kits/skies.html, materials.html, foliage.html, rocks.html.
#a7aca1 · exposure 0.85 · skyIntensity 0.163 · envMul 0.14 · skyFade [-0.02, 0.06][0.804, 0.059, 0.591] (az/el [126.3, 3.4]) · foreground clear 1hdri/polyhaven-aarfontein_pan/aarfontein_pan_2k.hdr

#a2aca7
#7fabf1
#91adc6

by:'slope', lo 0.35, hi 0.6 · tint a 0xfff0d8, b 0xffe6c8Dunes are gentle: lower lo/hi so rock only shows on real scarps. Pale sand is bright (L 0.73): exposure down a touch.
Photoscanned cacti (lite) as spires, Poly Haven dead quiver trunks, low-poly yuccas and sansevieria, Namaqualand flowers near the camera. · ~2.6M tris
| layer | count | collide | models (height m) |
|---|---|---|---|
| spires | 80 | yes | ferocactus-acanthodes-lite.glb (6), pipe-organ-cactus__8rSaubjT4uM__poly-by-google__cc-by.glb (7), Cactus_2.glb (5) |
| hero | 12 | yes | dead_quiver_trunk.gltf (4) |
| understory | 150 | large-yucca__flCC5m8pPS.glb (3), sansevieria-plant__2zmROipXIE.glb (1.2), ferocactus-wislizeni-lite.glb (1.2), dead_quiver_branch_01.glb (0.5) | |
| near-flowers | 40 | flower_gazania.glb (0.25), flower_ursinia.glb (0.25), crystalline_iceplant.gltf (0.2) |
warm scans, no tint needed; [1.05,0.98,0.9] matches the canyon HDRI
solidified Poly Haven cliff scans: closed, so they sink and yaw without holes, but only the scan side is photographic. buildForest yaws at random: place walls in overlapping runs along the rim (sample()) so neighbours hide each other's darker synthetic backs, and keep them >= 150 m from the flight line. tint = red-canyon values; swap with tint_by_world
{"sandstone":[1.12,1.02,0.88],"limestone":[1.2,1.02,0.82],"granite":[1.15,1,0.85]}kits/worlds.json → dune-desert){
"sky": {
"hdri": "hdri/polyhaven-aarfontein_pan/aarfontein_pan_2k.hdr",
"fog_hex": "#a7aca1",
"exposure": 0.85,
"skyIntensity": 0.163,
"envMul": 0.14,
"skyFade": [
-0.02,
0.06
],
"sunDir": [
0.8043,
0.0585,
0.5914
]
},
"terrain": {
"a": {
"folder": "textures/ground/ambientcg-Ground093B",
"files": {
"map": "Ground093B_2K-JPG_Color.jpg",
"normalMap": "Ground093B_2K-JPG_NormalGL.jpg",
"roughnessMap": "Ground093B_2K-JPG_Roughness.jpg"
}
},
"b": {
"folder": "textures/rock/polyhaven-worn_rock_natural_01",
"files": {
"map": "worn_rock_natural_01_diff_2k.jpg",
"normalMap": "worn_rock_natural_01_nor_gl_2k.jpg",
"roughnessMap": "worn_rock_natural_01_rough_2k.jpg"
}
},
"a_repeat_m": 10,
"b_repeat_m": 14,
"by": "slope",
"lo": 0.35,
"hi": 0.6,
"invert": false
},
"water": null,
"foliage_set": "desert-succulents",
"rock_set": "desert-sandstone"
}
#97acc4 · exposure 0.72 · skyIntensity 0.506 · envMul 0.463 · skyFade [-0.06, -0.008][0.674, 0.551, 0.492] (az/el [126.1, 33.5]) · foreground clear 0.9hdri/polyhaven-drakensberg_solitary_mountain/drakensberg_solitary_mountain_2k.hdr

#a4abaf
#a2abb5
#93aebe

by:'slope', lo 0.45, hi 0.7 · tint a 0xffffff, b 0xffe0cc (warmer strata)cliff_side has horizontal strata: map UVs world-XZ as terrain.js does, strata then run sideways on walls (fine at 12 m).
Photoscanned cacti (lite) as spires, Poly Haven dead quiver trunks, low-poly yuccas and sansevieria, Namaqualand flowers near the camera. · ~2.6M tris
| layer | count | collide | models (height m) |
|---|---|---|---|
| spires | 80 | yes | ferocactus-acanthodes-lite.glb (6), pipe-organ-cactus__8rSaubjT4uM__poly-by-google__cc-by.glb (7), Cactus_2.glb (5) |
| hero | 12 | yes | dead_quiver_trunk.gltf (4) |
| understory | 150 | large-yucca__flCC5m8pPS.glb (3), sansevieria-plant__2zmROipXIE.glb (1.2), ferocactus-wislizeni-lite.glb (1.2), dead_quiver_branch_01.glb (0.5) | |
| near-flowers | 40 | flower_gazania.glb (0.25), flower_ursinia.glb (0.25), crystalline_iceplant.gltf (0.2) |
warm scans, no tint needed; [1.05,0.98,0.9] matches the canyon HDRI
solidified Poly Haven cliff scans: closed, so they sink and yaw without holes, but only the scan side is photographic. buildForest yaws at random: place walls in overlapping runs along the rim (sample()) so neighbours hide each other's darker synthetic backs, and keep them >= 150 m from the flight line. tint = red-canyon values; swap with tint_by_world
{"sandstone":[1.05,0.98,0.9],"limestone":[1.1,0.92,0.78],"granite":[1.08,0.95,0.84]}kits/worlds.json → red-canyon){
"sky": {
"hdri": "hdri/polyhaven-drakensberg_solitary_mountain/drakensberg_solitary_mountain_2k.hdr",
"fog_hex": "#97acc4",
"exposure": 0.72,
"skyIntensity": 0.506,
"envMul": 0.463,
"skyFade": [
-0.06,
-0.008
],
"sunDir": [
0.6741,
0.5513,
0.4916
]
},
"terrain": {
"a": {
"folder": "textures/ground/polyhaven-red_sand",
"files": {
"map": "red_sand_diff_2k.jpg",
"normalMap": "red_sand_nor_gl_2k.jpg",
"roughnessMap": "red_sand_rough_2k.jpg"
}
},
"b": {
"folder": "textures/rock/polyhaven-cliff_side",
"files": {
"map": "cliff_side_diff_2k.jpg",
"normalMap": "cliff_side_nor_gl_2k.jpg",
"roughnessMap": "cliff_side_rough_2k.jpg"
}
},
"a_repeat_m": 8,
"b_repeat_m": 12,
"by": "slope",
"lo": 0.45,
"hi": 0.7,
"invert": false
},
"water": null,
"foliage_set": "desert-succulents",
"rock_set": "desert-sandstone"
}
#b2a994 · exposure 0.85 · skyIntensity 0.361 · envMul 0.867 · skyFade [-0.02, 0.1][0.998, 0.041, -0.039] (az/el [87.8, 2.4]) · foreground clear 1hdri/ambientcg-EveningSkyHDRI030B/EveningSkyHDRI030B_2k.hdr

#c5a384
#d09d97

by:'height', lo -5, hi 5, invert · tint a 0xd8d0c8, emissive 0xff6a2a, emissiveIntensity 2.5Lava must be layer B (terrain.js only emits on B). by height + invert = lava in the low ground; set lo/hi to the lava level +-5 m.
Bone-white and charred dead forest on lava: EZ-Tree dead tree, Quaternius dead trees, Space Kit lava trees, photoscan trunks and roots (lite). · ~2.3M tris
| layer | count | collide | models (height m) |
|---|---|---|---|
| canopy | 300 | yes | eztree-alien-dead-1.glb (22), CommonTree_Dead_1.glb (14), Willow_Dead_2.glb (12), Tree_Lava_1.glb (30) |
| debris | 40 | dead_tree_trunk-lite.glb (2), root_cluster_02-lite.glb (3), pine_roots-lite.glb (2) |
multiply tints darken and cool the scans; vesicular ShareTextures stones become scoria
solidified Poly Haven cliff scans: closed, so they sink and yaw without holes, but only the scan side is photographic. buildForest yaws at random: place walls in overlapping runs along the rim (sample()) so neighbours hide each other's darker synthetic backs, and keep them >= 150 m from the flight line. tint = red-canyon values; swap with tint_by_world
{"sandstone":[0.3,0.27,0.27],"limestone":[0.34,0.3,0.3],"granite":[0.32,0.29,0.29]}kits/worlds.json → volcanic){
"sky": {
"hdri": "hdri/ambientcg-EveningSkyHDRI030B/EveningSkyHDRI030B_2k.hdr",
"fog_hex": "#b2a994",
"exposure": 0.85,
"skyIntensity": 0.361,
"envMul": 0.867,
"skyFade": [
-0.02,
0.1
],
"sunDir": [
0.9984,
0.0414,
-0.0391
]
},
"terrain": {
"a": {
"folder": "textures/rock/polyhaven-dark_rock_02",
"files": {
"map": "dark_rock_02_diff_2k.jpg",
"normalMap": "dark_rock_02_nor_gl_2k.jpg",
"roughnessMap": "dark_rock_02_rough_2k.jpg"
}
},
"b": {
"folder": "textures/ground/ambientcg-Lava001",
"files": {
"map": "Lava001_2K-JPG_Color.jpg",
"normalMap": "Lava001_2K-JPG_NormalGL.jpg",
"roughnessMap": "Lava001_2K-JPG_Roughness.jpg",
"emissiveMap": "Lava001_2K-JPG_Emission.jpg"
}
},
"a_repeat_m": 12,
"b_repeat_m": 20,
"by": "height",
"lo": -5,
"hi": 5,
"invert": true
},
"water": null,
"foliage_set": "volcanic-dead",
"rock_set": "volcanic-basalt"
}
#a9aaaa · exposure 0.9 · skyIntensity 0.503 · envMul 0.159 · skyFade [-0.02, 0.06][0.758, 0.155, 0.633] (az/el [129.9, 8.9]) · foreground clear 0.95hdri/polyhaven-snow_field_2/snow_field_2_2k.hdr

#afa9a1
#84addd
#92accd

by:'slope', lo 0.5, hi 0.75 · tint a new THREE.Color(1.15, 1.17, 1.22) (reads white from altitude, as Hoth), b 0xdfe6eeFor snow on top of rock by altitude instead: a = rock, b = snow, by height.
EZ-Tree pines near, Quaternius snow pines far. · ~2.6M tris
| layer | count | collide | models (height m) |
|---|---|---|---|
| canopy | 60 | yes | eztree-pine-1.glb (20), eztree-pine-2.glb (30) |
| far | 700 | yes | PineTree_Snow_1.glb (18), PineTree_Snow_2.glb (22), PineTree_Snow_3.glb (20) |
tints above 1 lift and cool the scans so they do not read as black silhouettes on snow (same as the current Hoth set)
solidified Poly Haven cliff scans: closed, so they sink and yaw without holes, but only the scan side is photographic. buildForest yaws at random: place walls in overlapping runs along the rim (sample()) so neighbours hide each other's darker synthetic backs, and keep them >= 150 m from the flight line. tint = red-canyon values; swap with tint_by_world
{"sandstone":[1.2,1.25,1.4],"limestone":[1.2,1.25,1.38],"granite":[1.2,1.25,1.4]}kits/worlds.json → ice-world){
"sky": {
"hdri": "hdri/polyhaven-snow_field_2/snow_field_2_2k.hdr",
"fog_hex": "#a9aaaa",
"exposure": 0.9,
"skyIntensity": 0.503,
"envMul": 0.159,
"skyFade": [
-0.02,
0.06
],
"sunDir": [
0.7582,
0.1555,
0.6332
]
},
"terrain": {
"a": {
"folder": "textures/ground/polyhaven-snow_01",
"files": {
"map": "snow_01_diff_2k.jpg",
"normalMap": "snow_01_nor_gl_2k.jpg",
"roughnessMap": "snow_01_rough_2k.jpg"
}
},
"b": {
"folder": "textures/rock/ambientcg-Rock017",
"files": {
"map": "Rock017_2K-JPG_Color.jpg",
"normalMap": "Rock017_2K-JPG_NormalGL.jpg",
"roughnessMap": "Rock017_2K-JPG_Roughness.jpg"
}
},
"a_repeat_m": 8,
"b_repeat_m": 16,
"by": "slope",
"lo": 0.5,
"hi": 0.75,
"invert": false
},
"water": null,
"foliage_set": "alpine",
"rock_set": "ice-polished-granite"
}
#aaa9aa · exposure 0.9 · skyIntensity 0.329 · envMul 0.107 · skyFade [-0.02, 0.1][0.863, 0.477, -0.165] (az/el [79.2, 28.5]) · foreground clear 1hdri/polyhaven-kloofendal_28d_misty_puresky/kloofendal_28d_misty_puresky_2k.hdr

#aaa9ad
#a4aaba

by:'slope', lo 0.45, hi 0.7 · tint a 0xe8f0d8 (less yellow), b 0xffffffFrom the air a jungle floor is mostly hidden by trees; spend the texture budget on the cliffs.

0x1d3b2eDense jungle canopy for the Yavin flight band (200-500 m). A roof of overlapping 64 m crown tiles lifted to ~30 m, 14 m impostor crowns rising through it, and real 3D EZ-Tree crown clusters only where the camera comes low (temple ring, trail edges). Counts are for buildForest area 3200 (a 6.4 km square, 41 km2) at full density; per_km2 is given per layer. Keep every layer out of the speeder trail corridor and the temple clearing (keepOut). Optional far layer: canopy-roof-a-256m.glb planes (or the tex/canopy-roof-a maps on a terrain mesh offset +30 m) under the fog. · ~2.5M tris
| layer | count | collide | models (height m) |
|---|---|---|---|
| roof | 14350 | canopy-tile-64-a.glb (3.58), canopy-tile-64-b.glb (2.97), canopy-tile-64-c.glb (3.17) | |
| emergent-crowns | 8200 | canopy-crown-green.glb (34), canopy-crown-olive.glb (34), canopy-crown-dark.glb (34), canopy-crown-flowering.glb (34) | |
| near-clusters | 120 | yes | canopy-cluster-7-a.glb (30), canopy-cluster-9-dense.glb (22), canopy-cluster-emergent.glb (40) |
Other sets that fit: jungle-realistic, palm-pbr, alien-jungle, temperate-realistic
moss is in the albedo: no tint; keep them small and half-buried among the photo trees
kits/worlds.json → jungle){
"sky": {
"hdri": "hdri/polyhaven-kloofendal_28d_misty_puresky/kloofendal_28d_misty_puresky_2k.hdr",
"fog_hex": "#aaa9aa",
"exposure": 0.9,
"skyIntensity": 0.329,
"envMul": 0.107,
"skyFade": [
-0.02,
0.1
],
"sunDir": [
0.8631,
0.4772,
-0.1653
]
},
"terrain": {
"a": {
"folder": "textures/ground/ambientcg-Ground037",
"files": {
"map": "Ground037_2K-JPG_Color.jpg",
"normalMap": "Ground037_2K-JPG_NormalGL.jpg",
"roughnessMap": "Ground037_2K-JPG_Roughness.jpg"
}
},
"b": {
"folder": "textures/rock/polyhaven-mossy_rock",
"files": {
"map": "mossy_rock_diff_2k.jpg",
"normalMap": "mossy_rock_nor_gl_2k.jpg",
"roughnessMap": "mossy_rock_rough_2k.jpg"
}
},
"a_repeat_m": 6,
"b_repeat_m": 10,
"by": "slope",
"lo": 0.45,
"hi": 0.7,
"invert": false
},
"water": {
"recipe": "Water.js",
"normals": "textures/water/generated-water-calm/water-calm_normal_gl.jpg",
"size_m": 12,
"waterColor": "0x1d3b2e"
},
"foliage_set": "canopy-from-above",
"rock_set": "mossy-jungle"
}
#a3aab8 · exposure 0.85 · skyIntensity 0.574 · envMul 0.109 · skyFade [-0.02, 0.1][0.502, 0.744, 0.442] (az/el [131.4, 48]) · foreground clear 1hdri/polyhaven-aristea_wreck_puresky/aristea_wreck_puresky_2k.hdr

#9bacbe
#99acbb

by:'slope', lo 0.45, hi 0.7 · tint a 0xfff6e6, b new THREE.Color(1.2, 1.15, 1.1) (seaside_rock is dark, L 0.25)coast_sand_01 is an aerial scan (15 m real): best from flight altitude. Put the water plane just above the sand/rock transition.

0x0e3a3c

Smithsonian coral scans (lite, 20k tris) scaled 100-400x into a dry-seabed forest; CC-BY kelp as tall fronds. · ~2.3M tris
| layer | count | collide | models (height m) |
|---|---|---|---|
| canopy | 60 | yes | acropora-cervicornis-lite.glb (45), madrepora-hyacinthus-lite.glb (35), paragorgia-arborea-lite.glb (50), stylaster-sanguineus-lite.glb (30) |
| understory | 25 | yes | diploria-labyrinthiformis-lite.glb (12), fungia-crassa-lite.glb (10) |
| fronds | 300 | kelp__4cFllH6Iazk__poly-by-google__cc-by.glb (20), kelp__3VhttTFyADO__christopher-f__cc-by.glb (15) |
Other sets that fit: jungle-realistic, palm-pbr
moss is in the albedo: no tint; keep them small and half-buried among the photo trees
kits/worlds.json → coral-coast){
"sky": {
"hdri": "hdri/polyhaven-aristea_wreck_puresky/aristea_wreck_puresky_2k.hdr",
"fog_hex": "#a3aab8",
"exposure": 0.85,
"skyIntensity": 0.574,
"envMul": 0.109,
"skyFade": [
-0.02,
0.1
],
"sunDir": [
0.5018,
0.7437,
0.4417
]
},
"terrain": {
"a": {
"folder": "textures/ground/polyhaven-coast_sand_01",
"files": {
"map": "coast_sand_01_diff_2k.jpg",
"normalMap": "coast_sand_01_nor_gl_2k.jpg",
"roughnessMap": "coast_sand_01_rough_2k.jpg"
}
},
"b": {
"folder": "textures/rock/polyhaven-seaside_rock",
"files": {
"map": "seaside_rock_diff_2k.jpg",
"normalMap": "seaside_rock_nor_gl_2k.jpg",
"roughnessMap": "seaside_rock_rough_2k.jpg"
}
},
"a_repeat_m": 30,
"b_repeat_m": 10,
"by": "slope",
"lo": 0.45,
"hi": 0.7,
"invert": false
},
"water": {
"recipe": "Water.js",
"normals": "textures/water/generated-water-choppy/water-choppy_normal_gl.jpg",
"size_m": 30,
"waterColor": "0x0e3a3c",
"caustics": "textures/water/generated-water-caustics/water-caustics.jpg",
"foam": "textures/water/generated-water-foam/water-foam.jpg"
},
"foliage_set": "alien-reef-forest",
"rock_set": "mossy-jungle"
}
#a6aba7 · exposure 0.85 · skyIntensity 1.7 · envMul 0.517 · skyFade [-0.02, 0.1][-0.484, 0.658, 0.577] (az/el [220, 41.1]) · foreground clear 1hdri/ambientcg-DaySkyHDRI068B/DaySkyHDRI068B_2k.hdr

#a9a9af
#a8aba2

by:'slope', lo 0.45, hi 0.7
0x0b3d14Weeping trees, Quaternius willows, lily pads and photoscan roots. · ~2.6M tris
| layer | count | collide | models (height m) |
|---|---|---|---|
| canopy | 40 | yes | eztree-alien-weeping-1.glb (22) |
| mid | 600 | yes | Willow_1.glb (12), Willow_3.glb (11), Willow_Dead_1.glb (10) |
| water | 500 | Lilypad.glb (1.2), single_root-lite.glb (1.5) |
Other sets that fit: mushroom-glow
moss is in the albedo: no tint; keep them small and half-buried among the photo trees
kits/worlds.json → toxic-swamp){
"sky": {
"hdri": "hdri/ambientcg-DaySkyHDRI068B/DaySkyHDRI068B_2k.hdr",
"fog_hex": "#a6aba7",
"exposure": 0.85,
"skyIntensity": 1.7,
"envMul": 0.517,
"skyFade": [
-0.02,
0.1
],
"sunDir": [
-0.4843,
0.6578,
0.5769
]
},
"terrain": {
"a": {
"folder": "textures/ground/polyhaven-mud_forest",
"files": {
"map": "mud_forest_diff_2k.jpg",
"normalMap": "mud_forest_nor_gl_2k.jpg",
"roughnessMap": "mud_forest_rough_2k.jpg"
}
},
"b": {
"folder": "textures/rock/ambientcg-Rock059",
"files": {
"map": "Rock059_2K-JPG_Color.jpg",
"normalMap": "Rock059_2K-JPG_NormalGL.jpg",
"roughnessMap": "Rock059_2K-JPG_Roughness.jpg"
}
},
"a_repeat_m": 4.7,
"b_repeat_m": 8,
"by": "slope",
"lo": 0.45,
"hi": 0.7,
"invert": false
},
"water": {
"recipe": "Water.js",
"normals": "textures/water/generated-water-viscous/water-viscous_normal_gl.jpg",
"size_m": 45,
"waterColor": "0x0b3d14"
},
"foliage_set": "swamp",
"rock_set": "mossy-jungle"
}
#43454d · exposure 1 · skyIntensity 1.431 · envMul 0.771 · skyFade [-0.02, 0.1][0.809, 0.588, 0] (az/el [90, 36]) · foreground clear 1hdri/ambientcg-NightSkyHDRI006/NightSkyHDRI006_2k.hdr

#c79fa9
#b8a69e

by:'slope', lo 0.4, hi 0.65 · tint a 0xffffff, b 0xb8a8ff (purple obsidian)Onyx013 is a polished-stone set (1k, flat normal): raise roughness via material.roughness multiply if it looks wet.
Low-poly crystals and Space Kit spike trees as a mineral forest. · ~1.2M tris
| layer | count | collide | models (height m) |
|---|---|---|---|
| spires | 250 | yes | big-crystal__pf5lzmgr2J.glb (30), crystal__3saqXqoOti.glb (20), Tree_Spikes_1.glb (40) |
| groundcover | 1500 | crystal__dxCmHfpqc5.glb (3), sansevieria-plant__V1yPemXoOW.glb (4) |
Other sets that fit: mushroom-glow, alien-jungle
multiply tints darken and cool the scans; vesicular ShareTextures stones become scoria
solidified Poly Haven cliff scans: closed, so they sink and yaw without holes, but only the scan side is photographic. buildForest yaws at random: place walls in overlapping runs along the rim (sample()) so neighbours hide each other's darker synthetic backs, and keep them >= 150 m from the flight line. tint = red-canyon values; swap with tint_by_world
kits/worlds.json → alien-crystal){
"sky": {
"hdri": "hdri/ambientcg-NightSkyHDRI006/NightSkyHDRI006_2k.hdr",
"fog_hex": "#43454d",
"exposure": 1,
"skyIntensity": 1.431,
"envMul": 0.771,
"skyFade": [
-0.02,
0.1
],
"sunDir": [
0.809,
0.5878,
-0.0002
]
},
"terrain": {
"a": {
"folder": "textures/alien/texturecan-red-crystal-ground",
"files": {
"map": "red-crystal-ground_color_2k.jpg",
"normalMap": "red-crystal-ground_normal_gl_2k.jpg",
"roughnessMap": "red-crystal-ground_roughness_2k.jpg"
}
},
"b": {
"folder": "textures/alien/ambientcg-Onyx013",
"files": {
"map": "Onyx013_1K-JPG_Color.jpg",
"normalMap": "Onyx013_1K-JPG_NormalGL.jpg",
"roughnessMap": "Onyx013_1K-JPG_Roughness.jpg"
}
},
"a_repeat_m": 5,
"b_repeat_m": 14,
"by": "slope",
"lo": 0.4,
"hi": 0.65,
"invert": false
},
"water": null,
"foliage_set": "crystal-garden",
"rock_set": "volcanic-basalt"
}
#42454e · exposure 1 · skyIntensity 1.268 · envMul 1.088 · skyFade [-0.02, 0.1][0.629, 0.772, -0.086] (az/el [82.2, 50.6]) · foreground clear 1hdri/ambientcg-NightSkyHDRI009/NightSkyHDRI009_2k.hdr

#41464c
#2a4158

by:'slope', lo 0.4, hi 0.7 · tint a 0xe6e6e6, b 0xd0d0d0 (desaturate)Moon regolith has high macro variation: keep anti-tile on and repeat >= 10 m.
multiply tints cannot desaturate, so the field uses near-grey scans only (moon rocks, OGA rock 2, rock_6, rock-14); for asteroids sink 0 and rotate freely
solidified Poly Haven cliff scans: closed, so they sink and yaw without holes, but only the scan side is photographic. buildForest yaws at random: place walls in overlapping runs along the rim (sample()) so neighbours hide each other's darker synthetic backs, and keep them >= 150 m from the flight line. tint = red-canyon values; swap with tint_by_world
{"sandstone":[0.82,0.84,0.88],"limestone":[0.9,0.9,0.92],"granite":[0.9,0.9,0.92]}kits/worlds.json → moon){
"sky": {
"hdri": "hdri/ambientcg-NightSkyHDRI009/NightSkyHDRI009_2k.hdr",
"fog_hex": "#42454e",
"exposure": 1,
"skyIntensity": 1.268,
"envMul": 1.088,
"skyFade": [
-0.02,
0.1
],
"sunDir": [
0.6291,
0.7725,
-0.0861
]
},
"terrain": {
"a": {
"folder": "textures/ground/polyhaven-moon_01",
"files": {
"map": "moon_01_diff_2k.jpg",
"normalMap": "moon_01_nor_gl_2k.jpg",
"roughnessMap": "moon_01_rough_2k.jpg"
}
},
"b": {
"folder": "textures/rock/polyhaven-marble_cliff_05",
"files": {
"map": "marble_cliff_05_diff_2k.jpg",
"normalMap": "marble_cliff_05_nor_gl_2k.jpg",
"roughnessMap": "marble_cliff_05_rough_2k.jpg"
}
},
"a_repeat_m": 10,
"b_repeat_m": 40,
"by": "slope",
"lo": 0.4,
"hi": 0.7,
"invert": false
},
"water": null,
"rock_set": "moon"
}
#42454e · exposure 1 · skyIntensity 1.268 · envMul 1.088 · skyFade [-0.02, 0.1][0.629, 0.772, -0.086] (az/el [82.2, 50.6]) · foreground clear 1hdri/ambientcg-NightSkyHDRI009/NightSkyHDRI009_2k.hdr

#41464c
#2a4158multiply tints cannot desaturate, so the field uses near-grey scans only (moon rocks, OGA rock 2, rock_6, rock-14); for asteroids sink 0 and rotate freely
Death Star (dark grey)




Star Destroyer (light grey)





kits/worlds.json → space){
"sky": {
"hdri": "hdri/ambientcg-NightSkyHDRI009/NightSkyHDRI009_2k.hdr",
"fog_hex": "#42454e",
"exposure": 1,
"skyIntensity": 1.268,
"envMul": 1.088,
"skyFade": [
-0.02,
0.1
],
"sunDir": [
0.6291,
0.7725,
-0.0861
]
},
"terrain": null,
"water": null,
"rock_set": "moon"
}Generated 2026-09-14 06:39 by tools/kits/build-worlds.mjs.