Przewodnik oświetlenia w czasie rzeczywistym
LCC Unity SDK obsługuje oświetlenie w czasie rzeczywistym z dynamicznych świateł punktowych i reflektorów. Poniżej na przykładzie światła punktowego poruszającego się po ścieżce kołowej opisano kompletne kroki implementacji oświetlenia w czasie rzeczywistym.
Krok 1: Utwórz scenę i GameObjects
Utwórz zupełnie nową scenę w Unity. Unity domyślnie tworzy Kamerę główną i Światło kierunkowe.
Skonfiguruj Kamerę główną
Wybierz Kamerę główną w oknie Hierarchia i ustaw jej właściwości w oknie Inspektor, jak pokazano poniżej.

Ustaw właściwości Kamery głównej
Utwórz LCCManager
Kliknij prawym przyciskiem myszy pusty obszar w oknie Hierarchia, wybierz Utwórz pusty z menu podręcznego, aby utworzyć pusty GameObject, nazwij go LCCManager, znormalizuj jego Transform i dodaj do niego skrypt LCCManager przez Dodaj komponent.

Utwórz GameObject LCCManager i dodaj skrypt LCCManager
Utwórz LCCRenderer
Kliknij prawym przyciskiem myszy pusty obszar w oknie Hierarchia, wybierz Utwórz pusty, aby utworzyć pusty GameObject, nazwij go LCCRenderer i ustaw jego Transform na Rotation.x = -90 i Scale.x = -1.

Utwórz LCCRenderer i ustaw jego Transform (Rotation.x = -90, Scale.x = -1)
Uwaga:
Ustawienia Transform GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) wyrównują go z układem współrzędnych danych LCC. Szczegóły wyrównania układu współrzędnych znajdziesz w sekcji „Układ współrzędnych danych LCC" w Wprowadzenie do Unity SDK.
Krok 2: Napisz skrypt, aby przesłać światła
Utwórz nowy skrypt C# o nazwie Relighting.cs z następującym kodem:
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("Ustawienia światła punktowego")]
public Vector3 pointLightPosition = new Vector3(0, 2, 0);
public Color pointLightColor = Color.red;
public float pointLightIntensity = 2.0f;
public float pointLightRange = 3.0f;
[Header("Ustawienia reflektora")]
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("Animacja")]
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] postęp ładowania: {_progress:P1}");
}
private void onComplete()
{
Debug.Log("[Relighting] ładowanie zakończone, konfigurowanie świateł");
//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 = światło punktowe
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 = reflektor
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 nie powiodło się: {result}");
}
void OnDisable()
{
// Przekaż null, aby wyłączyć niestandardowe oświetlenie
m_manager.SetLights(null);
}
}
Uwaga:
- Oświetlenie w czasie rzeczywistym musi być przesłane po zakończeniu ładowania sceny LCC, więc pierwsze wywołanie
ApplyLights()znajduje się w wywołaniu zwrotnymonComplete.- Ten przykład odświeża pozycję światła co klatkę w
Update, aby animować światło punktowe poruszające się po ścieżce kołowej.- Typ pola światła to
Unity.Mathematics.float3, co wymagausing Unity.Mathematics;.colorma tylko trzy składowe RGB i nie ma alfa.
Krok 3: Dołącz skrypt i ustaw ścieżkę danych
- Dołącz skrypt
Relighting.csdo GameObject LCCManager w oknie Hierarchia. - W oknie Inspektor przeciągnij GameObject LCCManager na właściwość Manager skryptu.
- Wpisz ścieżkę pliku LCC we właściwości File Path skryptu.
- Pozostałe właściwości światła punktowego, reflektora i animacji można skonfigurować dowolnie.

Dołącz skrypt Relighting i ustaw jego właściwości w Inspektorze
W tym przykładzie tworzone jest jedno światło punktowe i jeden reflektor, a światło punktowe porusza się po ścieżce kołowej, aby zademonstrować efekt oświetlenia w czasie rzeczywistym.
Krok 4: Uruchom
Kliknij przycisk Odtwórz w oknie Gra, aby zobaczyć efekt oświetlenia w czasie rzeczywistym w scenie.

Efekt oświetlenia w czasie rzeczywistym w scenie 3DGS po uruchomieniu
Specyfika oświetlenia 3DGS
Oświetlenie w 3DGS różni się znacznie od tradycyjnego oświetlenia modeli siatek. Efekt oświetlenia w 3DGS jest zapisywany bezpośrednio w kolorze RGB, co oznacza, że oświetlenie jest „wypiekane" w renderowane składowe koloru. Dlatego jeśli model 3DGS został uchwycony w słoneczny dzień z bardzo silnymi twardymi cieniami, ponowne oświetlenie nie może usunąć tych już wypieczonych cieni.
Ponadto zakres koloru podczas renderowania to [0, 1]. Jeśli bezpośrednio wzmocnisz oświetlenie bez żadnego przetwarzania, wystąpi prześwietlenie. Aby zapobiec prześwietleniu, zwykle najpierw przyciemniasz scenę 3DGS, a dopiero potem ją ponownie oświetlasz.
W SDK intensywność oświetlenia można regulować przez LCCManager.SetLightIntensity(float _intensity):
- Parametr wejściowy
_intensitymieści się w zakresie[0, 1]. - Ta funkcja wpływa na ogólny efekt oświetlenia: im silniejsze skonfigurowane natężenie światła, tym ciemniejsza jest scena 3DGS.
- Wartość domyślna to
0.5.
Wskazówka:
Obliczanie oświetlenia jest stosunkowo kosztowną operacją. SDK obsługuje maksymalnie 50 dynamicznych świateł (świateł punktowych i reflektorów łącznie). Po przekroczeniu limitu
SetLightszwraca-1i nie działa.
Kluczowe kroki
Kluczowe kroki dodawania oświetlenia w czasie rzeczywistym do sceny 3DGS:
- Ukończ wstępną konfigurację
SetPlatformType/SwitchRenderPass/SetMainCamerai załaduj scenę LCC przezGetRender+Load. - Po zakończeniu ładowania sceny (w wywołaniu zwrotnym
onComplete) zbuduj listęPointLightDatai wywołajSetLights, aby przesłać światła. - Gdy potrzebna jest animacja, aktualizuj parametry świateł w
Updatei ponownie wywołajSetLights. - Jeśli wystąpi prześwietlenie, użyj
SetLightIntensity, aby najpierw przyciemnić scenę, a dopiero potem ją ponownie oświetlić. - Aby wyłączyć oświetlenie w czasie rzeczywistym, przekaż
nulllub pustą listę doSetLights.
API oświetlenia w czasie rzeczywistym
LCC Unity SDK udostępnia dwa poniższe API oświetlenia w czasie rzeczywistym przez LCCManager. Oba muszą być wywoływane po zakończeniu ładowania sceny LCC (czyli w wywołaniu zwrotnym onComplete).
SetLights
// Wartość zwracana: int → 0 = sukces, -1 = przekroczono limit maksymalnej liczby
public int SetLights(List<PointLightData> lights)
Ustawia niestandardową listę świateł punktowych. Przekazanie null lub pustej listy wyłącza niestandardowe oświetlenie.
| Parametr | Typ | Opis |
|---|---|---|
lights | List<PointLightData> | Lista świateł (maksymalnie 50 świateł punktowych i reflektorów łącznie) |
Przykład użycia:
using Unity.Mathematics; // float3
var lights = new List<PointLightData>();
lights.Add(new PointLightData {
position = new float3(0, 5, 0),
lightType = 0, // 0=światło punktowe, 1=reflektor
color = new float3(1, 1, 1),
intensity = 2f,
range = 10f
});
m_manager.SetLights(lights);
Uwagi:
- Typ pola to
Unity.Mathematics.float3, a nieVector4;colornie ma składowej alfa. lightType:0= światło punktowe (ignorujedirection/spotAngle),1= reflektor (wymagadirection/spotAngle).- Maksymalna liczba to 50 (światła punktowe i reflektory łącznie); po przekroczeniu zwraca
-1. - Przekazanie
nulllub pustej listy wyłącza niestandardowe oświetlenie. - Po włączeniu włączane jest słowo kluczowe shadera
_USERLIGHT. - Struktura danych nosi nazwę PointLightData, ponieważ UnityEngine definiuje już LightData, aby uniknąć niejednoznaczności.
SetLightIntensity
// Wartość zwracana: void
public void SetLightIntensity(float intensity)
Ustawia globalną intensywność oświetlenia, używaną do przyciemnienia sceny 3DGS przed ponownym oświetleniem, aby zapobiec prześwietleniu.
| Parametr | Typ | Opis |
|---|---|---|
intensity | float | Intensywność oświetlenia, w zakresie [0, 1] |
Przykład użycia:
m_manager.SetLightIntensity(0.5f);
Uwagi:
- Wartość domyślna to
0.5. - Zakres
[0, 1]; wartości spoza zakresu są automatycznie przycinane. - Im większa wartość, tym ciemniejsza jest ogólna scena 3DGS.
Struktura danych PointLightData
public struct PointLightData {
public float3 position; // pozycja w przestrzeni świata
public int lightType; // 0=światło punktowe, 1=reflektor
public float3 color; // kolor rgb (bez składowej alfa)
public float intensity; // natężenie światła
public float3 direction; // kierunek reflektora (ignorowany dla świateł punktowych)
public float range; // zasięg światła
public float spotAngle; // kąt stożka reflektora (w stopniach, ignorowany dla świateł punktowych)
public float3 pad; // wypełnienie wyrównania, brak potrzeby przypisania
}
| Pole | Typ | Opis |
|---|---|---|
position | float3 | Pozycja światła w przestrzeni świata |
lightType | int | 0 = światło punktowe, 1 = reflektor |
color | float3 | Kolor RGB (bez składowej alfa) |
intensity | float | Natężenie światła |
direction | float3 | Kierunek reflektora, ignorowany dla świateł punktowych |
range | float | Zasięg światła |
spotAngle | float | Kąt stożka reflektora (w stopniach), ignorowany dla świateł punktowych |
pad | float3 | Wypełnienie wyrównania, brak potrzeby przypisania |