XGRIDSДокументация
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • Polski
  • Nederlands
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • Polski
  • Nederlands
  • Lixel CyberColor

    • Руководство пользователя LCC Studio

      • Начало работы
      • Версия и обновления
      • Загрузка и установка
      • Обзор интерфейса и навигация
      • Перед реконструкцией
      • Реконструкция модели
      • Реконструкция одиночной модели
      • Объединение карт
      • Воздушно-наземное объединение
      • Воздушная реконструкция
      • Мои модели
      • Другие функции
      • Настройки и учётная запись
      • Конвертер
      • Реконструкция по видео
      • Часто задаваемые вопросы
    • LCC Scene Editor

      • Версия и обновления
      • Учётная запись и вход
      • Обзор продукта и главная страница
      • Интерфейс редактора
      • Режимы навигации по сцене
      • Файл
      • Настройки
      • Операции редактирования
      • Окно
      • Глобальная панель инструментов
      • Ресурсы и свойства
      • Левая панель инструментов
      • Точки обзора
      • Портал
      • Skybox
      • Аннотации
      • Измерение
      • Flythrough
      • Отчёт по сцене
      • 3D Layout
      • Мини-карта
      • Preview Mode (Viewer)
      • Справка
      • Часто задаваемые вопросы
      • Точка появления
    • LCC Model Editor

      • Версия и обновления
      • Руководство пользователя
      • Обзор и интерфейс
      • Операции с файлами
      • Инструменты выбора
      • Редактирование моделей
      • Измерение
      • Цветокоррекция
      • Управление ресурсами
      • Настройки и справка
      • Часто задаваемые вопросы
    • Рекомендации по применению

      • Объединение нескольких крупных моделей 3DGS
  • Plugin & SDK

    • Unreal

      • Введение
      • Быстрый старт — Windows
      • Быстрый старт — Linux
      • Быстрый старт — Quest3
      • Редакции и лицензирование
      • Рендеринг
      • Растеризация Tiled (экспериментально)
      • Визуальные настройки
      • Нормали и освещение
      • Редактирование сцены
      • Параметры производительности
      • Руководство по оптимизации производительности
      • Интеграция со сторонними и движковыми плагинами
      • Прокси-меш
      • Анимация загрузки
      • Коллизии
      • Поддержка системы навигации
      • Поддержка однослойной воды
      • Локализация
      • Частые вопросы
      • Устранение неполадок
      • Журналы и диагностика
      • Свяжитесь с нами
      • Рекомендуемые практики

        • Переосвещение 3DGS с помощью меша LixelStudio
      • Справочник API

        • ALCCActorBase
        • ULCCComponentBase
        • ULCCComponent
        • ULCC2Component
        • Actor SOG / SPZ / PLY
        • ALCC2ProxyMesh
        • ALCCClippingVolume
        • ALCCSectionPlane
        • ALCCLoadVolume
        • ULCCUtilLibrary
        • Enums
        • Structs
      • Журнал изменений

        • v3.4.0
        • v3.3.1
        • v3.0.0
        • v2.2.1
        • v1.0.0
        • v0.9.0
        • v0.8.0
        • v0.7.1
        • v0.6.1
        • v0.5.2
        • v0.4.1
        • v0.4.0
        • v0.3.0
        • v0.0.5
        • v0.0.4
        • v0.0.3
        • v0.0.2
        • v0.0.1
    • Unity

      • Введение в Unity SDK
      • Технические возможности
      • Требования к среде разработки
      • Руководство по быстрому старту для PC
      • Руководство по оптимизации настроек проекта
      • Руководство по разработке для Pico 4 Ultra
      • Руководство по стримингу Pico 4 Ultra с PC
      • Руководство по разработке для Quest 3
      • Руководство по стримингу Quest 3 с PC
      • Руководство по разработке OpenXR
      • Руководство по бизнес-стримингу Pico 4 Ultra
      • Глоссарий
      • FAQ
      • Свяжитесь с нами
      • Руководство по разработке функций

        • Руководство по разработке смешанного рендеринга нескольких сцен
        • Руководство по разработке приёма теней
        • Руководство по разработке освещения в реальном времени
        • Руководство по разработке многокамерного рендеринга
        • Руководство по разработке рендеринга изображений высокого разрешения
        • Руководство по разработке совместимости форматов данных LCC и LCC2
        • Руководство по разработке эффекта загрузки
        • Руководство по разработке переключения режима рендеринга Mip
        • Руководство по разработке привязки к рёбрам и углам
        • Руководство по разработке проецируемых декалей
        • Руководство по разработке видеопроецируемой декали
        • Руководство по разработке подсветки
        • Руководство по разработке обрезки в реальном времени
        • Руководство по разработке коррекции цвета
        • Руководство по разработке получения данных Mesh сцены
        • Руководство по разработке в режиме редактора
        • Руководство по настройке параметров производительности рендеринга
        • Руководство по разработке совместной упаковки приложения и данных
        • Руководство по разработке системы коллизий
        • Руководство по проблемам с разрешениями при разработке на macOS
        • Руководство по разработке компиляции и упаковки для устройств iOS
      • Справочник по API

        • LCCManager
        • Renderer
        • Типы данных
      • Журнал изменений

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

Руководство по разработке освещения в реальном времени

LCC Unity SDK поддерживает освещение в реальном времени от динамических точечных источников света и прожекторов. Ниже на примере точечного источника света, движущегося по круговой траектории, описаны полные шаги по реализации освещения в реальном времени.

Шаг 1: Создайте сцену и GameObject

Создайте совершенно новую сцену в Unity. Unity по умолчанию создаёт Main Camera и Directional Light.

Настройте Main Camera

Выберите Main Camera в окне Hierarchy и задайте его свойства в окне Inspector, как показано ниже.

Настройка свойств Main Camera

Настройка свойств Main Camera

Создайте LCCManager

Щёлкните правой кнопкой мыши в пустой области окна Hierarchy, выберите Create Empty во всплывающем меню, чтобы создать пустой GameObject, назовите его LCCManager, нормализуйте его Transform и добавьте к нему скрипт LCCManager через Add Component.

Создание GameObject LCCManager и добавление скрипта LCCManager

Создание GameObject LCCManager и добавление скрипта LCCManager

Создайте LCCRenderer

Щёлкните правой кнопкой мыши в пустой области окна Hierarchy, выберите Create Empty, чтобы создать пустой GameObject, назовите его LCCRenderer и задайте его Transform значения Rotation.x = -90 и Scale.x = -1.

Создание LCCRenderer и настройка его Transform

Создание LCCRenderer и настройка его Transform (Rotation.x = -90, Scale.x = -1)

Примечание:

Настройки Transform GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) выравнивают его с системой координат данных LCC. Подробнее о выравнивании системы координат см. в разделе «Система координат данных LCC» документа Введение в Unity SDK.

Шаг 2: Напишите скрипт для передачи источников света

Создайте новый скрипт C# с именем Relighting.cs со следующим кодом:

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("Настройки точечного источника света")]
    public Vector3 pointLightPosition = new Vector3(0, 2, 0);
    public Color pointLightColor = Color.red;
    public float pointLightIntensity = 2.0f;
    public float pointLightRange = 3.0f;

    [Header("Настройки прожекторного источника света")]
    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("Анимация")]
    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] прогресс загрузки: {_progress:P1}");
    }

    private void onComplete()
    {
        Debug.Log("[Relighting] загрузка завершена, настройка источников света");
        //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 = точечный источник света
        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 = прожекторный источник света
        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 завершился ошибкой: {result}");
    }

    void OnDisable()
    {
        // Передаём null, чтобы отключить пользовательское освещение
        m_manager.SetLights(null);
    }
}

Примечание:

  • Освещение в реальном времени должно передаваться после завершения загрузки LCC-сцены, поэтому первый вызов ApplyLights() выполняется в обратном вызове onComplete.
  • Этот пример каждый кадр в Update обновляет положение источника света, чтобы анимировать точечный источник света, движущийся по круговой траектории.
  • Тип поля источника света — Unity.Mathematics.float3, что требует using Unity.Mathematics;. color имеет только три компонента RGB и не имеет альфа.

Шаг 3: Прикрепите скрипт и задайте путь к данным

  1. Прикрепите скрипт Relighting.cs к GameObject LCCManager в окне Hierarchy.
  2. В окне Inspector перетащите GameObject LCCManager на свойство Manager скрипта.
  3. Заполните путь к файлу LCC в свойстве File Path скрипта.
  4. Остальные свойства точечного источника света, прожектора и анимации можно настроить свободно.
Прикрепление скрипта Relighting и настройка его свойств

Прикрепление скрипта Relighting и настройка его свойств в Inspector

В этом примере создаются один точечный источник света и один прожектор, а точечный источник света движется по круговой траектории, демонстрируя эффект освещения в реальном времени.

Шаг 4: Запустите

Нажмите кнопку Play в окне Game, чтобы увидеть эффект освещения в реальном времени в сцене.

Эффект освещения в реальном времени в сцене 3DGS после запуска

Эффект освещения в реальном времени в сцене 3DGS после запуска

Особенности освещения 3DGS

Освещение в 3DGS сильно отличается от традиционного освещения моделей Mesh. Эффект освещения в 3DGS записывается непосредственно в цвет RGB, то есть освещение «запекается» в компоненты отрендеренного цвета. Поэтому если модель 3DGS была захвачена в солнечный день с очень сильными жёсткими тенями, переосвещение не сможет удалить эти уже запечённые тени.

Кроме того, диапазон цвета при рендеринге равен [0, 1]. Если напрямую усилить освещение без какой-либо обработки, возникнет переэкспонирование. Чтобы предотвратить переэкспонирование, обычно сначала затемняют сцену 3DGS, а затем переосвещают её.

В SDK интенсивность освещения можно настроить через LCCManager.SetLightIntensity(float _intensity):

  • Входной параметр _intensity находится в диапазоне [0, 1].
  • Эта функция влияет на общий эффект освещения: чем сильнее настроенная интенсивность света, тем темнее становится сцена 3DGS.
  • Значение по умолчанию — 0.5.

Совет:

Расчёт освещения — относительно дорогостоящая операция. SDK поддерживает максимум 50 динамических источников света (точечных и прожекторных вместе). При превышении лимита SetLights возвращает -1 и не даёт эффекта.

Ключевые шаги

Ключевые шаги для добавления освещения в реальном времени в сцену 3DGS:

  1. Выполните предварительную настройку SetPlatformType / SwitchRenderPass / SetMainCamera и загрузите LCC-сцену через GetRender + Load.
  2. После завершения загрузки сцены (в обратном вызове onComplete) постройте список PointLightData и вызовите SetLights для передачи источников света.
  3. При необходимости анимации обновляйте параметры источников света в Update и снова вызывайте SetLights.
  4. Если возникает переэкспонирование, используйте SetLightIntensity, чтобы сначала затемнить сцену, а затем переосветить её.
  5. Чтобы отключить освещение в реальном времени, передайте null или пустой список в SetLights.

API освещения в реальном времени

LCC Unity SDK предоставляет следующие два API освещения в реальном времени через LCCManager. Оба они должны вызываться после завершения загрузки LCC-сцены (то есть в обратном вызове onComplete).

SetLights

// Возвращаемое значение: int → 0 = успех, -1 = превышен максимальный лимит количества
public int SetLights(List<PointLightData> lights)

Задаёт пользовательский список точечных источников света. Передача null или пустого списка отключает пользовательское освещение.

ПараметрТипОписание
lightsList<PointLightData>Список источников света (до 50 точечных и прожекторных вместе)

Пример использования:

using Unity.Mathematics; // float3

var lights = new List<PointLightData>();
lights.Add(new PointLightData {
    position = new float3(0, 5, 0),
    lightType = 0,              // 0=точечный источник света, 1=прожекторный источник света
    color = new float3(1, 1, 1),
    intensity = 2f,
    range = 10f
});
m_manager.SetLights(lights);

Примечания:

  • Тип поля — Unity.Mathematics.float3, а не Vector4; color не имеет компонента альфа.
  • lightType: 0 = точечный источник света (игнорирует direction / spotAngle), 1 = прожекторный источник света (требует direction / spotAngle).
  • Максимальное количество — 50 (точечные и прожекторные вместе); при превышении возвращается -1.
  • Передача null или пустого списка отключает пользовательское освещение.
  • При включении активируется ключевое слово шейдера _USERLIGHT.
  • Структура данных названа PointLightData, потому что UnityEngine уже определяет LightData, во избежание неоднозначности.

SetLightIntensity

// Возвращаемое значение: void
public void SetLightIntensity(float intensity)

Задаёт глобальную интенсивность освещения, используемую для затемнения сцены 3DGS перед переосвещением, чтобы предотвратить переэкспонирование.

ПараметрТипОписание
intensityfloatИнтенсивность освещения, в диапазоне [0, 1]

Пример использования:

m_manager.SetLightIntensity(0.5f);

Примечания:

  • Значение по умолчанию — 0.5.
  • Диапазон [0, 1]; значения вне диапазона ограничиваются автоматически.
  • Чем больше значение, тем темнее становится общая сцена 3DGS.

Структура данных PointLightData

public struct PointLightData {
    public float3 position;    // мировая позиция
    public int lightType;      // 0=точечный источник света, 1=прожекторный источник света
    public float3 color;       // цвет RGB (без компонента альфа)
    public float intensity;    // интенсивность света
    public float3 direction;   // направление прожектора (игнорируется для точечных источников света)
    public float range;        // дальность света
    public float spotAngle;    // угол конуса прожектора (в градусах, игнорируется для точечных источников света)
    public float3 pad;         // выравнивающее заполнение, назначать не нужно
}
ПолеТипОписание
positionfloat3Мировая позиция источника света
lightTypeint0 = точечный источник света, 1 = прожекторный источник света
colorfloat3Цвет RGB (без компонента альфа)
intensityfloatИнтенсивность света
directionfloat3Направление прожектора, игнорируется для точечных источников света
rangefloatДальность света
spotAnglefloatУгол конуса прожектора (в градусах), игнорируется для точечных источников света
padfloat3Выравнивающее заполнение, назначать не нужно