リアルタイムクリッピング開発ガイド
LCC Unity SDK は、3DGS シーンに対するハイライトやクリッピングなどの編集操作に対応しています。このガイドでは、リアルタイムクリッピング操作を説明します。2D 投影テクスチャ、3D ジオメトリ、またはその組み合わせで領域を選択し、選択領域をシーンから切り取ります。通常選択と反転選択に対応しています。
注:
現在のクリッピング機能はランタイムの表示効果のみで、元のデータファイルを一切変更せず、編集結果の保存やエクスポートにも対応していません。データのカラー調整・クリッピング・保存が必要な場合は、XGRIDS LCC Editor ソフトウェアツールを使用してください。
データを変更したくない場合は、操作を記録しておき、次回データ読み込み完了後に再生することもできます。
前提条件
SDK でシーンをクリッピングするには、以下の条件が必要です。
- データ読み込み前に編集状態に入る。 SDK はデフォルトで閲覧状態(View)で、最も高い性能を提供し、通常の閲覧に推奨されます。クリッピングなどの編集操作を行うには、
Loadを呼び出す前にSetEditorMode(true)で編集状態に切り替えます。このメソッドはすべてのデータを読み込む前に呼び出した場合のみ有効です。 - データ読み込み完了後にクリッピング操作を行う。 クリッピングインターフェースは、シーンデータが完全に読み込まれた後に呼び出す必要があります。
手順 1:シーンをセットアップする
以下のように、クリッピングに必要な GameObject をシーンに準備します。

クリッピング例のシーンヒエラルキー構成
- Main Camera:シーンカメラ。2D クリッピングはそのビュー行列と投影行列を使用します。
- LCCManager:Transform を正規化した空の GameObject で、
LCCManagerスクリプトを追加します。 - LCCRenderer:Transform を Rotation.x = -90、Scale.x = -1 に設定した空の GameObject(LCC データ座標系にアライメント)で、後述の
Clipスクリプトをアタッチします。 - 3D 選択ジオメトリ:3D クリッピングの補助オブジェクト。この例では 3 つの Cube(
Box1、Box2、Box3)と 1 つの Sphere(Clipsphere)を用意します。これらのオブジェクトを移動・スケーリングすると、クリッピング選択の位置とサイズを制御できます。
注:
レンダリングカメラ、LCCManager、LCCRenderer GameObject に関する設定は、PC クイックスタートガイド と プロジェクト設定の最適化ガイド の関連セクションを参照してください。

3D クリッピングに使用する選択ジオメトリ(Box1 / Box2 / Box3 / Clipsphere)
手順 2:データ構造を理解する
クリッピングには 2D、3D、2D/3D 混合の 3 つの操作方法があります。使用する列挙型と構造体は以下のとおりです。
public enum SelectMode { normal, invert, clip } // 通常選択、反転、リアルタイムクリッピング
public enum OperationMode { normal, erase } // 通常選択、選択の消去
public enum ShapeType { box, sphere } // 3D Box 選択、3D Sphere 選択
public enum EditType { Edit2D, Edit3D } // 2D 編集、3D 編集
// 2D テクスチャ選択
public struct Data2D
{
public Texture2D texture; // 2D マスクテクスチャ
public Matrix4x4 mv; // カメラのビュー行列
public Matrix4x4 mvp; // カメラのビュー投影行列
public SelectMode mode; // 選択モード
}
// 3D ジオメトリ選択
public struct Data3D
{
public ShapeType type; // ジオメトリタイプ(box / sphere)
public Matrix4x4 invMat; // ジオメトリのワールド→ローカル(逆)行列
public OperationMode operation; // 操作タイプ(通常の和 / 消去の差)
public SelectMode mode; // 選択モード
}
// 2D / 3D 混合選択
public struct DataMix
{
public EditType editType; // 編集タイプ(必須。2D と 3D のどちらのフィールドを使うかを決定)
public Texture2D texture; // 2D マスクテクスチャ(Edit2D で使用)
public Matrix4x4 mv; // カメラのビュー行列(Edit2D で使用)
public Matrix4x4 mvp; // カメラのビュー投影行列(Edit2D で使用)
public ShapeType type; // ジオメトリタイプ(Edit3D で使用)
public Matrix4x4 invMat; // ジオメトリの逆行列(Edit3D で使用)
public OperationMode operation; // 操作タイプ(Edit3D で使用)
public SelectMode mode; // 選択モード(必須)
}
選択リストについて注意すべき点は 3 つあります。
- リストは順序付きです。 2D でも 3D でも、リスト内のエントリは順番に有効になります。追加順が期待と一致することを確認してください。
- 反転は操作コマンドであり、特定の選択データと関連付ける必要はありません。
mode = SelectMode.invertのエントリを追加するだけで、現在選択中の領域が反転されます。 - 1 つのリストの最大エントリ数は 255 です。 超えるとエラーコードが返ります。
手順 3:クリッピング API を理解する
クリッピング関連のインターフェースはすべて LCCManager が提供します。3 つの SetClip オーバーロードと 1 つの終了メソッドがあります。
SetClip(2D テクスチャクリッピング)
// 戻り値: int
// 0: 成功
// 1: リストが null または要素数 0
// 2: リスト要素が最大数 255 を超過
public int SetClip(List<Data2D> _2Ds)
2D 投影テクスチャマスクを使用してシーンをクリッピングします。マークされた領域がシーンから切り取られます。
SetClip(3D ジオメトリクリッピング)
// 戻り値: int
// 0: 成功
// 1: リストが null または要素数 0
// 2: リスト要素が最大数 255 を超過
// 3: 選択ジオメトリボックスの数が 0
public int SetClip(List<Data3D> _3Ds)
3D ジオメトリ(直方体、立方体、球)でクリッピング領域を定義し、和と差の組み合わせに対応します。少なくとも 1 つの operation == OperationMode.normal のジオメトリが必要です。
SetClip(混合モードクリッピング)
// 戻り値: int
// 0: 成功
// 1: リストが null または要素数 0
// 2: リスト要素が最大数 255 を超過
public int SetClip(List<DataMix> _Mix)
2D テクスチャと 3D ジオメトリを同時に使用してクリッピング領域を定義します。各エントリは editType で 2D か 3D かを決定します。
QuitClipMode
// 戻り値: void
public void QuitClipMode()
クリッピングモードを終了し、シーン全体の表示を復元します。
ヒント:
3 つの
SetClipオーバーロードは相互排他的です。クリッピング方法の切り替えや現在のクリッピングのクリア時は、先にQuitClipMode()を呼び出してから新しいクリッピングを設定します。
手順 4:2D マスクテクスチャ仕様
2D クリッピングはマスクテクスチャで選択を記述し、四角形、三角形、ブラシ、投げ縄などさまざまな選択方法に対応します。対応するピクセルをテクスチャ内でクリッピング値としてマークするだけです。2D 操作を使用する場合、カメラをロックし、固定視点からテクスチャをマークする必要があります。テクスチャとピクセル値の規約は以下のとおりです。
- テクスチャは 1024 × 1024 固定、
R8単一チャンネル、Mipmap なし、ポイントフィルタリング(FilterMode.Point)、クランプサンプリング(TextureWrapMode.Clamp)。 - ピクセル値の規約:
| ピクセル値 | 意味 |
|---|---|
128 | デフォルト(保持) |
240 | 選択済み |
180 | 選択解除(既選択領域の消去) |
0 | クリッピング |
クリッピングシナリオでは、通常 128(デフォルト保持)と 0(クリッピング)の 2 つの値のみを使用します。
手順 5:スクリプトを書く
Clip.cs という名前の新しい C# スクリプトを作成します。まず基本の骨組みを完成させます。Start で編集状態に入りデータを読み込み、読み込み完了後に後続のクリッピングメソッドがチェックするための読み込みフラグを設定します。
using LCCCore;
using System.Collections.Generic;
using UnityEngine;
public class Clip : MonoBehaviour
{
public LCCManager m_manager;
public string m_FilePath;
public GameObject m_Box1;
public GameObject m_Box2;
public GameObject m_Box3;
public GameObject m_Clipsphere;
private LCCCore.Renderer m_renderer;
private Camera m_camera;
private bool m_isLoaded = false;
void Start()
{
m_camera = Camera.main;
m_manager.SetPlatformType(PlatformType.PC);
// 編集モードに入る。Load の前に呼び出す必要がある
m_manager.SetEditorMode(true);
m_renderer = m_manager.GetRender(this.transform);
if (m_renderer == null)
Debug.LogError("GetRender に失敗しました。マネージャが正しく設定され、ファイルパスが有効か確認してください。");
m_renderer.Load(m_FilePath, onLoadProgress, onLoadCallback);
}
private void onLoadProgress(float value)
{
Debug.Log($"読み込み進捗: {value}");
}
private void onLoadCallback()
{
Debug.Log("データが読み込まれました !!!");
m_isLoaded = true;
// 環境(遠景の低精度点群)レンダリングを無効化してクリッピング結果を観察しやすくする
m_renderer.SetEnvironment(false);
}
// 2D / 3D / 混合クリッピングメソッドを以下に追加
}
注:
SetEditorMode(true)はLoadの前に呼び出さないと有効になりません。またSetClipはデータ読み込み完了後(onLoadCallbackコールバック発火後)に呼び出す必要があります。SetEnvironment(false)は遠景の環境点群を無効化してクリッピング結果をより明確にします。必要に応じて呼び出すかどうかを判断してください。
手順 6:スクリプトをアタッチしてプロパティを設定する
Clip.csスクリプトを LCCRenderer GameObject にアタッチします。- Inspector ウィンドウで LCCManager GameObject をスクリプトの Manager プロパティへドラッグします。
- File Path プロパティに LCC ファイルパスを入力します。
- シーン内の
Box1、Box2、Box3、Clipsphereを、それぞれスクリプトの対応するプロパティへドラッグします。

Inspector で Clip スクリプトのプロパティを設定
手順 7:クリッピング操作例
以下のメソッドを Clip クラスに追加し、実行してデータ読み込み完了後に対応するメソッドを呼び出します。
2D テクスチャクリッピング
2 つの R8 マスクテクスチャを構築し、クリッピングするピクセルを 0、残りの保持領域を 128 としてマークし、カメラ行列で Data2D を構築してリストに追加します。
public void on2DClip()
{
// テクスチャサイズは 1024*1024 に固定。その他のプロパティは例と同じに保つ
Texture2D _texture = new Texture2D(1024, 1024, TextureFormat.R8, false);
_texture.filterMode = FilterMode.Point;
_texture.wrapMode = TextureWrapMode.Clamp;
int _count = 1024 * 1024;
int _half = _count / 2;
byte[] _values = new byte[_count];
for (int i = 0; i < _count; i++)
{
if (i < _half)
_values[i] = 0; // 0 はクリッピング、128 はデフォルト、240 は選択
else
_values[i] = 128;
}
_texture.SetPixelData(_values, 0);
Texture2D _texture2 = new Texture2D(1024, 1024, TextureFormat.R8, false);
_texture2.filterMode = FilterMode.Point;
_texture2.wrapMode = TextureWrapMode.Clamp;
byte[] _values2 = new byte[_count];
for (int i = 0; i < _count; i++)
{
if (i > _count * 0.75 && i < _count * 0.9)
_values2[i] = 0;
else
_values2[i] = 128;
}
_texture2.SetPixelData(_values2, 0);
List<Data2D> _2Ds = new List<Data2D>();
Data2D _2d01 = new Data2D();
_2d01.mv = m_camera.worldToCameraMatrix;
_2d01.texture = _texture;
_2d01.mode = SelectMode.normal;
_2d01.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_2Ds.Add(_2d01);
Data2D _2d02 = new Data2D();
_2d02.mv = m_camera.worldToCameraMatrix;
_2d02.texture = _texture2;
_2d02.mode = SelectMode.normal;
_2d02.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_2Ds.Add(_2d02);
m_manager.SetClip(_2Ds);
}
コード解説:2 つのマスクテクスチャを構築します。1 つ目のマスクは画面の下半分(画面原点は左下隅)をクリッピングし、2 つ目のマスクは画面上半分の 0.75 から 0.9 の領域をクリッピングします。例の効果は以下のとおりです。
実際の使用では、矩形、三角形、ブラシ、投げ縄などさまざまな選択ツールでマスク上の対応位置を選択できます。

2D テクスチャクリッピング効果
3D ジオメトリクリッピング
ジオメトリの worldToLocalMatrix を選択逆行列として使用し、operation で和(normal)と差(erase)を組み合わせ、mode = SelectMode.invert のエントリで反転選択を実現します。
public void on3DClip()
{
List<Data3D> _3Ds = new List<Data3D>();
var _mat1 = m_Box1.transform.worldToLocalMatrix;
var _mat2 = m_Box2.transform.worldToLocalMatrix;
var _mat3 = m_Box3.transform.worldToLocalMatrix;
var _mat4 = m_Clipsphere.transform.worldToLocalMatrix;
// Box 選択
Data3D _3d01 = new Data3D();
_3d01.type = ShapeType.box;
_3d01.operation = OperationMode.normal;
_3d01.mode = SelectMode.normal;
_3d01.invMat = _mat1;
_3Ds.Add(_3d01);
Data3D _3d02 = new Data3D();
_3d02.type = ShapeType.box;
_3d02.operation = OperationMode.normal;
_3d02.mode = SelectMode.normal;
_3d02.invMat = _mat2;
_3Ds.Add(_3d02);
// Sphere 選択
Data3D _3d04 = new Data3D();
_3d04.type = ShapeType.sphere;
_3d04.operation = OperationMode.normal;
_3d04.mode = SelectMode.normal;
_3d04.invMat = _mat4;
_3Ds.Add(_3d04);
// Box/Sphere の消去(差分)
Data3D _3d03 = new Data3D();
_3d03.type = ShapeType.box;
_3d03.operation = OperationMode.erase;
_3d03.mode = SelectMode.normal;
_3d03.invMat = _mat3;
_3Ds.Add(_3d03);
// 反転
//Data3D _3d05 = new Data3D();
//_3d05.mode = SelectMode.invert;
//_3Ds.Add(_3d05);
m_manager.SetClip(_3Ds);
}
コード解説:4 つのジオメトリを使用します。Box1、Box2、Sphere は通常選択、Box3 は消去選択(既選択領域の消去)です。反転関連のコードはコメントアウトした状態での例の効果は以下のとおりです。

3D ジオメトリクリッピング効果
反転コードのコメントを外すと反転が有効になります。例の効果は以下のとおりです。反転は以前選択した領域を反転させます。コマンドであり、操作データと関連付ける必要はありません。
特に、リストは順序付きであることに注意してください。操作手順が異なると最終効果も異なります。

3D ジオメトリ + 反転クリッピング効果
混合モードクリッピング
2D テクスチャと 3D ジオメトリのエントリを同じリストに混在させ、各エントリは editType で処理方法を指定します。
public void onMixClip()
{
// --- 2D 選択の準備 ---
// テクスチャサイズは 1024*1024 に固定。その他のプロパティは例と同じに保つ
Texture2D _texture = new Texture2D(1024, 1024, TextureFormat.R8, false);
_texture.filterMode = FilterMode.Point;
_texture.wrapMode = TextureWrapMode.Clamp;
int _count = 1024 * 1024;
int _half = _count / 2;
byte[] _values = new byte[_count];
for (int i = 0; i < _count; i++)
{
if (i < _half)
_values[i] = 128; // 128 はデフォルト、240 は選択、0 はクリッピング
else
_values[i] = 0;
}
_texture.SetPixelData(_values, 0);
List<DataMix> _Mixs = new List<DataMix>();
DataMix _mix01 = new DataMix();
_mix01.editType = EditType.Edit2D;
_mix01.mv = m_camera.worldToCameraMatrix;
_mix01.texture = _texture;
_mix01.mode = SelectMode.normal;
_mix01.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_Mixs.Add(_mix01);
// --- 3D 選択の準備 ---
var _mat1 = m_Box1.transform.worldToLocalMatrix;
var _mat2 = m_Box2.transform.worldToLocalMatrix;
var _mat3 = m_Box3.transform.worldToLocalMatrix;
var _mat4 = m_Clipsphere.transform.worldToLocalMatrix;
// Box 選択
DataMix _mix02 = new DataMix();
_mix02.editType = EditType.Edit3D;
_mix02.type = ShapeType.box;
_mix02.operation = OperationMode.normal;
_mix02.mode = SelectMode.normal;
_mix02.invMat = _mat1;
_Mixs.Add(_mix02);
DataMix _mix03 = new DataMix();
_mix03.editType = EditType.Edit3D;
_mix03.type = ShapeType.box;
_mix03.operation = OperationMode.normal;
_mix03.mode = SelectMode.normal;
_mix03.invMat = _mat2;
_Mixs.Add(_mix03);
// Sphere 選択
DataMix _mix04 = new DataMix();
_mix04.editType = EditType.Edit3D;
_mix04.type = ShapeType.sphere;
_mix04.operation = OperationMode.normal;
_mix04.mode = SelectMode.normal;
_mix04.invMat = _mat4;
_Mixs.Add(_mix04);
// Box/Sphere の消去(差分)
DataMix _mix05 = new DataMix();
_mix05.editType = EditType.Edit3D;
_mix05.type = ShapeType.box;
_mix05.operation = OperationMode.erase;
_mix05.mode = SelectMode.normal;
_mix05.invMat = _mat3;
_Mixs.Add(_mix05);
// 反転(必要に応じて有効化)
DataMix _mix06 = new DataMix();
_mix06.editType = EditType.Edit3D;
_mix06.type = ShapeType.box;
_mix06.mode = SelectMode.invert;
//_Mixs.Add(_mix06);
m_manager.SetClip(_Mixs);
}
コード解説:4 つのジオメトリと 1 つの 2D テクスチャを使用し、2D と 3D の混合処理が可能です。例の効果は以下のとおりです。

混合モードクリッピング効果
手順 8:クリッピングを解除する
QuitClipMode() を呼び出して現在のクリッピングをクリアし、シーン全体の表示を復元します。
public void onClearClip()
{
m_manager.QuitClipMode();
}
重要な手順
3DGS シーンにリアルタイムクリッピングを実行するための重要な手順は以下のとおりです。
- データ読み込み前に
SetEditorMode(true)を呼び出して編集状態に入ります。 - データ読み込み後(
onLoadCallbackコールバック発火後、またはボタン/イベントでトリガー)にSetClipを呼び出します。 - 必要に応じて 2D テクスチャ、3D ジオメトリ、混合モードを選び、選択リストの追加順が期待と一致することを確認します。
- 2D マスクテクスチャは 1024 × 1024 固定、
R8単一チャンネルです。ピクセル値は規約(128デフォルト保持、0クリッピング)に従って埋めます。 - クリッピングのクリアや切り替え時は、先に
QuitClipMode()を呼び出します。