Entwicklungsanleitung für Echtzeitbeleuchtung
Das LCC Unity SDK unterstützt Echtzeitbeleuchtung durch dynamische Punktlichter und Spotlights. Im Folgenden wird anhand eines Beispiels, bei dem sich ein Punktlicht auf einer Kreisbahn bewegt, der vollständige Ablauf zur Implementierung von Echtzeitbeleuchtung beschrieben.
Schritt 1: Szene und GameObjects erstellen
Erstellen Sie eine brandneue Szene in Unity. Unity erstellt standardmäßig Hauptkamera und Richtungslicht.
Hauptkamera einrichten
Wählen Sie die Hauptkamera im Fenster Hierarchie aus und legen Sie deren Eigenschaften im Fenster Inspektor wie unten dargestellt fest.

Die Eigenschaften der Hauptkamera festlegen
LCCManager erstellen
Klicken Sie mit der rechten Maustaste in einen leeren Bereich des Fensters Hierarchie, wählen Sie im Popup-Menü Leeres GameObject erstellen, um ein leeres GameObject zu erstellen, benennen Sie es LCCManager, normalisieren Sie dessen Transform und fügen Sie über Komponente hinzufügen das Skript LCCManager hinzu.

Das GameObject LCCManager erstellen und das Skript LCCManager hinzufügen
LCCRenderer erstellen
Klicken Sie mit der rechten Maustaste in einen leeren Bereich des Fensters Hierarchie, wählen Sie Leeres GameObject erstellen, um ein leeres GameObject zu erstellen, benennen Sie es LCCRenderer und setzen Sie dessen Transform auf Rotation.x = -90 und Scale.x = -1.

LCCRenderer erstellen und dessen Transform festlegen (Rotation.x = -90, Scale.x = -1)
Hinweis:
Die Transform-Einstellungen des GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) richten es am LCC-Daten-Koordinatensystem aus. Details zur Ausrichtung am Koordinatensystem finden Sie unter „LCC-Daten-Koordinatensystem“ in Einführung in das Unity SDK.
Schritt 2: Ein Skript zum Übertragen der Lichter schreiben
Erstellen Sie ein neues C#-Skript namens Relighting.cs mit folgendem Code:
using System.Collections.Generic;
using LCCCore;
using Unity.Mathematics;
using UnityEngine;
public class Relighting : MonoBehaviour
{
public LCCManager m_manager;
public string m_FilePath;
private LCCCore.Renderer m_renderer;
[Header("Punktlicht-Einstellungen")]
public Vector3 pointLightPosition = new Vector3(0, 2, 0);
public Color pointLightColor = Color.red;
public float pointLightIntensity = 2.0f;
public float pointLightRange = 3.0f;
[Header("Spotlight-Einstellungen")]
public Vector3 spotLightPosition = new Vector3(0, 2, -2);
public Vector3 spotLightDirection = new Vector3(0, -1, 0);
public Color spotLightColor = new Color(0.1f, 0.9f, 0.7f);
public float spotLightIntensity = 3.0f;
public float spotLightRange = 20.0f;
public float spotLightAngle = 45.0f;
[Header("Animation")]
public bool animateLights = true;
public float rotateSpeed = 30.0f;
private List<PointLightData> m_lights = new List<PointLightData>();
private float m_angle;
void Start()
{
m_manager.SetPlatformType(PlatformType.PC);
m_manager.SwitchRenderPass(ActiveRenderMode.SingleRender);
m_manager.SetMainCamera(Camera.main);
m_renderer = m_manager.GetRender(this.transform);
m_renderer.Load(m_FilePath, onProgress, onComplete);
}
private void onProgress(float _progress)
{
Debug.Log($"[Relighting] Ladefortschritt: {_progress:P1}");
}
private void onComplete()
{
Debug.Log("[Relighting] Laden abgeschlossen, Lichter werden eingerichtet");
//m_manager.SetLightIntensity(0.5f);
ApplyLights();
}
void Update()
{
if (!animateLights) return;
m_angle += rotateSpeed * Time.deltaTime;
ApplyLights();
}
private void ApplyLights()
{
m_lights.Clear();
float rad = m_angle * Mathf.Deg2Rad;
float px = pointLightPosition.x + Mathf.Cos(rad) * 3f;
float pz = pointLightPosition.z + Mathf.Sin(rad) * 3f;
// lightType 0 = Punktlicht
m_lights.Add(new PointLightData
{
position = new float3(px, pointLightPosition.y, pz),
lightType = 0,
color = new float3(pointLightColor.r, pointLightColor.g, pointLightColor.b),
intensity = pointLightIntensity,
direction = float3.zero,
range = pointLightRange,
spotAngle = 0f,
pad = float3.zero
});
// lightType 1 = Spotlight
Vector3 dir = spotLightDirection.normalized;
m_lights.Add(new PointLightData
{
position = new float3(spotLightPosition.x, spotLightPosition.y, spotLightPosition.z),
lightType = 1,
color = new float3(spotLightColor.r, spotLightColor.g, spotLightColor.b),
intensity = spotLightIntensity,
direction = new float3(dir.x, dir.y, dir.z),
range = spotLightRange,
spotAngle = spotLightAngle,
pad = float3.zero
});
int result = m_manager.SetLights(m_lights);
if (result != 0)
Debug.LogWarning($"[Relighting] SetLights fehlgeschlagen: {result}");
}
void OnDisable()
{
// null übergeben, um die benutzerdefinierte Beleuchtung zu deaktivieren
m_manager.SetLights(null);
}
}
Hinweis:
- Die Echtzeitbeleuchtung muss nach Abschluss des Ladens der LCC-Szene übertragen werden; daher wird das erste
ApplyLights()im CallbackonCompleteaufgerufen.- Dieses Beispiel aktualisiert die Lichtposition in jedem Frame in
Update, um die Bewegung des Punktlichts auf einer Kreisbahn zu animieren.- Der Typ des Lichtfelds ist
Unity.Mathematics.float3, wasusing Unity.Mathematics;erfordert.colorbesitzt nur drei RGB-Komponenten und kein Alpha.
Schritt 3: Das Skript anhängen und den Datenpfad festlegen
- Hängen Sie das Skript
Relighting.csim Fenster Hierarchie an das GameObject LCCManager. - Ziehen Sie im Fenster Inspektor das GameObject LCCManager auf die Eigenschaft Manager des Skripts.
- Tragen Sie den LCC-Dateipfad in die Eigenschaft File Path des Skripts ein.
- Die übrigen Eigenschaften für Punktlicht, Spotlight und Animation können frei konfiguriert werden.

Das Relighting-Skript anhängen und dessen Eigenschaften im Inspektor festlegen
In diesem Beispiel werden ein Punktlicht und ein Spotlight erstellt, und das Punktlicht bewegt sich auf einer Kreisbahn, um den Echtzeit-Beleuchtungseffekt zu demonstrieren.
Schritt 4: Ausführen
Klicken Sie im Fenster Spiel auf die Schaltfläche Play, um den Echtzeit-Beleuchtungseffekt in der Szene zu sehen.

Der Echtzeit-Beleuchtungseffekt in der 3DGS-Szene nach dem Ausführen
Besonderheiten der 3DGS-Beleuchtung
Die Beleuchtung in 3DGS unterscheidet sich stark von der traditionellen Mesh-Modell-Beleuchtung. Der Beleuchtungseffekt in 3DGS wird direkt in die RGB-Farbe geschrieben, d. h., die Beleuchtung ist in die gerenderten Farbkomponenten eingebacken. Wenn ein 3DGS-Modell daher an einem sonnigen Tag mit sehr starken harten Schatten aufgenommen wurde, kann Re-Lighting diese bereits eingebackenen Schatten nicht entfernen.
Darüber hinaus liegt der Farbbereich beim Rendern bei [0, 1]. Wenn Sie die Beleuchtung ohne jegliche Verarbeitung direkt verstärken, tritt Überbelichtung auf. Um Überbelichtung zu vermeiden, dunkeln Sie die 3DGS-Szene in der Regel zunächst ab, bevor Sie sie erneut beleuchten.
Im SDK kann die Lichtintensität über LCCManager.SetLightIntensity(float _intensity) angepasst werden:
- Der Eingabeparameter
_intensityliegt im Bereich[0, 1]. - Diese Funktion wirkt sich auf den gesamten Beleuchtungseffekt aus: Je stärker die konfigurierte Lichtintensität ist, desto dunkler wird die 3DGS-Szene gedrückt.
- Der Standardwert ist
0.5.
Tipp:
Die Beleuchtungsberechnung ist eine relativ teure Operation. Das SDK unterstützt maximal 50 dynamische Lichter (Punkt- und Spotlights zusammen). Bei Überschreitung des Limits gibt
SetLightsden Wert-1zurück und zeigt keine Wirkung.
Schlüsselschritte
Die Schlüsselschritte zum Hinzufügen von Echtzeitbeleuchtung zu einer 3DGS-Szene:
- Die Vorkonfiguration von
SetPlatformType/SwitchRenderPass/SetMainCameraabschließen und die LCC-Szene überGetRender+Loadladen. - Nach Abschluss des Ladens der Szene (im Callback
onComplete) diePointLightData-Liste aufbauen undSetLightszum Übertragen der Lichter aufrufen. - Bei Bedarf an Animation die Lichtparameter in
Updateaktualisieren undSetLightserneut aufrufen. - Bei Überbelichtung zuerst die Szene mit
SetLightIntensityabdunkeln, bevor erneut beleuchtet wird. - Zum Deaktivieren der Echtzeitbeleuchtung
nulloder eine leere Liste anSetLightsübergeben.
Echtzeit-Beleuchtungs-APIs
Das LCC Unity SDK stellt über LCCManager die folgenden zwei Echtzeit-Beleuchtungs-APIs bereit. Sie müssen beide nach Abschluss des Ladens der LCC-Szene (d. h. im Callback onComplete) aufgerufen werden.
SetLights
// Rückgabewert: int → 0 = Erfolg, -1 = maximales Limit überschritten
public int SetLights(List<PointLightData> lights)
Legt die benutzerdefinierte Punktlicht-Liste fest. Das Übergeben von null oder einer leeren Liste deaktiviert die benutzerdefinierte Beleuchtung.
| Parameter | Typ | Beschreibung |
|---|---|---|
lights | List<PointLightData> | Lichtliste (bis zu 50 Punkt- und Spotlights zusammen) |
Verwendungsbeispiel:
using Unity.Mathematics; // float3
var lights = new List<PointLightData>();
lights.Add(new PointLightData {
position = new float3(0, 5, 0),
lightType = 0, // 0=Punktlicht, 1=Spotlight
color = new float3(1, 1, 1),
intensity = 2f,
range = 10f
});
m_manager.SetLights(lights);
Hinweise:
- Der Typ des Felds ist
Unity.Mathematics.float3, nichtVector4;colorbesitzt keine Alphakomponente. lightType:0= Punktlicht (ignoriertdirection/spotAngle),1= Spotlight (erfordertdirection/spotAngle).- Die maximale Anzahl beträgt 50 (Punkt- und Spotlights zusammen); bei Überschreitung wird
-1zurückgegeben. - Das Übergeben von
nulloder einer leeren Liste deaktiviert die benutzerdefinierte Beleuchtung. - Bei Aktivierung wird das Shader-Keyword
_USERLIGHTaktiviert. - Die Datenstruktur trägt den Namen PointLightData, weil UnityEngine bereits LightData definiert, um Mehrdeutigkeit zu vermeiden.
SetLightIntensity
// Rückgabewert: void
public void SetLightIntensity(float intensity)
Legt die globale Lichtintensität fest; sie dient dazu, die 3DGS-Szene vor dem Re-Lighting abzudunkeln, um Überbelichtung zu verhindern.
| Parameter | Typ | Beschreibung |
|---|---|---|
intensity | float | Beleuchtungsintensität, im Bereich [0, 1] |
Verwendungsbeispiel:
m_manager.SetLightIntensity(0.5f);
Hinweise:
- Der Standardwert ist
0.5. - Bereich
[0, 1]; Werte außerhalb des Bereichs werden automatisch begrenzt. - Je größer der Wert, desto dunkler wird die gesamte 3DGS-Szene gedrückt.
Datenstruktur PointLightData
public struct PointLightData {
public float3 position; // Weltposition
public int lightType; // 0=Punktlicht, 1=Spotlight
public float3 color; // RGB-Farbe (ohne Alphakomponente)
public float intensity; // Lichtintensität
public float3 direction; // Spotlight-Richtung (bei Punktlichtern ignoriert)
public float range; // Lichtreichweite
public float spotAngle; // Spotlight-Kegelwinkel (Grad, bei Punktlichtern ignoriert)
public float3 pad; // Ausrichtungs-Padding, keine Zuweisung erforderlich
}
| Feld | Typ | Beschreibung |
|---|---|---|
position | float3 | Weltposition des Lichts |
lightType | int | 0 = Punktlicht, 1 = Spotlight |
color | float3 | RGB-Farbe (ohne Alphakomponente) |
intensity | float | Lichtintensität |
direction | float3 | Spotlight-Richtung, bei Punktlichtern ignoriert |
range | float | Lichtreichweite |
spotAngle | float | Spotlight-Kegelwinkel (Grad), bei Punktlichtern ignoriert |
pad | float3 | Ausrichtungs-Padding, keine Zuweisung erforderlich |