調色開發指南
LCC Unity SDK 支持對 3DGS 場景進行高亮、裁剪、調色等編輯操作。本文介紹調色相關操作:通過 2D 投影紋理、3D 幾何體或二者混合的方式圈選區域,對選中區域調整亮度、飽和度、對比度,支持正選、反選等操作。
注意:
當前調色功能僅是運行時的顯示效果,不會對原始數據文件產生任何修改,也不支持將編輯結果保存導出。如果需要調色、裁剪並保存數據,請使用其域創新(XGrids)LCC Editor 軟件工具處理。
如果不希望修改數據,也可以將操作記錄下來,下次在數據加載完成後重放操作(執行設置)。
前置條件
通過 SDK 對場景進行調色,需要滿足以下條件:
- 在加載數據之前進入編輯狀態。 SDK 默認處於瀏覽狀態(View),該狀態能提供最佳性能,正常瀏覽時建議保持。要進行調色等編輯操作,需在
Load數據之前通過SetEditorMode(true)切換到編輯狀態。該方法只在加載所有數據之前調用才有效。 - 在數據加載完成後再執行調色操作。 調色接口需要在場景數據完全加載後調用。
步驟 1:搭建場景
在場景中準備好調色所需的遊戲對象:
- Main Camera:場景相機,2D 調色會用到它的視圖與投影矩陣。
- LCCManager:空遊戲對象,Transform 歸一,添加
LCCManager腳本。 - LCCRenderer:空遊戲對象,Transform 設置為 Rotation.x = -90、Scale.x = -1(與 LCC 數據座標系對齊),用於掛載後面編寫的
Tone腳本。 - 3D 選區幾何體(可選):用於 3D 調色的輔助對象,示例中準備了一個 Cube(
Box1),移動、縮放它即可控制 3D 調色選區的位置和大小。
注意:
渲染相機、LCCManager、LCCRenderer 遊戲對象(GameObject)相關設置請參照PC 快速開發入門指南、工程設置優化指南 相關章節。
步驟 2:了解數據結構
調色使用 ToneMix 數據結構,可同時描述 2D 紋理選區和 3D 幾何體選區,並攜帶調色參數。用到的枚舉和結構體如下。
public enum SelectMode { normal, invert, clip } // 正常選區、反選、實時裁剪
public enum OperationMode { normal, erase } // 正常選區、擦除選區
public enum ShapeType { box, sphere } // 3D Box 選區、3D Sphere 選區
public enum EditType { Edit2D, Edit3D } // 2D 編輯、3D 編輯
// 調色選區
public struct ToneMix
{
public EditType editType; // 編輯類型(必填,決定使用 2D 還是 3D 字段)
public Texture2D texture; // 2D 蒙版紋理(Edit2D 使用)
public Matrix4x4 mv; // 相機視圖矩陣(Edit2D 使用)
public Matrix4x4 mvp; // 相機視圖投影矩陣(Edit2D 使用)
public ShapeType type; // 幾何體類型(Edit3D 使用)
public Matrix4x4 invMat; // 幾何體逆變換矩陣(Edit3D 使用)
public OperationMode operation; // 操作類型(Edit3D 使用)
public SelectMode mode; // 選擇模式(必填)
public float brightness; // 亮度,範圍 [0, 3],默認 1.0
public float saturation; // 飽和度,範圍 [0, 3],默認 1.0
public float contrast; // 對比度,範圍 [0, 3],默認 1.0
public int lutid; // LUT 表索引(預留),0 表示不使用
}
關於調色列表,有三點需要注意:
- 列表是有序的。 無論 2D 還是 3D,列表中的條目按順序依次生效,請確保添加順序符合預期。
- 反選(invert)必須攜帶調色數據。 這是調色與高亮、裁剪最關鍵的不同之處——高亮、裁剪的反選是純指令,可不關聯數據;而調色的反選條目除了
mode = SelectMode.invert,還必須設置brightness、saturation、contrast,用於指定選區之外區域的調色效果。 - 單個列表的條目數量上限為 255。 超出會返回錯誤碼。
步驟 3:了解調色 API
調色相關接口都由 LCCManager 提供,包含一個 SetTone 方法和一個退出方法。
SetTone
// 返回值:int
// 0:執行成功
// 1:列表為 null 或元素個數為 0
// 2:列表元素超出最大值 255
public int SetTone(List<ToneMix> _Mix)
對選定區域進行調色處理,支持亮度、飽和度、對比度調整。2D 紋理條目與 3D 幾何體條目可在同一個列表中混合使用。
QuitToneMode
// 返回值:void
public void QuitToneMode()
退出調色模式,恢復場景原始色彩。
提示:
切換調色參數或清除當前調色時,先調用
QuitToneMode()再設置新的調色。
步驟 4:2D 蒙版紋理規範
2D 調色通過一張蒙版紋理來描述選區,可支持四邊形、三角形、筆刷、套索等各種圈選方式——在紋理上把對應像素標記為選中值即可。使用 2D 操作時應鎖定相機,在固定視角下標識紋理。紋理和像素值有如下約定:
- 紋理規格固定為 1024 × 1024,
R8單通道,不生成 Mipmap,使用點濾波(FilterMode.Point),採樣夾斷(TextureWrapMode.Clamp)。 - 像素值約定:
| 像素值 | 含義 |
|---|---|
128 | 默認(未選中) |
240 | 選中 |
180 | 減選(擦除已選區域) |
0 | 裁剪 |
在調色場景下,通常只用到 128(默認)和 240(選中)兩個值。
步驟 5:編寫腳本
新建一個 C# 腳本,命名為 Tone.cs。先完成基礎框架:在 Start 中進入編輯狀態並加載數據,加載完成後置位加載標記,供後續調色方法判斷。
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);
// 進入編輯狀態,必須在 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;
}
// 調色方法見下文
}
注意:
SetEditorMode(true)必須在Load之前調用才有效;而SetTone必須在數據加載完成(onLoadCallback回調觸發)之後調用。m_brightness、m_saturation、m_contrast三個 Slider 用於在運行時動態調整調色參數,可按需使用。
步驟 6:掛載腳本並設置屬性
- 將
Tone.cs腳本掛載到 LCCRenderer 遊戲對象上。 - 在 Inspector 窗口中,將 LCCManager 遊戲對象拖動到腳本的 Manager 屬性上。
- 在 File Path 屬性中填寫 LCC 文件的路徑地址。
- 將場景中的
Box1拖動到腳本的 Box1 屬性上,將三個 Slider 分別拖動到 Brightness、Saturation、Contrast 屬性上,用於 3D 調色與運行時參數調整。

在 Inspector 中設置 Tone 腳本的屬性
步驟 7:調色操作示例
將下面的方法補充到 Tone 類中,並在運行、數據加載完成後調用對應方法。
正常調色
構造一張 R8 蒙版紋理,把要調色的像素標記為 240、其餘標記為 128,再用相機矩陣構造 ToneMix,設置 brightness、saturation、contrast 後加入列表。
public void onTone()
{
// 紋理尺寸固定 1024*1024,其它屬性保持與示例一致
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 表示默認,240 表示選中,0 表示裁剪
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);
}
代碼解釋 : 構建了一張紋理蒙板,將屏幕上半區域選中(屏幕以左下角為原點),對選中區域應用亮度 2.0、飽和度 2.0、對比度 0.4 的調色,示例效果如下。
在實際使用時,可使用矩形框、三角形、筆刷、套索等各種圈選工具對蒙板對應位置進行選擇,也可通過 Slider 動態傳入 brightness、saturation、contrast 的值。

正常調色效果
反選調色
調色的反選與高亮、裁剪不同:反選條目除了設置 mode = SelectMode.invert,還必須攜帶調色數據(brightness、saturation、contrast),用於指定選區之外區域的調色效果。在上面正常調色的基礎上,追加一個反選條目即可。
public void onToneInvert()
{
// 紋理尺寸固定 1024*1024,其它屬性保持與示例一致
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 表示默認,240 表示選中,0 表示裁剪
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);
// 反選:必須攜帶調色數據(brightness/saturation/contrast),不是純指令
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);
}
代碼解釋 : 在正常調色的基礎上追加了一個反選條目,為選區之外的區域應用亮度 0.5、飽和度 0.5、對比度 2.0 的調色。這樣選區內外可應用不同的調色參數,示例效果如下。

反選調色效果
注意:
高亮、裁剪的反選是純指令,追加一個
mode = SelectMode.invert的條目即可,無需其它數據;而調色的反選條目必須同時設置brightness、saturation、contrast,否則反選區域會使用默認值(1.0),達不到預期效果。
步驟 8:退出調色
調用 QuitToneMode() 即可清除當前調色,恢復場景原始色彩。
public void onToneClear()
{
m_manager.QuitToneMode();
}
關鍵步驟
對 3DGS 場景進行調色的關鍵步驟:
- 在
Load數據之前調用SetEditorMode(true)進入編輯狀態。 - 在數據加載完成後(
onLoadCallback回調觸發 或者通過按鈕/事件觸發)再調用SetTone。 - 通過
ToneMix的brightness、saturation、contrast(範圍[0, 3],默認1.0)控制調色效果,並保證調色列表的添加順序符合預期。 - 2D 蒙版紋理固定為 1024 × 1024、
R8單通道,按約定填充像素值(128默認、240選中)。 - 調色的反選(
SelectMode.invert)必須攜帶brightness、saturation、contrast數據,這是與高亮、裁剪反選的關鍵差異。 - 需要清除或切換調色時,先調用
QuitToneMode()。