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

    • PortalCam P1

      • Product Overview
      • Basic Operation
      • Using the LCC Scan App
      • Maintenance and Care
      • FAQ
  • Lixel K Series

    • Lixel K1

      • Product Overview
      • Basic Operation
      • Device Activation and Connection
      • Scanning Workflow
      • Acquire Point Cloud Data with Absolute Coordinate
      • Map Fusion
      • Route Planning Suggestions for Typical Scenes
      • Precautions
      • FAQ
    • Lixel K2

      • Product Overview
      • Basic Operation
      • Device Activation and Connection
      • Scanning Workflow
      • Acquire Point Cloud Data with Absolute Coordinate
      • Map Fusion
      • Route Planning Suggestions for Typical Scenes
      • Precautions
      • FAQ
  • Lixel L Series

    • Lixel L2 Pro

      • Product Overview
      • Basic Operation
      • Device Activation and Connection
      • Scanning Workflow
      • Acquire Point Cloud Data with Absolute Coordinate
      • Measure Point
      • Appendix
      • FAQ
    • Lixel L3

      • Product Overview
      • Basic Device Functions
      • Device Activation and Connection
      • Data Capture
      • Capturing Absolute Coordinates
      • Appendix
  • Accessories

    • Stick Light

      • Installation Guide
      • Basic Operation
      • FAQ
  • Lixel Studio

    • Version and Copyright
    • Installation and Activation
    • Software Interface
    • File Operations
    • Project Processing
    • Tools
    • 2D Drawing
    • Applications
    • Settings
    • Device Connection
    • FAQ
  • Lixel CyberColor

    • LCC Studio

      • Getting Started
      • Version and Updates
      • Download and Installation
      • Interface Overview and Navigation
      • Before Reconstruction
      • Model Reconstruction
      • Single Model Reconstruction
      • Map Fusion
      • Aerial-Ground Fusion
      • Aerial Reconstruction
      • My Models
      • Other Features
      • Settings and Account
      • Converter
      • Video Reconstruction
      • FAQ
    • LCC Scene Editor

      • Version & Updates
      • Account & Login
      • Product Overview & Home
      • Editor Interface
      • Scene Navigation Modes
      • File
      • Settings
      • Edit Operations
      • Window
      • Global Toolbar
      • Assets & Properties
      • Left Toolbar
      • Viewpoints
      • Portal
      • Skybox
      • Annotations
      • Measurement
      • Flythrough
      • Scene Report
      • 3D Layout
      • Mini-Map
      • Preview Mode (Viewer)
      • Help
      • FAQ
      • Spawn Point
    • LCC Model Editor

      • Version and Updates
      • User Guide
      • Overview and Interface
      • File Operations
      • Selectors
      • Editing Models
      • Measurement
      • Color Grading
      • Asset Management
      • Settings and Help
      • FAQ
    • Capture Guide

      • Overview
      • Capture Devices Overview
      • General Capture Principles
      • Indoor Scene Capture
      • Outdoor Scene Capture
      • Large-Scale Capture (Map Fusion)
      • Aerial-Ground Map Fusion Capture
      • Object Capture
      • People Capture
      • Video Reconstruction Capture
      • HD Enhancement
      • Control Points (Lixel P1)
      • FAQ and Troubleshooting
    • LCC Studio Linux

      • Product Overview
      • Architecture Guide
      • Installation and Deployment Guide
      • Container Startup Parameters Guide
      • CodeMeter Offline Licensing Deployment Guide
      • API Reference
      • Appendix - Developer Data Guide
      • Appendix - Error Code List
      • Single-Machine Multi-GPU Cluster Deployment QuickStart
    • Best Practices

      • Merging Multiple Large 3DGS Models
    • Version History
  • Plugin & SDK

    • Unreal

      • Introduction
      • Quick Start - Windows
      • Quick Start - Linux
      • Quick Start - Quest3
      • Editions and Licensing
      • Rendering
      • Tiled Rasterization (Experimental)
      • Visual Settings
      • Normals and Lighting
      • Scene Editing
      • Performance Parameters
      • Performance Guide
      • Third-party and Engine Plugin Integration
      • Proxy Mesh
      • Loading Animation
      • Collision
      • Navigation System Support
      • Single Layer Water Support
      • Localization
      • FAQ
      • Troubleshooting
      • Logging and Diagnostics
      • Contact Us
      • Best Practices

        • Relighting 3DGS with a LixelStudio Mesh
      • API Reference

        • ALCCActorBase
        • ULCCComponentBase
        • ULCCComponent
        • ULCC2Component
        • SOG / SPZ / PLY Actors
        • ALCC2ProxyMesh
        • ALCCClippingVolume
        • ALCCSectionPlane
        • ALCCLoadVolume
        • ULCCUtilLibrary
        • Enums
        • Structs
      • Changelog

        • 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 Introduction
      • Technical Features
      • Development Environment Requirements
      • PC Quick Start Guide
      • Project Settings Optimization Guide
      • Pico 4 Ultra Development Guide
      • Pico 4 Ultra PC Streaming Guide
      • Quest 3 Development Guide
      • Quest 3 PC Streaming Guide
      • OpenXR Development Guide
      • Pico 4 Ultra Business Streaming Guide
      • Glossary
      • FAQ
      • Contact Us
      • Feature Development Guide

        • Multi-Scene Mixed Rendering Development Guide
        • Shadow Receiving Development Guide
        • Real-Time Lighting Development Guide
        • Multi-Camera Rendering Development Guide
        • High-Resolution Image Rendering Development Guide
        • LCC and LCC2 Data Format Compatibility Development Guide
        • Loading Effect Development Guide
        • Mip Rendering Mode Switching Development Guide
        • Edge and Corner Snapping Development Guide
        • Projected Decal Development Guide
        • Video Projected Decal Development Guide
        • Highlight Development Guide
        • Real-Time Clipping Development Guide
        • Color Adjustment Development Guide
        • Getting Scene Mesh Data Development Guide
        • Editor Mode Development Guide
        • Render Performance Parameter Configuration Guide
        • Application and Data Co-packaging Development Guide
        • Collision System Development Guide
        • macOS Development Permission Issue Guide
        • iOS Device Compilation and Packaging Development Guide
      • API Reference

        • LCCManager
        • Renderer
        • Data Types
      • Changelog

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

      • Introduction
      • Rendering Performance Optimization Guide
      • Graphics Configuration
      • FAQ
      • API Reference

        • LCCRender::clearIndexDB
        • LCCRender::dispose
        • LCCRender::load
        • LCCRender::setCamera
        • LCCRender::unload
        • LCCRender::update
        • LCCObject::checkRenderNextFrame
        • LCCObject::clearRenderNextFrame
        • LCCObject::ecef2Prj
        • LCCObject::getBounds
        • LCCObject::getEnvInstancedMesh
        • LCCObject::getInstancedMesh
        • LCCObject::getLodInfos
        • LCCObject::getOriginPosition
        • LCCObject::getProjectionCoordinateSystemInfos
        • LCCObject::hasCollision
        • LCCObject::hasEnvironment
        • LCCObject::hasShcoef
        • LCCObject::intersectsCapsule
        • LCCObject::intersectsRayExt
        • LCCObject::intersectsRayFromOriginExt
        • LCCObject::intersectsSphere
        • LCCObject::lowerToBottom
        • LCCObject::prj2Ecef
        • LCCObject::raiseToTop
        • LCCObject::raycast
        • LCCObject::raycastFromOrigin
        • LCCObject::setAlpha
        • LCCObject::setClipBox
        • LCCObject::setClipPlane
        • LCCObject::setEndLod
        • LCCObject::setLodAutoLevelUp
        • LCCObject::setMaxDistance
        • LCCObject::setMaxNodeSplats
        • LCCObject::setMaxSplats
        • LCCObject::setOriginPosition
        • LCCObject::setPointsColor
        • LCCObject::setRenderState
        • LCCObject::setRotation
        • LCCObject::setScale
        • LCCObject::setSemantic
        • LCCObject::setSemanticColor
        • LCCObject::setSmooth
        • LCCObject::setStartLod
        • LCCObject::setTranslation
        • LCCObject::setVisible
        • LCCObject::togglePointsDisplayMode
        • LCCObject::useEnvironment
        • LCCObject::useShcoef
      • Changelog

        • v0.6.3
        • v0.6.2
        • v0.6.1
        • v0.6.0
        • v0.5.5
        • v0.5.4
        • v0.5.3
        • v0.5.2
        • v0.5.1
        • v0.5.0
        • v0.4.1
        • v0.4.0
        • v0.3.1
        • v0.3.0
        • v0.2.0
    • Lixel OpenAPI

      • Overview
      • Connection & Authentication
      • Message Model & Codec
      • Interface Catalog
      • Real-time Data
      • Project File Access
      • Error Codes
      • Python

        • Quick Start
        • Client Wrapper & Tools
        • FAQ
      • C++

        • Quick Start
        • Client & Examples
        • FAQ

Color Adjustment Development Guide

The LCC Unity SDK supports editing operations such as highlighting, clipping, and color adjustment on 3DGS scenes. This guide introduces color adjustment operations: selecting an area through 2D projected textures, 3D geometry, or a mix of both, and adjusting the brightness, saturation, and contrast of the selected area, supporting normal selection and invert selection.

Note:

The current color adjustment feature is only a runtime display effect; it does not modify the original data file in any way and does not support saving or exporting the edit result. If you need to color-adjust, clip, and save data, use the XGRIDS LCC Editor software tool.

If you do not want to modify the data, you can also record the operations and replay them (execute the settings) after the data finishes loading next time.

Prerequisites

Color-adjusting a scene through the SDK requires the following conditions:

  1. Enter the edit state before loading data. The SDK is in the browsing state (View) by default, which provides the best performance and is recommended for normal browsing. To perform editing operations such as color adjustment, switch to the edit state via SetEditorMode(true) before calling Load. This method only takes effect if called before loading all the data.
  2. Perform the color adjustment operation after data finishes loading. The color adjustment interface needs to be called after the scene data has fully loaded.

Step 1: Set up the scene

Prepare the GameObjects needed for color adjustment in the scene:

  • Main Camera: the scene camera; 2D color adjustment uses its view and projection matrices.
  • LCCManager: an empty GameObject with a normalized Transform, with the LCCManager script added.
  • LCCRenderer: an empty GameObject with Transform set to Rotation.x = -90, Scale.x = -1 (aligned with the LCC data coordinate system), used to attach the Tone script written later.
  • 3D selection geometry (optional): auxiliary objects for 3D color adjustment. The example prepares one Cube (Box1); moving and scaling it controls the position and size of the 3D color adjustment selection.

Note:

For settings related to the rendering camera, LCCManager, and LCCRenderer GameObjects, refer to the relevant sections of PC Quick Start Guide and Project Settings Optimization Guide.

Step 2: Understand the data structure

Color adjustment uses the ToneMix data structure, which can describe both a 2D texture selection and a 3D geometry selection at the same time, and carries the color adjustment parameters. The enums and structs used are as follows.

public enum SelectMode    { normal, invert, clip }  // normal selection, invert, real-time clipping
public enum OperationMode { normal, erase }         // normal selection, erase selection
public enum ShapeType     { box, sphere }           // 3D Box selection, 3D Sphere selection
public enum EditType      { Edit2D, Edit3D }        // 2D edit, 3D edit

// Color adjustment selection
public struct ToneMix
{
    public EditType editType;       // edit type (required; determines whether 2D or 3D fields are used)
    public Texture2D texture;       // 2D mask texture (used by Edit2D)
    public Matrix4x4 mv;            // camera view matrix (used by Edit2D)
    public Matrix4x4 mvp;           // camera view projection matrix (used by Edit2D)
    public ShapeType type;          // geometry type (used by Edit3D)
    public Matrix4x4 invMat;        // geometry inverse matrix (used by Edit3D)
    public OperationMode operation; // operation type (used by Edit3D)
    public SelectMode mode;         // selection mode (required)

    public float brightness;        // brightness, range [0, 3], default 1.0
    public float saturation;        // saturation, range [0, 3], default 1.0
    public float contrast;          // contrast, range [0, 3], default 1.0
    public int lutid;               // LUT table index (reserved), 0 means not used
}

There are three points to note about the color adjustment list:

  1. The list is ordered. Whether 2D or 3D, entries in the list take effect in order; make sure the order of addition matches your expectation.
  2. Invert must carry color adjustment data. This is the most critical difference between color adjustment and highlight/clipping — the invert of highlight/clipping is a pure command and does not need to be associated with data; but the invert entry of color adjustment, besides mode = SelectMode.invert, must also set brightness, saturation, and contrast, to specify the color adjustment effect for the area outside the selection.
  3. The maximum number of entries in a single list is 255. Exceeding it returns an error code.

Step 3: Understand the color adjustment APIs

All color-adjustment-related interfaces are provided by LCCManager, including one SetTone method and one exit method.

SetTone

// Return value: int
// 0: success
// 1: list is null or has 0 elements
// 2: list elements exceed the maximum of 255
public int SetTone(List<ToneMix> _Mix)

Performs color adjustment on the selected area, supporting brightness, saturation, and contrast adjustments. 2D texture entries and 3D geometry entries can be mixed in the same list.

QuitToneMode

// Return value: void
public void QuitToneMode()

Exits color adjustment mode and restores the scene's original colors.

Tip:

When switching color adjustment parameters or clearing the current color adjustment, call QuitToneMode() first and then set the new color adjustment.

Step 4: 2D mask texture specification

2D color adjustment describes the selection through a mask texture, supporting various selection methods such as quadrilaterals, triangles, brushes, and lassos — simply mark the corresponding pixels in the texture with the selected value. When using 2D operations, the camera should be locked and the texture marked from a fixed viewpoint. The texture and pixel values have the following conventions:

  • The texture is fixed at 1024 × 1024, R8 single channel, no Mipmap, point filtering (FilterMode.Point), and clamped sampling (TextureWrapMode.Clamp).
  • Pixel value conventions:
Pixel valueMeaning
128Default (not selected)
240Selected
180Deselect (erase the already selected area)
0Clipping

In a color adjustment scenario, only the two values 128 (default) and 240 (selected) are usually used.

Step 5: Write the script

Create a new C# script named Tone.cs. First complete the basic skeleton: in Start, enter the edit state and load data; after loading completes, set the load flag for the subsequent color adjustment methods to check.

using LCCCore;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Tone : MonoBehaviour
{
    public LCCManager m_manager;
    public string m_FilePath;
    public GameObject m_Box1;
    public Slider m_brightness;
    public Slider m_saturation;
    public Slider m_contrast;

    private LCCCore.Renderer m_renderer;
    private Camera m_camera;
    private bool m_isLoaded = false;

    void Start()
    {
        m_camera = Camera.main;
        m_manager.SetPlatformType(PlatformType.PC);

        // Enter edit mode; must be called before Load
        m_manager.SetEditorMode(true);

        m_renderer = m_manager.GetRender(this.transform);
        if (m_renderer == null)
            Debug.LogError("GetRender failed, check if the manager is set correctly and the file path is valid.");

        m_renderer.Load(m_FilePath, onLoadProgress, onLoadCallback);
    }

    private void onLoadProgress(float value)
    {
        Debug.Log($"loading progress: {value}");
    }

    private void onLoadCallback()
    {
        Debug.Log("data loaded !!!");
        m_isLoaded = true;
    }

    // Color adjustment methods below
}

Note:

SetEditorMode(true) must be called before Load to take effect; and SetTone must be called after data finishes loading (after the onLoadCallback callback fires). The three sliders m_brightness, m_saturation, and m_contrast are used to dynamically adjust the color adjustment parameters at runtime and can be used as needed.

Step 6: Attach the script and set properties

  1. Attach the Tone.cs script to the LCCRenderer GameObject.
  2. In the Inspector window, drag the LCCManager GameObject onto the script's Manager property.
  3. Fill in the LCC file path in the File Path property.
  4. Drag Box1 in the scene onto the script's Box1 property, and drag the three sliders onto the Brightness, Saturation, and Contrast properties respectively, for 3D color adjustment and runtime parameter adjustment.
Set the Tone script properties in the Inspector

Set the Tone script properties in the Inspector

Step 7: Color adjustment operation examples

Add the methods below to the Tone class, and call the corresponding method after running and after data finishes loading.

Normal color adjustment

Construct an R8 mask texture, mark the pixels to color-adjust as 240 and the rest as 128, then construct ToneMix with the camera matrices, set brightness, saturation, and contrast, and add it to the list.

public void onTone()
{
    // Texture size is fixed at 1024*1024; keep other properties the same as the example
    Texture2D _texture = new Texture2D(1024, 1024, TextureFormat.R8, false);
    _texture.filterMode = FilterMode.Point;
    _texture.wrapMode = TextureWrapMode.Clamp;

    int _count = 1024 * 1024;
    int _half = _count / 2;
    byte[] _values = new byte[_count];
    for (int i = 0; i < _count; i++)
    {
        if (i < _half)
            _values[i] = 128;    // 128 means default, 240 means selected, 0 means clipping
        else
            _values[i] = 240;
    }
    _texture.SetPixelData(_values, 0);

    List<ToneMix> _tMixs = new List<ToneMix>();
    ToneMix _tmix01 = new ToneMix();
    _tmix01.editType = EditType.Edit2D;
    _tmix01.mv = m_camera.worldToCameraMatrix * this.transform.localToWorldMatrix;
    _tmix01.texture = _texture;
    _tmix01.mode = SelectMode.normal;
    _tmix01.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix * this.transform.localToWorldMatrix;
    _tmix01.brightness = 2.0f;
    _tmix01.saturation = 2.0f;
    _tmix01.contrast = 0.4f;
    _tMixs.Add(_tmix01);

    m_manager.SetTone(_tMixs);
}

Code explanation: a mask texture is built that selects the upper half of the screen (the screen origin is the lower-left corner), and a color adjustment of brightness 2.0, saturation 2.0, and contrast 0.4 is applied to the selected area. The example effect is as follows.

In actual use, you can use various selection tools such as rectangles, triangles, brushes, and lassos to select the corresponding positions on the mask, and also dynamically pass the values of brightness, saturation, and contrast through sliders.

Normal color adjustment effect

Normal color adjustment effect

Invert color adjustment

The invert of color adjustment differs from highlight and clipping: the invert entry, besides setting mode = SelectMode.invert, must carry color adjustment data (brightness, saturation, contrast) to specify the color adjustment effect for the area outside the selection. Based on the normal color adjustment above, simply append an invert entry.

public void onToneInvert()
{
    // Texture size is fixed at 1024*1024; keep other properties the same as the example
    Texture2D _texture = new Texture2D(1024, 1024, TextureFormat.R8, false);
    _texture.filterMode = FilterMode.Point;
    _texture.wrapMode = TextureWrapMode.Clamp;

    int _count = 1024 * 1024;
    int _half = _count / 2;
    byte[] _values = new byte[_count];
    for (int i = 0; i < _count; i++)
    {
        if (i < _half)
            _values[i] = 128;    // 128 means default, 240 means selected, 0 means clipping
        else
            _values[i] = 240;
    }
    _texture.SetPixelData(_values, 0);

    List<ToneMix> _tMixs = new List<ToneMix>();

    // Normal selection color adjustment
    ToneMix _tmix01 = new ToneMix();
    _tmix01.editType = EditType.Edit2D;
    _tmix01.mv = m_camera.worldToCameraMatrix * this.transform.localToWorldMatrix;
    _tmix01.texture = _texture;
    _tmix01.mode = SelectMode.normal;
    _tmix01.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix * this.transform.localToWorldMatrix;
    _tmix01.brightness = 2.0f;
    _tmix01.saturation = 2.0f;
    _tmix01.contrast = 0.4f;
    _tMixs.Add(_tmix01);

    // Invert: must carry color adjustment data (brightness/saturation/contrast), not a pure command
    ToneMix _tmix02 = new ToneMix();
    _tmix02.editType = EditType.Edit2D;
    _tmix02.mode = SelectMode.invert;
    _tmix02.brightness = 0.5f;
    _tmix02.saturation = 0.5f;
    _tmix02.contrast = 2.0f;
    _tMixs.Add(_tmix02);

    m_manager.SetTone(_tMixs);
}

Code explanation: an invert entry is appended on top of the normal color adjustment, applying a color adjustment of brightness 0.5, saturation 0.5, and contrast 2.0 to the area outside the selection. This way, different color adjustment parameters can be applied inside and outside the selection. The example effect is as follows.

Invert color adjustment effect

Invert color adjustment effect

Note:

The invert of highlight and clipping is a pure command: appending an entry with mode = SelectMode.invert is enough, with no other data required. But the invert entry of color adjustment must also set brightness, saturation, and contrast; otherwise the inverted area uses the default values (1.0) and does not achieve the expected effect.

Step 8: Exit color adjustment

Call QuitToneMode() to clear the current color adjustment and restore the scene's original colors.

public void onToneClear()
{
    m_manager.QuitToneMode();
}

Key Steps

The key steps for color-adjusting a 3DGS scene:

  1. Call SetEditorMode(true) before loading data to enter the edit state.
  2. Call SetTone after data finishes loading (after the onLoadCallback callback fires, or triggered through a button/event).
  3. Control the color adjustment effect through ToneMix's brightness, saturation, and contrast (range [0, 3], default 1.0), and make sure the color adjustment list's order of addition matches your expectation.
  4. The 2D mask texture is fixed at 1024 × 1024, R8 single channel; fill pixel values per convention (128 default, 240 selected).
  5. The color adjustment invert (SelectMode.invert) must carry brightness, saturation, and contrast data — this is the key difference from highlight/clipping invert.
  6. When clearing or switching color adjustment, call QuitToneMode() first.