Realistic Atmosphere

このチュートリアルで学べること:
- 大気遠近法(Aerial Perspective)エフェクトの追加
- 空・太陽・星のDescriptor設定
- 雲エフェクトの追加
- トーンマッピングの設定
- 雨・雪エフェクトの追加
- 地形のウォーターマスクによる水面表現
大気遠近法エフェクトを追加する
Section titled “大気遠近法エフェクトを追加する”大気遠近法(Aerial Perspective)は、距離に応じた空気感・霞の効果を付与します。DefaultPlugin を登録しておくと、addDefaultPhotorealScene() がフォトリアルなシーンを一括で構築します。 空・太陽光・星・環境光・大気エフェクト・トーンマッピング・アンチエイリアシングまで含めてです。
import ThreeView from "@navaramap/three";import { DefaultPlugin, type DefaultDescriptions } from "@navaramap/three-default-plugin";
const plugin = new DefaultPlugin();const view = new ThreeView<DefaultDescriptions>({ shadow: true });view.addPlugin(plugin);await view.init();
const layers = plugin.addDefaultPhotorealScene();
layers.aerialPerspective.update({ aerialPerspective: { irradiance: true, },});
view.lit = false;
const photoSource = view.addSource({ // Credit: // - Geospatial Information Authority of Japan Tiles - Latest Nationwide Photo (Seamless) // https://maps.gsi.go.jp/development/ichiran.html type: "raster-tile", url: "https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg", maxZoom: 18,});view.addLayer({ type: "raster", source: photoSource,});
const terrainSource = view.addSource({ type: "quantized-mesh", url: "https://terrain.reearth.land/cesium-mesh/ellipsoid/{z}/{x}/{y}.terrain", requestVertexNormals: true, requestWaterMask: true, maxZoom: 18,});view.addLayer({ type: "terrain", source: terrainSource, terrain: { castShadow: true, receiveShadow: true, },});
// 朝の斜光が雲を側面から照らすため、雲が平坦な白い塊ではなく立体として見えます。view.atmosphere.date = new Date("2026-06-22T08:00:00+09:00");
// 雲頂より上から。雲の広がり全体が街の上に並びます。view.setCamera({ lng: 139.7511, lat: 35.6736, height: 4200, heading: -100, pitch: -22, roll: 0 });影を落とすには太陽光を更新します。
layers.sun.update({ sun: { castShadow: true } });このチュートリアルのスクリーンショットに写っている影は雲影です。太陽のシャドウマップは描画され続けますが view.lit = false の間は適用されないため、他に必要がなければ castShadow はオフにしてください。
トーンマッピングを設定する
Section titled “トーンマッピングを設定する”HDR らしい自然な見た目にするためにトーンマッピングの露出を設定します。このシーンは irradiance による大気からのライティングでフォワードライティングのシーンより明るく出るため、通常のシーンが 10 前後になるのに対して 6 程度に落ち着きます。
view.toneMappingExposure = 6;雲エフェクトを追加する
Section titled “雲エフェクトを追加する”qualityPreset: "high" で雲のディテールを高め、lightShafts: true で雲を透過する光芒を加えます。そこから影や密度を調整してください。
const clouds = view.addEffect<CloudsEffectDesc>({ clouds: { qualityPreset: "high", lightShafts: true, },});
clouds.update({ clouds: { shadows: true } });
雨エフェクトを追加する
Section titled “雨エフェクトを追加する”雨の表現には2つのオブジェクトを組み合わせて使用します。RainMeshDesc はシーン内に3D雨粒パーティクルを描画し、RainDropEffectDesc は画面に水滴が付着するポストエフェクトを提供します。
3D雨粒パーティクル
Section titled “3D雨粒パーティクル”// アニメーションループを回し、雨が常に動くようにするview.animation = true;
const rain = view.addMesh<RainMeshDesc>({ rain: { particleCount: 5000, speed: 0.0015, opacity: 1.0, width: 3, // m height: 60.0, // m areaWidth: 500, // m areaHeight: 1000, // m maxHeight: 10000, // m。雪セクションの注記を参照 },});
view.setCamera({ lng: 139.7511, lat: 35.6736, height: 700, heading: -100, pitch: 3, roll: 0 });画面水滴エフェクト
Section titled “画面水滴エフェクト”dropSizeFactor と dropGridSize は水滴の半径ではなく水滴グリッドの細かさを決める値です。そのため値を小さくすると水滴は大きくなります。水滴を大きくすると画面が寂しくなるので、dropDensity を上げて補います。
const rainDropEffect = view.addEffect<RainDropEffectDesc>({ rainDrop: { opacity: 0.8, dropGridSize: 12, dropDensity: 0.7, dropSizeFactor: 0.018, },});
雪エフェクトを追加する
Section titled “雪エフェクトを追加する”雨オブジェクトを消して、代わりに SnowMeshDesc を追加します。
const snow = view.addMesh<SnowMeshDesc>({ snow: { particleCount: 10000, speed: 0.00005, size: 20, opacity: 1, areaWidth: 400, areaHeight: 800, maxHeight: 3000, movementStrength: { x: 50, y: 20, z: 50 }, movementSpeed: { x: 0.0005, y: 0.0002, z: 0.0005 }, },});
水面を追加する(地形のウォーターマスク)
Section titled “水面を追加する(地形のウォーターマスク)”Cesium quantized-mesh タイルは、メッシュと一緒にウォーターマスクを持つことができます。ソースに requestWaterMask: true を指定すると、マスクされたピクセルが水面としてシェーディングされます。太陽のグレアを受け、環境マップや SSR の反射も乗る、反射率が高くラフネスの低い面になります。追加のソースやレイヤーは不要です。
const terrainSource = view.addSource({ type: "quantized-mesh", url: "https://terrain.reearth.land/cesium-mesh/ellipsoid/{z}/{x}/{y}.terrain", requestVertexNormals: true, requestWaterMask: true, maxZoom: 18,});view.addLayer({ type: "terrain", source: terrainSource, terrain: { castShadow: true, receiveShadow: true },});
view.atmosphere.date = new Date("2026-01-01T16:15:00+09:00");view.toneMappingExposure = 12;
view.setCamera({ lng: 139.88, lat: 35.42, height: 2800, heading: 250, pitch: -16, roll: 0 });
SSR(スクリーンスペース反射)との組み合わせ
Section titled “SSR(スクリーンスペース反射)との組み合わせ”SSREffectDesc を追加すると、建物などの反射がリアルタイムで水面に映り込みます。
const plateauSource = view.addSource({ // Credit: // - 3D City Model (Project PLATEAU) Chuo Ward (FY2023) - MLIT PLATEAU // https://www.geospatial.jp/ckan/dataset/plateau-13102-chuo-ku-2023 type: "3d-tiles", url: "https://assets.cms.plateau.reearth.io/assets/4c/f2436a-e2be-40e2-83da-f1781f36e30b/13102_chuo-ku_pref_2023_citygml_1_op_bldg_3dtiles_13102_chuo-ku_lod2_no_texture/tileset.json",});view.addLayer({ type: "3d-tiles", source: plateauSource, model: { show: true, color: new Color().setStyle("#ffffff"), metalness: 0, roughness: 0.5, castShadow: true, receiveShadow: true, },});
view.addEffect<SSREffectDesc>({ ssr: {},});
view.toneMappingExposure = 6;view.atmosphere.date = new Date("2026-06-22T08:00:00+09:00");
view.setCamera({ lng: 139.7868, lat: 35.6733, height: 68, heading: 240, pitch: -10, roll: 0,});
import ThreeView, { Color } from "@navaramap/three";import { type CloudsEffectDesc, type RainDropEffectDesc, type RainMeshDesc, type SnowMeshDesc, type SSREffectDesc, ToneMappingMode } from "@navaramap/three-default-descs";import { DefaultPlugin, type DefaultDescriptions } from "@navaramap/three-default-plugin";
const plugin = new DefaultPlugin();const view = new ThreeView<DefaultDescriptions>({ shadow: true, animation: true,});view.addPlugin(plugin);await view.init();
const layers = plugin.addDefaultPhotorealScene();
layers.aerialPerspective.update({ aerialPerspective: { irradiance: true, },});
view.lit = false;
const photoSource = view.addSource({ // Credit: // - Geospatial Information Authority of Japan Tiles - Latest Nationwide Photo (Seamless) // https://maps.gsi.go.jp/development/ichiran.html type: "raster-tile", url: "https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg", maxZoom: 18,});view.addLayer({ type: "raster", source: photoSource,});
const terrainSource = view.addSource({ type: "quantized-mesh", url: "https://terrain.reearth.land/cesium-mesh/ellipsoid/{z}/{x}/{y}.terrain", requestVertexNormals: true, requestWaterMask: true, maxZoom: 18,});view.addLayer({ type: "terrain", source: terrainSource, terrain: { castShadow: true, receiveShadow: true, },});
layers.sun.update({ sun: { castShadow: true } });
layers.toneMapping.update({ toneMapping: { mode: ToneMappingMode.AGX } });view.toneMappingExposure = 6;
const clouds = view.addEffect<CloudsEffectDesc>({ clouds: { qualityPreset: "high", lightShafts: true, },});
clouds.update({ clouds: { shadows: true } });
view.addMesh<RainMeshDesc>({ rain: { particleCount: 5000, speed: 0.0015, opacity: 1.0, width: 3, height: 60.0, areaWidth: 500, areaHeight: 1000, maxHeight: 10000, },});
view.addEffect<RainDropEffectDesc>({ rainDrop: { opacity: 0.8, dropGridSize: 12, dropDensity: 0.7, dropSizeFactor: 0.018, },});
const plateauSource = view.addSource({ // Credit: // - 3D City Model (Project PLATEAU) Chuo Ward (FY2023) - MLIT PLATEAU // https://www.geospatial.jp/ckan/dataset/plateau-13102-chuo-ku-2023 type: "3d-tiles", url: "https://assets.cms.plateau.reearth.io/assets/4c/f2436a-e2be-40e2-83da-f1781f36e30b/13102_chuo-ku_pref_2023_citygml_1_op_bldg_3dtiles_13102_chuo-ku_lod2_no_texture/tileset.json",});view.addLayer({ type: "3d-tiles", source: plateauSource, model: { show: true, color: new Color().setStyle("#ffffff"), metalness: 0, roughness: 0.5, castShadow: true, receiveShadow: true, },});
view.addEffect<SSREffectDesc>({ ssr: { },});
view.atmosphere.date = new Date("2026-01-01T16:15:00+09:00");view.toneMappingExposure = 12;
view.setCamera({ lng: 139.88, lat: 35.42, height: 2800, heading: 250, pitch: -16, roll: 0 });