Entwicklungsanleitung für Echtzeit-Clipping
Das LCC Unity SDK unterstützt Bearbeitungsoperationen wie Hervorhebung und Clipping auf 3DGS-Szenen. Diese Anleitung stellt Echtzeit-Clipping-Operationen vor: das Auswählen eines Bereichs über 2D-projizierte Texturen, 3D-Geometrie oder eine Mischung aus beidem, das Ausschneiden des ausgewählten Bereichs aus der Szene, wobei normale Auswahl und invertierte Auswahl unterstützt werden.
Hinweis:
Die aktuelle Clipping-Funktion ist nur ein Laufzeit-Anzeigeeffekt; sie verändert die ursprüngliche Datendatei in keiner Weise und unterstützt weder das Speichern noch das Exportieren des Bearbeitungsergebnisses. Wenn Sie Daten farbanpassen, zuschneiden und speichern müssen, verwenden Sie das Software-Tool XGRIDS LCC Editor.
Wenn Sie die Daten nicht verändern möchten, können Sie die Operationen auch aufzeichnen und sie nach dem nächsten Abschluss des Datenladens erneut abspielen.
Voraussetzungen
Das Clipping einer Szene über das SDK erfordert folgende Bedingungen:
- Vor dem Laden der Daten in den Bearbeitungszustand wechseln. Das SDK befindet sich standardmäßig im Durchsuchen-Zustand (View), der die beste Leistung bietet und für das normale Durchsuchen empfohlen wird. Um Bearbeitungsoperationen wie Clipping auszuführen, wechseln Sie vor dem Aufruf von
LoadüberSetEditorMode(true)in den Bearbeitungszustand. Diese Methode wirkt nur, wenn sie vor dem Laden aller Daten aufgerufen wird. - Die Clipping-Operation nach Abschluss des Datenladens ausführen. Die Clipping-Schnittstelle muss aufgerufen werden, nachdem die Szenendaten vollständig geladen sind.
Schritt 1: Die Szene einrichten
Bereiten Sie die für das Clipping benötigten GameObjects in der Szene wie unten dargestellt vor.

Hierarchiestruktur der Szene für das Clipping-Beispiel
- Hauptkamera: die Szenenkamera; das 2D-Clipping verwendet ihre View- und Projektionsmatrizen.
- LCCManager: ein leeres GameObject mit normalisierter Transform und dem hinzugefügten Skript
LCCManager. - LCCRenderer: ein leeres GameObject mit Transform Rotation.x = -90, Scale.x = -1 (am LCC-Daten-Koordinatensystem ausgerichtet), zum Anhängen des später geschriebenen Skripts
Clip. - 3D-Auswahlgeometrie: Hilfsobjekte für das 3D-Clipping. Das Beispiel bereitet 3 Würfel (
Box1,Box2,Box3) und 1 Kugel (Clipsphere) vor; das Verschieben und Skalieren dieser Objekte steuert Position und Größe der Clipping-Auswahl.
Hinweis:
Für Einstellungen im Zusammenhang mit den GameObjects Rendering-Kamera, LCCManager und LCCRenderer siehe die relevanten Abschnitte der PC-Schnellstartanleitung und des Leitfadens zur Optimierung der Projekteinstellungen.

Für das 3D-Clipping verwendete Auswahlgeometrie (Box1 / Box2 / Box3 / Clipsphere)
Schritt 2: Die Datenstrukturen verstehen
Das Clipping umfasst drei Operationsmethoden – 2D, 3D und 2D/3D gemischt. Die verwendeten Enums und Structs sind wie folgt.
public enum SelectMode { normal, invert, clip } // normale Auswahl, invertieren, Echtzeit-Clipping
public enum OperationMode { normal, erase } // normale Auswahl, Auswahl löschen
public enum ShapeType { box, sphere } // 3D-Box-Auswahl, 3D-Kugel-Auswahl
public enum EditType { Edit2D, Edit3D } // 2D-Bearbeitung, 3D-Bearbeitung
// 2D-Texturauswahl
public struct Data2D
{
public Texture2D texture; // 2D-Maskentextur
public Matrix4x4 mv; // Kamera-View-Matrix
public Matrix4x4 mvp; // Kamera-View-Projection-Matrix
public SelectMode mode; // Auswahlmodus
}
// 3D-Geometrieauswahl
public struct Data3D
{
public ShapeType type; // Geometrietyp (Box / Kugel)
public Matrix4x4 invMat; // Welt-zu-lokal-(Inverse-)Matrix der Geometrie
public OperationMode operation; // Operationstyp (normale Vereinigung / Lösch-Differenz)
public SelectMode mode; // Auswahlmodus
}
// 2D-/3D-gemischte Auswahl
public struct DataMix
{
public EditType editType; // Bearbeitungstyp (erforderlich; bestimmt, ob 2D- oder 3D-Felder verwendet werden)
public Texture2D texture; // 2D-Maskentextur (von Edit2D verwendet)
public Matrix4x4 mv; // Kamera-View-Matrix (von Edit2D verwendet)
public Matrix4x4 mvp; // Kamera-View-Projection-Matrix (von Edit2D verwendet)
public ShapeType type; // Geometrietyp (von Edit3D verwendet)
public Matrix4x4 invMat; // Geometrie-Inversmatrix (von Edit3D verwendet)
public OperationMode operation; // Operationstyp (von Edit3D verwendet)
public SelectMode mode; // Auswahlmodus (erforderlich)
}
Zur Auswahlliste gibt es drei Punkte zu beachten:
- Die Liste ist geordnet. Ob 2D oder 3D, Einträge in der Liste wirken in Reihenfolge; stellen Sie sicher, dass die Reihenfolge des Hinzufügens Ihrer Erwartung entspricht.
- Invertieren ist ein Operationsbefehl und muss nicht mit bestimmten Auswahldaten verknüpft werden. Fügen Sie einfach einen Eintrag mit
mode = SelectMode.inverthinzu, um den aktuell ausgewählten Bereich zu invertieren. - Die maximale Anzahl von Einträgen in einer einzelnen Liste beträgt 255. Bei Überschreitung wird ein Fehlercode zurückgegeben.
Schritt 3: Die Clipping-APIs verstehen
Alle clippingbezogenen Schnittstellen werden von LCCManager bereitgestellt, einschließlich drei SetClip-Überladungen und einer Beenden-Methode.
SetClip (2D-Textur-Clipping)
// Rückgabewert: int
// 0: Erfolg
// 1: Liste ist null oder hat 0 Elemente
// 2: Listenelemente überschreiten das Maximum von 255
public int SetClip(List<Data2D> _2Ds)
Schneidet die Szene mit einer 2D-projizierten Texturmaske; der markierte Bereich wird aus der Szene ausgeschnitten.
SetClip (3D-Geometrie-Clipping)
// Rückgabewert: int
// 0: Erfolg
// 1: Liste ist null oder hat 0 Elemente
// 2: Listenelemente überschreiten das Maximum von 255
// 3: die Anzahl der Auswahlgeometrie-Boxen ist 0
public int SetClip(List<Data3D> _3Ds)
Definiert den Clipping-Bereich mit 3D-Geometrie (Quader, Würfel, Kugel) und unterstützt Vereinigungs- und Differenzkombinationen. Mindestens eine Geometrie mit operation == OperationMode.normal ist erforderlich.
SetClip (gemischter Modus)
// Rückgabewert: int
// 0: Erfolg
// 1: Liste ist null oder hat 0 Elemente
// 2: Listenelemente überschreiten das Maximum von 255
public int SetClip(List<DataMix> _Mix)
Definiert den Clipping-Bereich gleichzeitig mit 2D-Texturen und 3D-Geometrie; jeder Eintrag bestimmt über editType, ob er als 2D oder 3D verarbeitet wird.
QuitClipMode
// Rückgabewert: void
public void QuitClipMode()
Beendet den Clipping-Modus und stellt die vollständige Szenenanzeige wieder her.
Tipp:
Die drei
SetClip-Überladungen schließen sich gegenseitig aus. Rufen Sie beim Wechseln der Clipping-Methode oder beim Löschen des aktuellen Clippings zuerstQuitClipMode()auf und setzen Sie dann das neue Clipping.
Schritt 4: Spezifikation der 2D-Maskentextur
Das 2D-Clipping beschreibt die Auswahl über eine Maskentextur und unterstützt verschiedene Auswahlmethoden wie Vierecke, Dreiecke, Pinsel und Lasso – markieren Sie einfach die entsprechenden Pixel in der Textur mit dem Clipping-Wert. Bei 2D-Operationen sollte die Kamera gesperrt und die Textur von einem festen Blickpunkt aus markiert werden. Die Textur und die Pixelwerte haben folgende Konventionen:
- Die Textur ist fest 1024 × 1024,
R8-Einkanal, ohne Mipmap, Punktfilterung (FilterMode.Point) und geklemmtes Sampling (TextureWrapMode.Clamp). - Pixelwert-Konventionen:
| Pixelwert | Bedeutung |
|---|---|
128 | Standard (behalten) |
240 | Ausgewählt |
180 | Abwählen (den bereits ausgewählten Bereich löschen) |
0 | Clipping |
In einem Clipping-Szenario werden normalerweise nur die beiden Werte 128 (Standard behalten) und 0 (Clipping) verwendet.
Schritt 5: Das Skript schreiben
Erstellen Sie ein neues C#-Skript namens Clip.cs. Vervollständigen Sie zunächst das Grundskelett: In Start in den Bearbeitungszustand wechseln und Daten laden; nach Abschluss des Ladens das Ladeflag setzen, damit die nachfolgenden Clipping-Methoden es prüfen können.
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);
// In den Bearbeitungsmodus wechseln; muss vor Load aufgerufen werden
m_manager.SetEditorMode(true);
m_renderer = m_manager.GetRender(this.transform);
if (m_renderer == null)
Debug.LogError("GetRender fehlgeschlagen. Prüfen Sie, ob der Manager korrekt gesetzt ist und der Dateipfad gültig ist.");
m_renderer.Load(m_FilePath, onLoadProgress, onLoadCallback);
}
private void onLoadProgress(float value)
{
Debug.Log($"Ladefortschritt: {value}");
}
private void onLoadCallback()
{
Debug.Log("Daten geladen !!!");
m_isLoaded = true;
// Das Rendern der Umgebung (niederpräzise Fernfeld-Punktwolke) deaktivieren, um das Clipping-Ergebnis besser zu beobachten
m_renderer.SetEnvironment(false);
}
// 2D-/3D-/gemischte Clipping-Methoden unten
}
Hinweis:
SetEditorMode(true)muss vorLoadaufgerufen werden, um zu wirken; undSetClipmuss nach Abschluss des Datenladens aufgerufen werden (nachdem der CallbackonLoadCallbackausgelöst wurde).SetEnvironment(false)deaktiviert die Fernfeld-Umgebungspunktwolke, um das Clipping-Ergebnis klarer zu machen; entscheiden Sie nach Bedarf, ob Sie es aufrufen.
Schritt 6: Das Skript anhängen und Eigenschaften festlegen
- Hängen Sie das Skript
Clip.csan das GameObject LCCRenderer. - Ziehen Sie im Fenster Inspektor das GameObject LCCManager auf die Eigenschaft Manager des Skripts.
- Tragen Sie den LCC-Dateipfad in die Eigenschaft File Path ein.
- Ziehen Sie
Box1,Box2,Box3undClipspherein der Szene jeweils auf die entsprechenden Eigenschaften des Skripts.

Die Eigenschaften des Clip-Skripts im Inspektor festlegen
Schritt 7: Beispiele für Clipping-Operationen
Fügen Sie die folgenden Methoden zur Klasse Clip hinzu und rufen Sie die entsprechende Methode nach dem Ausführen und nach Abschluss des Datenladens auf.
2D-Textur-Clipping
Konstruieren Sie zwei R8-Maskentexturen, markieren Sie die auszuschneidenden Pixel mit 0 und den Rest des Behaltebereichs mit 128, konstruieren Sie dann Data2D mit den Kameramatrizen und fügen Sie sie der Liste hinzu.
public void on2DClip()
{
// Die Texturgröße ist fest 1024*1024; die übrigen Eigenschaften wie im Beispiel beibehalten
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 bedeutet Clipping, 128 bedeutet Standard, 240 bedeutet ausgewählt
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);
}
Code-Erläuterung: Es werden zwei Maskentexturen erstellt. Die erste Maske schneidet die untere Bildschirmhälfte aus (der Bildschirmursprung ist die untere linke Ecke), und die zweite Maske schneidet den Bereich 0,75 bis 0,9 der oberen Bildschirmhälfte aus. Der Beispieleffekt ist wie folgt.
In der Praxis können Sie verschiedene Auswahlwerkzeuge wie Rechtecke, Dreiecke, Pinsel und Lasso verwenden, um die entsprechenden Positionen auf der Maske auszuwählen.

Effekt des 2D-Textur-Clippings
3D-Geometrie-Clipping
Verwenden Sie die worldToLocalMatrix der Geometrie als Auswahl-Inversmatrix, kombinieren Sie Vereinigung (normal) und Differenz (erase) über operation und implementieren Sie die invertierte Auswahl über einen Eintrag mit 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-Auswahl
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);
// Kugel-Auswahl
Data3D _3d04 = new Data3D();
_3d04.type = ShapeType.sphere;
_3d04.operation = OperationMode.normal;
_3d04.mode = SelectMode.normal;
_3d04.invMat = _mat4;
_3Ds.Add(_3d04);
// Box/Kugel löschen (Differenz)
Data3D _3d03 = new Data3D();
_3d03.type = ShapeType.box;
_3d03.operation = OperationMode.erase;
_3d03.mode = SelectMode.normal;
_3d03.invMat = _mat3;
_3Ds.Add(_3d03);
// Invertieren
//Data3D _3d05 = new Data3D();
//_3d05.mode = SelectMode.invert;
//_3Ds.Add(_3d05);
m_manager.SetClip(_3Ds);
}
Code-Erläuterung: Es werden 4 Geometrien verwendet, wobei Box1, Box2 und Kugel normale Auswahlen sind und Box3 eine Lösch-Auswahl ist, d. h. das Löschen des zuvor ausgewählten Bereichs. Mit auskommentiertem Invertier-Code ist der Beispieleffekt wie folgt:

Effekt des 3D-Geometrie-Clippings
Heben Sie die Auskommentierung des Invertier-Codes auf, damit das Invertieren wirkt; der Beispieleffekt ist wie folgt. Invertieren kehrt den zuvor ausgewählten Bereich um; es ist ein Befehl und muss nicht mit Operationsdaten verknüpft werden.
Beachten Sie insbesondere, dass die Liste geordnet ist; unterschiedliche Operationsschritte erzeugen unterschiedliche Endergebnisse.

Effekt des 3D-Geometrie- + Invert-Clippings
Clipping im gemischten Modus
Mischen Sie 2D-Textur- und 3D-Geometrie-Einträge in derselben Liste; jeder Eintrag gibt seine Verarbeitungsmethode über editType an.
public void onMixClip()
{
// --- 2D-Auswahlvorbereitung ---
// Die Texturgröße ist fest 1024*1024; die übrigen Eigenschaften wie im Beispiel beibehalten
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 bedeutet Standard, 240 bedeutet ausgewählt, 0 bedeutet Clipping
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-Auswahlvorbereitung ---
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-Auswahl
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);
// Kugel-Auswahl
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/Kugel löschen (Differenz)
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);
// Invertieren (nach Bedarf aktivieren)
DataMix _mix06 = new DataMix();
_mix06.editType = EditType.Edit3D;
_mix06.type = ShapeType.box;
_mix06.mode = SelectMode.invert;
//_Mixs.Add(_mix06);
m_manager.SetClip(_Mixs);
}
Code-Erläuterung: Es werden 4 Geometrien und 1 2D-Textur verwendet, was eine gemischte 2D-/3D-Verarbeitung ermöglicht. Der Beispieleffekt ist wie folgt:

Effekt des Clippings im gemischten Modus
Schritt 8: Clipping beenden
Rufen Sie QuitClipMode() auf, um das aktuelle Clipping zu löschen und die vollständige Szenenanzeige wiederherzustellen.
public void onClearClip()
{
m_manager.QuitClipMode();
}
Schlüsselschritte
Die Schlüsselschritte zum Durchführen von Echtzeit-Clipping auf einer 3DGS-Szene:
SetEditorMode(true)vor dem Laden der Daten aufrufen, um in den Bearbeitungszustand zu wechseln.SetClipnach Abschluss des Datenladens aufrufen (nachdem der CallbackonLoadCallbackausgelöst wurde, oder über einen Button/ein Ereignis ausgelöst).- Nach Bedarf 2D-Textur, 3D-Geometrie oder gemischten Modus wählen und sicherstellen, dass die Hinzufüge-Reihenfolge der Auswahlliste Ihrer Erwartung entspricht.
- Die 2D-Maskentextur ist fest 1024 × 1024,
R8-Einkanal; Pixelwerte gemäß Konvention füllen (128Standard behalten,0Clipping). - Beim Löschen oder Wechseln von Clippings zuerst
QuitClipMode()aufrufen.