XGRIDSDocs
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • Polski
  • Nederlands
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • Polski
  • Nederlands
  • Seria Lixel PortalCam

    • PortalCam P1

      • Przegląd produktu
      • Podstawowa obsługa
      • Korzystanie z aplikacji LCC Scan
      • Konserwacja i pielęgnacja
      • FAQ
  • Seria Lixel K

    • Lixel K1

      • Przegląd produktu
      • Podstawowa obsługa
      • Aktywacja i połączenie urządzenia
      • Przebieg skanowania
      • Pozyskiwanie danych chmury punktów ze współrzędnymi bezwzględnymi
      • Fuzja map
      • Zalecenia dotyczące planowania trasy dla typowych scen
      • Środki ostrożności
      • FAQ
    • Lixel K2

      • Przegląd produktu
      • Podstawowa obsługa
      • Aktywacja i połączenie urządzenia
      • Przebieg skanowania
      • Pozyskiwanie danych chmury punktów ze współrzędnymi bezwzględnymi
      • Fuzja map
      • Zalecenia dotyczące planowania trasy dla typowych scen
      • Środki ostrożności
      • FAQ
  • Seria Lixel L

    • Lixel L2 Pro

      • Przegląd produktu
      • Podstawowa obsługa
      • Aktywacja i połączenie urządzenia
      • Proces skanowania
      • Pozyskiwanie danych chmury punktów ze współrzędnymi bezwzględnymi
      • Punkt pomiarowy
      • Dodatek
      • FAQ
    • Lixel L3

      • Przegląd produktu
      • Podstawowe funkcje urządzenia
      • Aktywacja i połączenie urządzenia
      • Przechwytywanie danych
      • Przechwytywanie współrzędnych bezwzględnych
      • Dodatek
  • Akcesoria

    • Stick Light

      • Przewodnik instalacji
      • Podstawowa obsługa
      • Często zadawane pytania
  • Lixel Studio

    • Wersja i prawa autorskie
    • Instalacja i aktywacja
    • Interfejs oprogramowania
    • Operacje na plikach
    • Przetwarzanie projektu
    • Narzędzia
    • Rysowanie 2D
    • Zastosowania
    • Ustawienia
    • Połączenie z urządzeniem
  • 07-plugin-sdk

    • Unity

      • Wprowadzenie do Unity SDK
      • Funkcje techniczne
      • Wymagania środowiska deweloperskiego
      • Przewodnik szybkiego startu dla PC
      • Przewodnik optymalizacji ustawień projektu
      • Przewodnik deweloperski dla Pico 4 Ultra
      • Przewodnik strumieniowania PC dla Pico 4 Ultra
      • Przewodnik deweloperski dla Quest 3
      • Przewodnik strumieniowania PC dla Quest 3
      • Przewodnik deweloperski dla OpenXR
      • Przewodnik Business Streaming dla Pico 4 Ultra
      • Słownik
      • Często zadawane pytania (FAQ)
      • Skontaktuj się z nami
      • Przewodnik programowania funkcji

        • Przewodnik mieszanego renderowania wielu scen
        • Przewodnik odbierania cieni
        • Przewodnik oświetlenia w czasie rzeczywistym
        • Przewodnik renderowania wielokamerowego
        • Przewodnik renderowania obrazów wysokiej rozdzielczości
        • Przewodnik zgodności formatów danych LCC i LCC2
        • Przewodnik efektu ładowania
        • Przewodnik przełączania trybu renderowania Mip
        • Przewodnik przyciągania do krawędzi i narożników
        • Przewodnik dekala projekcyjnego
        • Przewodnik wideo dekala projekcyjnego
        • Przewodnik podświetlania
        • Przewodnik przycinania w czasie rzeczywistym
        • Przewodnik korekcji kolorów
        • Przewodnik pobierania danych siatki sceny
        • Przewodnik trybu edytora
        • Przewodnik konfiguracji parametrów wydajności renderowania
        • Przewodnik współpakowania aplikacji i danych
        • Przewodnik systemu kolizji
        • Przewodnik problemów z uprawnieniami w deweloperstwie na macOS
        • Przewodnik kompilacji i pakowania na urządzenia iOS
      • Dokumentacja API

        • LCCManager
        • Renderer
        • Typy danych
      • Dziennik zmian

        • v2.3.0
        • v2.2.10
        • v2.2.0
        • v2.1.19
        • v2.0.14

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

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 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

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 zwrotnym onComplete.
  • 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 wymaga using Unity.Mathematics;. color ma tylko trzy składowe RGB i nie ma alfa.

Krok 3: Dołącz skrypt i ustaw ścieżkę danych

  1. Dołącz skrypt Relighting.cs do GameObject LCCManager w oknie Hierarchia.
  2. W oknie Inspektor przeciągnij GameObject LCCManager na właściwość Manager skryptu.
  3. Wpisz ścieżkę pliku LCC we właściwości File Path skryptu.
  4. 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

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

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 _intensity mieś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 SetLights zwraca -1 i nie działa.

Kluczowe kroki

Kluczowe kroki dodawania oświetlenia w czasie rzeczywistym do sceny 3DGS:

  1. Ukończ wstępną konfigurację SetPlatformType / SwitchRenderPass / SetMainCamera i załaduj scenę LCC przez GetRender + Load.
  2. Po zakończeniu ładowania sceny (w wywołaniu zwrotnym onComplete) zbuduj listę PointLightData i wywołaj SetLights, aby przesłać światła.
  3. Gdy potrzebna jest animacja, aktualizuj parametry świateł w Update i ponownie wywołaj SetLights.
  4. Jeśli wystąpi prześwietlenie, użyj SetLightIntensity, aby najpierw przyciemnić scenę, a dopiero potem ją ponownie oświetlić.
  5. Aby wyłączyć oświetlenie w czasie rzeczywistym, przekaż null lub pustą listę do SetLights.

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.

ParametrTypOpis
lightsList<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 nie Vector4; color nie ma składowej alfa.
  • lightType: 0 = światło punktowe (ignoruje direction / spotAngle), 1 = reflektor (wymaga direction / spotAngle).
  • Maksymalna liczba to 50 (światła punktowe i reflektory łącznie); po przekroczeniu zwraca -1.
  • Przekazanie null lub 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.

ParametrTypOpis
intensityfloatIntensywność 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
}
PoleTypOpis
positionfloat3Pozycja światła w przestrzeni świata
lightTypeint0 = światło punktowe, 1 = reflektor
colorfloat3Kolor RGB (bez składowej alfa)
intensityfloatNatężenie światła
directionfloat3Kierunek reflektora, ignorowany dla świateł punktowych
rangefloatZasięg światła
spotAnglefloatKąt stożka reflektora (w stopniach), ignorowany dla świateł punktowych
padfloat3Wypełnienie wyrównania, brak potrzeby przypisania