mcpField
C
cesiumjs-materials-shaders

cesiumjs-materials-shaders

github.com/cesiumgs開発193217 回インストール6 週間前に更新
リポジトリ

cesiumjs-materials-shaders について

CesiumJSでマテリアル、シェーダー、ポストプロセス効果を作成する開発者向けのガイドです。Fabricマテリアル、カスタムシェーダー、イメージベース照明、スクリーンスペース処理を説明します。

主な機能

  1. 01Primitive向けFabricマテリアルの作成
  2. 02CustomShaderによるGLSLの挿入
  3. 03イメージベース照明の設定
  4. 04組み込みまたは独自のポストプロセス追加

活用シーン

  1. 01Primitiveの表面への模様やテクスチャ適用
  2. 02GLSLによるモデルやタイルセットの描画変更
  3. 03ブルーム、ぼかし、シルエット効果の追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cesiumgs/cesiumjs-skills --skill cesiumjs-materials-shaders

インストール後、Claude Code で/cesiumjs-materials-shadersを入力して読み込まれたか確認します。

詳細

CesiumJS のマテリアル、シェーダー、ポストプロセス

バージョンの基準:CesiumJS 1.144(2026 年 8 月)。すべてのインポートで ES モジュール形式を使用します。

マテリアルシステム(Fabric JSON)

Material は、Fabric と呼ばれる JSON スキーマを通じて プリミティブ の表面の外観を定義します。マテリアルは GLSL にコンパイルされ、MaterialAppearance または PolylineMaterialAppearance で使用されます。

マテリアルの画像の読み込み中、CesiumJS はプレースホルダーテクスチャを描画します。デフォルトでは白です。1.144 以降、静的な Texture.defaultColor を設定すると、マテリアルの構築中に白く点滅するのを防ぐため、プレースホルダーの色を変更できます。Texture クラスは実行時には公開されていますが、公開されている TypeScript 定義には含まれていないため、TypeScript の呼び出し側ではキャストが必要です。

組み込みのマテリアルタイプ

表面: Color(色)、Image(画像、繰り返し)、DiffuseMap、AlphaMap、SpecularMap、EmissionMap(画像、チャンネル、繰り返し)、BumpMap、NormalMap(画像、チャンネル、強度、繰り返し)。

パターン: Grid(色、セルのアルファ値、線の数、線の太さ)、Stripe(偶数色、奇数色、繰り返し)、Checkerboard(明色、暗色、繰り返し)、Dot(明色、暗色、繰り返し)。

エフェクト: Water(基本水色、ブレンド色、法線マップ、頻度、アニメーション速度、振幅)、RimLighting(色、リム色、幅)、Fade(フェードイン色、フェードアウト色、最大距離)。

地形: ElevationContour(色、間隔、幅)、ElevationRamp(画像、最小高度、最大高度)。

ポリライン: PolylineArrow(色)、PolylineDash(色、間隔の色、ダッシュの長さ、ダッシュパターン)、PolylineGlow(色、発光の強さ、テーパーの強さ)、PolylineOutline(色、アウトライン色、アウトライン幅)。

マテリアルの作成
import { Material, Color, Cartesian2 } from "cesium";

// Shorthand with fromType (preferred for built-in types)
const colorMat = Material.fromType("Color", { color: new Color(1.0, 0.0, 0.0, 0.5) });

// Full Fabric notation
const gridMat = new Material({
  fabric: {
    type: "Grid",
    uniforms: { color: Color.GREEN, cellAlpha: 0.1, lineCount: new Cartesian2(8, 8) },
  },
});

// Async loading -- awaits textures before first frame, no flicker
const imageMat = await Material.fromTypeAsync("Image", { image: "./textures/facade.png" });

Fabric マテリアルはプリミティブの外観に使用します。WaterMaterialProperty など、存在しないエンティティコンストラクターは使用しないでください。組み込みの水マテリアルを使うには、Material.fromType("Water", ...) を作成し、Primitive の MaterialAppearance に適用します。

GLSL ソースを使ったカスタム Fabric

インライン GLSL には source を使用します。uniforms で宣言したユニフォームは、シェーダー内で名前を指定して利用できます。

import { Material, Color } from "cesium";

const pulseMaterial = new Material({
  fabric: {
    uniforms: { color: Color.CYAN, speed: 2.0 },
    source: `czm_material czm_getMaterial(czm_materialInput materialInput) {
      czm_material material = czm_getDefaultMaterial(materialInput);
      float pulse = sin(czm_frameNumber * speed * 0.01) * 0.5 + 0.5;
      material.diffuse = color.rgb;
      material.alpha = color.a * pulse;
      return material;
    }`,
  },
  translucent: true,
});
プリミティブへのマテリアルの適用
import { Primitive, GeometryInstance, RectangleGeometry, Rectangle,
  MaterialAppearance, Material, Color, Cartesian2 } from "cesium";

viewer.scene.primitives.add(new Primitive({
  geometryInstances: new GeometryInstance({
    geometry: new RectangleGeometry({ rectangle: Rectangle.fromDegrees(-100, 30, -90, 40) }),
  }),
  appearance: new MaterialAppearance({
    material: Material.fromType("Checkerboard", {
      lightColor: Color.WHITE, darkColor: Color.BLACK, repeat: new Cartesian2(4, 4),
    }),
  }),
}));
サブマテリアルの合成(Fabric の materials + components)
import { Material, Color } from "cesium";

const compositeMat = new Material({ fabric: {
  materials: {
    gridMaterial: { type: "Grid" },
    colorMaterial: { type: "Color", uniforms: { color: Color.BLUE } },
  },
  components: {
    diffuse: "gridMaterial.diffuse + 0.2 * colorMaterial.diffuse",
    alpha: "min(gridMaterial.alpha, colorMaterial.alpha)",
  },
}});

CustomShader

CustomShader は、頂点属性、フィーチャー ID、EXT_structural_metadata にアクセスしながら、ユーザーの GLSL を Model、Cesium3DTileset、VoxelPrimitive の描画に挿入します。

シェーダーの作成方法(構造体のリファレンス、メタデータへのアクセス、フィーチャー ID、ボクセルのサブセット、1.139 の破壊的変更、7 つの実例)については、cesiumjs-custom-shader スキルを参照してください。 CustomShader の統合範囲はこのスキルが担当し、作成方法の詳細はそちらで説明しています。

最小限の例:

import { CustomShader, Model } from "cesium";

const shader = new CustomShader({
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
      material.diffuse = vec3(1.0, 0.5, 0.0);
    }
  `,
});
const model = await Model.fromGltfAsync({ url: "./building.glb", customShader: shader });
viewer.scene.primitives.add(model);

ImageBasedLighting

Model と Cesium3DTileset の PBR イメージベースドライティングを制御します。imageBasedLightingFactor(Cartesian2)は、拡散反射(x)と鏡面反射(y)を 0 から 1 の範囲でスケーリングします。拡散反射には sphericalHarmonicCoefficients(Cartesian3 の配列 9 個、L0~L2)を使用します。鏡面反射には specularEnvironmentMaps(KTX2 キューブマップの URL)を使用します。

import { ImageBasedLighting, Model, Cartesian2, Cartesian3 } from "cesium";

const coefficients = [ // 9 Cartesian3 values for L0..L2 bands
  new Cartesian3(0.35, 0.35, 0.38), new Cartesian3(0.11, 0.11, 0.11),
  new Cartesian3(0.04, 0.04, 0.04), new Cartesian3(-0.08, -0.08, -0.08),
  new Cartesian3(-0.02, -0.02, -0.02), new Cartesian3(0.04, 0.04, 0.04),
  new Cartesian3(-0.06, -0.06, -0.06), new Cartesian3(0.01, 0.01, 0.01),
  new Cartesian3(-0.03, -0.03, -0.03),
];
const ibl = new ImageBasedLighting({
  imageBasedLightingFactor: new Cartesian2(1.0, 1.0),
  sphericalHarmonicCoefficients: coefficients,
  specularEnvironmentMaps: "./environment/specular.ktx2",
});
const model = await Model.fromGltfAsync({ url: "./helmet.glb", imageBasedLighting: ibl });
viewer.scene.primitives.add(model);
// Disable: model.imageBasedLighting.imageBasedLightingFactor = new Cartesian2(0.0, 0.0);

ポストプロセス

viewer.scene.postProcessStages(PostProcessStageCollection)を通じたスクリーン空間のパイプラインです。ステージは順番に実行され、それぞれが colorTexture と depthTexture を読み取ります。

組み込みエフェクト(PostProcessStageLibrary)

すべてのファクトリー関数は、viewer.scene.postProcessStages.add()を介して追加する必要があるステージコンポジットを返します。

createBloomStage()(contrast、brightness、glowOnly、delta、sigma、stepSize)、createBlurStage()(delta、sigma、stepSize)、createDepthOfFieldStage()(focalDistance、delta、sigma、stepSize)、createEdgeDetectionStage()(color、length)、createSilhouetteStage([edgeStage])(エッジ検出ステージをシルエットコンポジットでラップします)、createBlackAndWhiteStage()(gradations)、createBrightnessStage()(brightness)、createNightVisionStage()、createLensFlareStage()(intensity、distortion、ghostDispersal、haloWidth)。

ファクトリーを使ったブルーム(postProcessStages.addで個別のブルームインスタンスを追加する場合に使用します):

import { PostProcessStageLibrary } from "cesium";

const bloom = viewer.scene.postProcessStages.add(
  PostProcessStageLibrary.createBloomStage()
);
bloom.enabled = true;
bloom.uniforms.contrast = 128.0;
bloom.uniforms.brightness = -0.3;
bloom.uniforms.glowOnly = false;
bloom.uniforms.delta = 1.0;
bloom.uniforms.sigma = 3.78;
bloom.uniforms.stepSize = 5.0;

ファクトリーを使ったシルエット(エッジ検出ステージをシルエットコンポジットに渡します):

import { PostProcessStageLibrary, Color } from "cesium";

const edgeStage = PostProcessStageLibrary.createEdgeDetectionStage();
edgeStage.uniforms.color = Color.YELLOW;
edgeStage.uniforms.length = 0.25;
const silhouette = PostProcessStageLibrary.createSilhouetteStage([edgeStage]);
viewer.scene.postProcessStages.add(silhouette);
コレクションステージ(Bloom、AO、FXAA、Tonemapping)

コレクションには、ブルーム、アンビエントオクルージョン、FXAAの組み込みコンポジットが常に用意されており、これらにadd()は必要ありません。TonemappingのデフォルトはPBR_NEUTRALです。

import { Tonemapper, PostProcessStageLibrary } from "cesium";

// Bloom (collection shortcut — always present, no add() needed)
viewer.scene.postProcessStages.bloom.enabled = true;
viewer.scene.postProcessStages.bloom.uniforms.contrast = 128.0;
viewer.scene.postProcessStages.bloom.uniforms.brightness = -0.3;

// Ambient Occlusion (HBAO)
viewer.scene.postProcessStages.ambientOcclusion.enabled = true;
viewer.scene.postProcessStages.ambientOcclusion.uniforms.intensity = 3.0;

// FXAA
viewer.scene.postProcessStages.fxaa.enabled = true;

// Tonemapping: REINHARD, MODIFIED_REINHARD, FILMIC, ACES, PBR_NEUTRAL (default)
viewer.scene.postProcessStages.tonemapper = Tonemapper.ACES;
viewer.scene.postProcessStages.exposure = 1.2; // <1 darker, >1 brighter

// Depth of field (added via library)
const dof = viewer.scene.postProcessStages.add(
  PostProcessStageLibrary.createDepthOfFieldStage()
);
dof.uniforms.focalDistance = 500.0; // meters from camera
dof.uniforms.sigma = 3.8;

夜景/ブルームのビジュアル評価: 周囲の暗い領域を保ちながら、明るい街の灯りが光って見えるようにブルームを適用します。夜景画像の下にOSMベースレイヤーがある場合は、ベースレイヤーのalpha/brightnessを下げ、ブルームを控えめにします(brightnessをより負の値にし、露出を下げます)。これにより、ラベルや地面が白く飛ぶのを防げます。黄色い霞がかかった淡い昼間の地図は、夜景の灯りを描画できているとは言えません。

カスタムPostProcessStage

カスタムステージは、colorTexture、depthTexture(sampler2D)、v_textureCoordinates(vec2)を受け取ります。out_FragColorで出力します。Uniformsには定数または関数を指定でき、関数はフレームごとに再評価されます。

import { PostProcessStage } from "cesium";

const sepia = viewer.scene.postProcessStages.add(new PostProcessStage({
  fragmentShader: `
    uniform sampler2D colorTexture; in vec2 v_textureCoordinates; uniform float intensity;
    void main() {
      vec4 c = texture(colorTexture, v_textureCoordinates);
      float gray = dot(c.rgb, vec3(0.299, 0.587, 0.114));
      out_FragColor = vec4(mix(c.rgb, gray * vec3(1.2, 1.0, 0.8), intensity), c.a);
    }`,
  uniforms: { intensity: () => 0.8 }, // function uniform, re-evaluated each frame
}));
選択したフィーチャーのハイライト表示

フラグメントシェーダーでczm_selected()を使用し、フィーチャーをstage.selectedに割り当てます。

import { PostProcessStage, Color } from "cesium";

const highlight = viewer.scene.postProcessStages.add(new PostProcessStage({
  fragmentShader: `
    uniform sampler2D colorTexture; in vec2 v_textureCoordinates; uniform vec4 highlight;
    void main() {
      vec4 color = texture(colorTexture, v_textureCoordinates);
      if (czm_selected()) {
        out_FragColor = vec4(mix(color.rgb, highlight.rgb, highlight.a), 1.0);
      } else { out_FragColor = color; }
    }`,
  uniforms: { highlight: () => new Color(1.0, 1.0, 0.0, 0.5) },
}));
highlight.selected = [pickedFeature];
PostProcessStageComposite
import { PostProcessStage, PostProcessStageComposite, PostProcessStageLibrary } from "cesium";

const blur = PostProcessStageLibrary.createBlurStage();
const combine = new PostProcessStage({
  fragmentShader: `
    uniform sampler2D colorTexture; uniform sampler2D blurTexture;
    in vec2 v_textureCoordinates;
    void main() {
      vec4 orig = texture(colorTexture, v_textureCoordinates);
      vec4 blurred = texture(blurTexture, v_textureCoordinates);
      out_FragColor = mix(orig, blurred, 0.5);
    }`,
  uniforms: { blurTexture: blur.name }, // reference another stage's output by name
});
viewer.scene.postProcessStages.add(new PostProcessStageComposite({
  stages: [blur, combine],
  inputPreviousStageTexture: false, // both read the original scene texture
}));
ステージの管理
viewer.scene.postProcessStages.remove(sepia); // remove specific stage
dof.enabled = false;                          // disable without removing
viewer.scene.postProcessStages.removeAll();   // remove all custom stages

BlendingState

PrimitiveのAppearance.renderStateで使用する、事前定義済みのブレンドプリセットです。

プリセット動作
BlendingState.DISABLEDブレンドなし
BlendingState.ALPHA_BLEND標準アルファ:src*srcA + dst*(1-srcA)
BlendingState.PRE_MULTIPLIED_ALPHA_BLEND乗算済みアルファ:src + dst*(1-srcA)
BlendingState.ADDITIVE_BLEND加算:src*srcA + dst
import { MaterialAppearance, BlendingState, Material, Color } from "cesium";

const appearance = new MaterialAppearance({
  material: Material.fromType("Color", { color: Color.RED.withAlpha(0.5) }),
  renderState: { depthTest: { enabled: true }, blending: BlendingState.ALPHA_BLEND },
});

パフォーマンスのヒント

  1. 組み込みタイプにはMaterial.fromType()を優先して使用します。シェーダープログラムがキャッシュされるため、再コンパイルを避けられます。
  2. テクスチャマテリアルにはMaterial.fromTypeAsync()を使用し、デフォルトテクスチャのちらつきを防ぎます。
  3. 負荷の高いステージで処理するピクセル数を減らすには、PostProcessStage.textureScaleを1.0未満(例:0.5)に設定します。
  4. 使用していない組み込みステージ(bloom.enabled = falseなど)を無効にします。有効なステージはGPUリソースを消費します。
  5. エフェクトをPostProcessStageCompositeにまとめ、中間テクスチャの割り当てを減らします。
  6. PostProcessStageの数を最小限に抑えます。各ステージで全画面描画呼び出しとフレームバッファーが必要です。

関連項目

  • cesiumjs-custom-shader -- Model.customShader、Cesium3DTileset.customShader、VoxelPrimitive.customShader向けのGLSL作成(構造体のリファレンス、メタデータ、フィーチャーID)
  • cesiumjs-primitives -- Primitive APIオブジェクトでのジオメトリ、Appearance、Materialの適用
  • cesiumjs-3d-tiles -- Cesium3DTilesetの読み込みとスタイル設定
  • cesiumjs-models-particles -- Modelの読み込みとglTF

コメント