Guide de développement de l'éclairage en temps réel
Le LCC Unity SDK prend en charge l'éclairage en temps réel provenant d'éclairages ponctuels et de spots dynamiques. Ce qui suit utilise l'exemple d'un éclairage ponctuel se déplaçant le long d'un chemin circulaire pour décrire les étapes complètes de mise en œuvre de l'éclairage en temps réel.
Étape 1 : Créer la scène et les GameObjects
Créez une toute nouvelle scène dans Unity. Unity crée Caméra principale et Lumière directionnelle par défaut.
Configurer la Caméra principale
Sélectionnez Caméra principale dans la fenêtre Hiérarchie, et définissez ses propriétés dans la fenêtre Inspecteur comme illustré ci-dessous.

Définir les propriétés de la Caméra principale
Créer LCCManager
Faites un clic droit dans une zone vide de la fenêtre Hiérarchie, sélectionnez Créer vide dans le menu contextuel pour créer un GameObject vide, nommez-le LCCManager, normalisez son Transform, et ajoutez-y le script LCCManager via Ajouter un composant.

Créer le GameObject LCCManager et ajouter le script LCCManager
Créer LCCRenderer
Faites un clic droit dans une zone vide de la fenêtre Hiérarchie, sélectionnez Créer vide pour créer un GameObject vide, nommez-le LCCRenderer, et définissez son Transform sur Rotation.x = -90 et Scale.x = -1.

Créer LCCRenderer et définir son Transform (Rotation.x = -90, Scale.x = -1)
Remarque :
Les réglages de Transform du GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) l'alignent avec le système de coordonnées des données LCC. Pour plus de détails sur l'alignement du système de coordonnées, voir « Système de coordonnées des données LCC » dans Introduction au SDK Unity.
Étape 2 : Écrire un script pour envoyer les lumières
Créez un nouveau script C# nommé Relighting.cs avec le code suivant :
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("Paramètres de l'éclairage ponctuel")]
public Vector3 pointLightPosition = new Vector3(0, 2, 0);
public Color pointLightColor = Color.red;
public float pointLightIntensity = 2.0f;
public float pointLightRange = 3.0f;
[Header("Paramètres du spot")]
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] progression du chargement : {_progress:P1}");
}
private void onComplete()
{
Debug.Log("[Relighting] chargement terminé, configuration des lumières");
//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 = éclairage ponctuel
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 = spot
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] échec de SetLights : {result}");
}
void OnDisable()
{
// Passer null pour désactiver l'éclairage personnalisé
m_manager.SetLights(null);
}
}
Remarque :
- L'éclairage en temps réel doit être envoyé après la fin du chargement de la scène LCC, donc le premier
ApplyLights()est appelé dans le callbackonComplete.- Cet exemple actualise la position de la lumière à chaque image dans
Updatepour animer l'éclairage ponctuel se déplaçant le long d'un chemin circulaire.- Le type du champ de lumière est
Unity.Mathematics.float3, ce qui nécessiteusing Unity.Mathematics;.colorn'a que trois composantes RGB et pas d'alpha.
Étape 3 : Attacher le script et définir le chemin des données
- Attachez le script
Relighting.csau GameObject LCCManager dans la fenêtre Hiérarchie. - Dans la fenêtre Inspecteur, faites glisser le GameObject LCCManager sur la propriété Manager du script.
- Renseignez le chemin du fichier LCC dans la propriété File Path du script.
- Les propriétés restantes d'éclairage ponctuel, de spot et d'animation peuvent être configurées librement.

Attacher le script Relighting et définir ses propriétés dans l'Inspecteur
Dans cet exemple, un éclairage ponctuel et un spot sont créés, et l'éclairage ponctuel se déplace le long d'un chemin circulaire pour démontrer l'effet d'éclairage en temps réel.
Étape 4 : Exécuter
Cliquez sur le bouton Play dans la fenêtre Jeu pour voir l'effet d'éclairage en temps réel dans la scène.

Effet d'éclairage en temps réel dans la scène 3DGS après l'exécution
Particularités de l'éclairage 3DGS
L'éclairage en 3DGS diffère grandement de l'éclairage traditionnel des modèles Mesh. L'effet d'éclairage en 3DGS est écrit directement dans la couleur RGB, ce qui signifie que l'éclairage est « cuit » dans les composantes de couleur rendues. Par conséquent, si un modèle 3DGS a été capturé par une journée ensoleillée avec des ombres dures très fortes, le ré-éclairage ne peut pas supprimer ces ombres déjà cuites.
De plus, la plage de couleurs pendant le rendu est [0, 1]. Si vous renforcez directement l'éclairage sans aucun traitement, une surexposition se produira. Pour éviter la surexposition, vous assombrissez généralement d'abord la scène 3DGS avant de la ré-éclairer.
Dans le SDK, l'intensité de l'éclairage peut être ajustée via LCCManager.SetLightIntensity(float _intensity) :
- Le paramètre d'entrée
_intensityest compris dans[0, 1]. - Cette fonction affecte l'effet d'éclairage global : plus l'intensité lumineuse configurée est forte, plus la scène 3DGS est poussée vers l'obscurité.
- La valeur par défaut est
0.5.
Conseil :
Le calcul de l'éclairage est une opération relativement coûteuse. Le SDK prend en charge un maximum de 50 lumières dynamiques (éclairages ponctuels et spots combinés). Lorsque la limite est dépassée,
SetLightsretourne-1et ne prend aucun effet.
Étapes clés
Les étapes clés pour ajouter un éclairage en temps réel à une scène 3DGS :
- Terminez la pré-configuration de
SetPlatformType/SwitchRenderPass/SetMainCamera, et chargez la scène LCC viaGetRender+Load. - Après la fin du chargement de la scène (dans le callback
onComplete), construisez la listePointLightDataet appelezSetLightspour envoyer les lumières. - Lorsqu'une animation est nécessaire, mettez à jour les paramètres de lumière dans
Updateet appelez à nouveauSetLights. - Si une surexposition se produit, utilisez
SetLightIntensitypour assombrir d'abord la scène avant de ré-éclairer. - Pour désactiver l'éclairage en temps réel, passez
nullou une liste vide àSetLights.
API d'éclairage en temps réel
Le LCC Unity SDK fournit les deux API d'éclairage en temps réel suivantes via LCCManager. Elles doivent toutes deux être appelées après la fin du chargement de la scène LCC (c'est-à-dire dans le callback onComplete).
SetLights
// Valeur de retour : int → 0 = succès, -1 = limite maximale de nombre dépassée
public int SetLights(List<PointLightData> lights)
Définit la liste d'éclairages ponctuels personnalisés. Passer null ou une liste vide désactive l'éclairage personnalisé.
| Paramètre | Type | Description |
|---|---|---|
lights | List<PointLightData> | Liste de lumières (jusqu'à 50 éclairages ponctuels et spots combinés) |
Exemple d'utilisation :
using Unity.Mathematics; // float3
var lights = new List<PointLightData>();
lights.Add(new PointLightData {
position = new float3(0, 5, 0),
lightType = 0, // 0=éclairage ponctuel, 1=spot
color = new float3(1, 1, 1),
intensity = 2f,
range = 10f
});
m_manager.SetLights(lights);
Remarques :
- Le type de champ est
Unity.Mathematics.float3, pasVector4;colorn'a pas de composante alpha. lightType:0= éclairage ponctuel (ignoredirection/spotAngle),1= spot (nécessitedirection/spotAngle).- Le nombre maximum est de 50 (éclairages ponctuels et spots combinés) ; retourne
-1lorsqu'il est dépassé. - Passer
nullou une liste vide désactive l'éclairage personnalisé. - Lorsqu'il est activé, le mot-clé de shader
_USERLIGHTest activé. - La structure de données est nommée PointLightData car UnityEngine définit déjà LightData, afin d'éviter toute ambiguïté.
SetLightIntensity
// Valeur de retour : void
public void SetLightIntensity(float intensity)
Définit l'intensité lumineuse globale, utilisée pour assombrir la scène 3DGS avant le ré-éclairage afin d'éviter la surexposition.
| Paramètre | Type | Description |
|---|---|---|
intensity | float | Intensité lumineuse, dans la plage [0, 1] |
Exemple d'utilisation :
m_manager.SetLightIntensity(0.5f);
Remarques :
- La valeur par défaut est
0.5. - Plage
[0, 1]; les valeurs hors plage sont automatiquement bornées. - Plus la valeur est grande, plus la scène 3DGS globale est poussée vers l'obscurité.
Structure de données PointLightData
public struct PointLightData {
public float3 position; // position mondiale
public int lightType; // 0=éclairage ponctuel, 1=spot
public float3 color; // couleur rgb (sans composante alpha)
public float intensity; // intensité lumineuse
public float3 direction; // direction du spot (ignorée pour les éclairages ponctuels)
public float range; // portée de la lumière
public float spotAngle; // angle du cône du spot (degrés, ignoré pour les éclairages ponctuels)
public float3 pad; // remplissage d'alignement, aucune assignation nécessaire
}
| Champ | Type | Description |
|---|---|---|
position | float3 | Position mondiale de la lumière |
lightType | int | 0 = éclairage ponctuel, 1 = spot |
color | float3 | Couleur RGB (sans composante alpha) |
intensity | float | Intensité lumineuse |
direction | float3 | Direction du spot, ignorée pour les éclairages ponctuels |
range | float | Portée de la lumière |
spotAngle | float | Angle du cône du spot (degrés), ignoré pour les éclairages ponctuels |
pad | float3 | Remplissage d'alignement, aucune assignation nécessaire |