Руководство по разработке подсветки
LCC Unity SDK поддерживает операции редактирования, такие как подсветка и обрезка, на сценах 3DGS. Это руководство знакомит с операциями, связанными с подсветкой: выделение области через 2D-проецируемые текстуры, 3D-геометрию или их смесь, чтобы выбранная область была подсвечена, с поддержкой обычного выделения и инвертированного выделения.
Примечание:
Текущая функция подсветки — это только эффект отображения во время выполнения; она никак не изменяет исходный файл данных и не поддерживает сохранение или экспорт результата редактирования. Если нужно выполнить коррекцию цвета, обрезку и сохранить данные, используйте программный инструмент XGRIDS LCC Editor.
Если вы не хотите изменять данные, можно также записать операции и воспроизвести их после следующего завершения загрузки данных.
Предварительные требования
Для подсветки сцены через SDK требуются следующие условия:
- Войдите в состояние редактирования перед загрузкой данных. По умолчанию SDK находится в состоянии просмотра (View), которое обеспечивает наилучшую производительность и рекомендуется для обычного просмотра. Для выполнения операций редактирования, таких как подсветка, переключитесь в состояние редактирования через
SetEditorMode(true)перед вызовомLoad. Этот метод действует только если вызван до загрузки всех данных. - Выполняйте операцию подсветки после завершения загрузки данных. Интерфейс подсветки должен вызываться после полной загрузки данных сцены.
Шаг 1: Настройте сцену
Подготовьте GameObject, необходимые для подсветки, в сцене, как показано ниже.

Структура иерархии сцены для примера подсветки
- Main Camera: камера сцены; 2D-подсветка использует её матрицы вида и проекции.
- LCCManager: пустой GameObject с нормализованным Transform, с добавленным скриптом
LCCManager. - LCCRenderer: пустой GameObject с Transform, заданным как Rotation.x = -90, Scale.x = -1 (выровнен с системой координат данных LCC), используемый для прикрепления скрипта
Highlight, написанного позже. - 3D-геометрия выделения: вспомогательные объекты для 3D-подсветки. В примере подготовлены 3 Cube (
Box1,Box2,Box3) и 1 Sphere (Clipsphere); перемещение и масштабирование этих объектов управляет позицией и размером выделения подсветки.
Примечание:
По настройкам, связанным с камерой рендеринга, GameObject LCCManager и LCCRenderer, см. соответствующие разделы Руководство по быстрому старту для PC и Руководство по оптимизации настроек проекта.

Геометрия выделения, используемая для 3D-подсветки (Box1 / Box2 / Box3 / Clipsphere)
Шаг 2: Разберитесь в структурах данных
Подсветка включает три способа операции — 2D, 3D и смешанный 2D/3D. Используемые перечисления и структуры следующие.
public enum SelectMode { normal, invert, clip } // обычное выделение, инверсия, обрезка в реальном времени
public enum OperationMode { normal, erase } // обычное выделение, стирание выделения
public enum ShapeType { box, sphere } // выделение 3D-боксом, выделение 3D-сферой
public enum EditType { Edit2D, Edit3D } // 2D-редактирование, 3D-редактирование
// выделение 2D-текстурой
public struct Data2D
{
public Texture2D texture; // 2D-текстура маски
public Matrix4x4 mv; // матрица вида камеры
public Matrix4x4 mvp; // матрица вида-проекции камеры
public SelectMode mode; // режим выделения
}
// выделение 3D-геометрией
public struct Data3D
{
public ShapeType type; // тип геометрии (бокс / сфера)
public Matrix4x4 invMat; // матрица геометрии из мира в локальные координаты (обратная)
public OperationMode operation; // тип операции (обычное объединение / стирание-разность)
public SelectMode mode; // режим выделения
}
// смешанное выделение 2D / 3D
public struct DataMix
{
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; // режим выделения (обязательное)
}
О списке выделения следует отметить три момента:
- Список упорядочен. Будь то 2D или 3D, записи в списке вступают в силу по порядку; убедитесь, что порядок добавления соответствует вашим ожиданиям.
- Инверсия — это команда операции, и её не нужно связывать с конкретными данными выделения. Просто добавьте запись с
mode = SelectMode.invert, чтобы инвертировать текущую выделенную область. - Максимальное количество записей в одном списке — 255. При превышении возвращается код ошибки.
Шаг 3: Разберитесь в API подсветки
Все интерфейсы, связанные с подсветкой, предоставляются LCCManager, включая три перегрузки SetHighlight и один метод выхода.
SetHighlight (подсветка 2D-текстурой)
// Возвращаемое значение: int
// 0: успех
// 1: список равен null или имеет 0 элементов
// 2: элементы списка превышают максимум 255
public int SetHighlight(List<Data2D> _2Ds)
Подсвечивает сцену с помощью 2D-проецируемой текстуры маски; часть вне подсвеченной области затемняется.
SetHighlight (подсветка 3D-геометрией)
// Возвращаемое значение: int
// 0: успех
// 1: список равен null или имеет 0 элементов
// 2: элементы списка превышают максимум 255
// 3: количество боксов геометрии выделения равно 0
public int SetHighlight(List<Data3D> _3Ds)
Определяет область подсветки с помощью 3D-геометрии (прямоугольный параллелепипед, куб, сфера), поддерживая комбинации объединения и разности. Требуется хотя бы одна геометрия с operation == OperationMode.normal.
SetHighlight (подсветка в смешанном режиме)
// Возвращаемое значение: int
// 0: успех
// 1: список равен null или имеет 0 элементов
// 2: элементы списка превышают максимум 255
public int SetHighlight(List<DataMix> _Mix)
Определяет область подсветки с помощью 2D-текстур и 3D-геометрии одновременно; каждая запись определяет, обрабатывается ли она как 2D или 3D, через editType.
QuitHighlightMode
// Возвращаемое значение: void
public void QuitHighlightMode()
Выходит из режима подсветки и восстанавливает обычное отображение сцены.
Совет:
Три перегрузки
SetHighlightвзаимно исключают друг друга. При переключении способов подсветки или очистке текущей подсветки сначала вызовитеQuitHighlightMode(), а затем задайте новую подсветку.
Шаг 4: Спецификация 2D-текстуры маски
2D-подсветка описывает выделение через текстуру маски, поддерживая различные способы выделения, такие как четырёхугольники, треугольники, кисти и лассо — просто пометьте соответствующие пиксели в текстуре выбранным значением. При использовании 2D-операций камера должна быть заблокирована, а текстура помечена с фиксированной точки обзора. Для текстуры и значений пикселей действуют следующие соглашения:
- Текстура фиксирована на 1024 × 1024,
R8один канал, без Mipmap, точечная фильтрация (FilterMode.Point) и зажатое сэмплирование (TextureWrapMode.Clamp). - Соглашения о значениях пикселей:
| Значение пикселя | Значение |
|---|---|
128 | По умолчанию (не выделено) |
240 | Выделено |
180 | Снять выделение (стереть уже выделенную область) |
0 | Обрезка |
В сценарии подсветки обычно используются только два значения — 128 (по умолчанию) и 240 (выделено).
Шаг 5: Напишите скрипт
Создайте новый скрипт C# с именем Highlight.cs. Сначала завершите базовый каркас: в Start войдите в состояние редактирования и загрузите данные; после завершения загрузки установите флаг загрузки для проверки последующими методами подсветки.
using LCCCore;
using System.Collections.Generic;
using UnityEngine;
public class Highlight : MonoBehaviour
{
public LCCManager m_manager;
public string m_FilePath;
public GameObject m_Box1;
public GameObject m_Box2;
public GameObject m_Box3;
public GameObject m_Clipsphere;
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 завершился ошибкой: проверьте, правильно ли задан manager и валиден ли путь к файлу.");
m_renderer.Load(m_FilePath, onLoadProgress, onLoadCallback);
}
private void onLoadProgress(float value)
{
Debug.Log($"прогресс загрузки: {value}");
}
private void onLoadCallback()
{
Debug.Log("данные загружены !!!");
m_isLoaded = true;
}
// ниже методы подсветки 2D / 3D / смешанной
}
Примечание:
SetEditorMode(true)должен вызываться передLoad, чтобы вступить в силу; аSetHighlightдолжен вызываться после завершения загрузки данных (после срабатывания обратного вызоваonLoadCallback).
Шаг 6: Прикрепите скрипт и настройте свойства
- Прикрепите скрипт
Highlight.csк GameObject LCCRenderer. - В окне Inspector перетащите GameObject LCCManager на свойство Manager скрипта.
- Заполните путь к файлу LCC в свойстве File Path.
- Перетащите
Box1,Box2,Box3иClipsphereв сцене на соответствующие свойства скрипта.

Настройка свойств скрипта Highlight в Inspector
Шаг 7: Примеры операций подсветки
Добавьте методы ниже в класс Highlight и вызовите соответствующий метод после запуска и после завершения загрузки данных.
Подсветка 2D-текстурой
Создайте две текстуры маски R8, пометьте пиксели для подсветки значением 240, а остальные — 128, затем создайте Data2D с матрицами камеры и добавьте их в список.
public void on2DHighlight()
{
// Размер текстуры фиксирован 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] = 240; // 240 означает выделено, 128 означает по умолчанию, 0 означает обрезку
else
_values[i] = 128;
}
_texture.SetPixelData(_values, 0);
Texture2D _texture2 = new Texture2D(1024, 1024, TextureFormat.R8, false);
_texture2.filterMode = FilterMode.Point;
_texture2.wrapMode = TextureWrapMode.Clamp;
byte[] _values2 = new byte[_count];
for (int i = 0; i < _count; i++)
{
if (i > _count * 0.75 && i < _count * 0.9)
_values2[i] = 240;
else
_values2[i] = 128;
}
_texture2.SetPixelData(_values2, 0);
List<Data2D> _2Ds = new List<Data2D>();
Data2D _2d01 = new Data2D();
_2d01.mv = m_camera.worldToCameraMatrix;
_2d01.texture = _texture;
_2d01.mode = SelectMode.normal;
_2d01.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_2Ds.Add(_2d01);
Data2D _2d02 = new Data2D();
_2d02.mv = m_camera.worldToCameraMatrix;
_2d02.texture = _texture2;
_2d02.mode = SelectMode.normal;
_2d02.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_2Ds.Add(_2d02);
m_manager.SetHighlight(_2Ds);
}
Объяснение кода: создаются две текстуры маски. Первая маска выделяет нижнюю половину экрана (начало координат экрана — нижний левый угол), а вторая маска выделяет область от 0.75 до 0.9 верхней половины экрана. Эффект примера следующий.
При фактическом использовании вы можете использовать различные инструменты выделения, такие как прямоугольники, треугольники, кисти и лассо, чтобы выбрать соответствующие позиции на маске.

Эффект подсветки 2D-текстурой
Подсветка 3D-геометрией
Используйте worldToLocalMatrix геометрии в качестве обратной матрицы выделения, комбинируйте объединение (normal) и разность (erase) через operation и реализуйте инвертированное выделение через запись с mode = SelectMode.invert.
public void on3DHighlight()
{
List<Data3D> _3Ds = new List<Data3D>();
var _mat1 = m_Box1.transform.worldToLocalMatrix;
var _mat2 = m_Box2.transform.worldToLocalMatrix;
var _mat3 = m_Box3.transform.worldToLocalMatrix;
var _mat4 = m_Clipsphere.transform.worldToLocalMatrix;
// Выделение боксом
Data3D _3d01 = new Data3D();
_3d01.type = ShapeType.box;
_3d01.operation = OperationMode.normal;
_3d01.mode = SelectMode.normal;
_3d01.invMat = _mat1;
_3Ds.Add(_3d01);
Data3D _3d02 = new Data3D();
_3d02.type = ShapeType.box;
_3d02.operation = OperationMode.normal;
_3d02.mode = SelectMode.normal;
_3d02.invMat = _mat2;
_3Ds.Add(_3d02);
// Выделение сферой
Data3D _3d04 = new Data3D();
_3d04.type = ShapeType.sphere;
_3d04.operation = OperationMode.normal;
_3d04.mode = SelectMode.normal;
_3d04.invMat = _mat4;
_3Ds.Add(_3d04);
// Стирание бокса/сферы (разность)
Data3D _3d03 = new Data3D();
_3d03.type = ShapeType.box;
_3d03.operation = OperationMode.erase;
_3d03.mode = SelectMode.normal;
_3d03.invMat = _mat3;
_3Ds.Add(_3d03);
// Инверсия
//Data3D _3d05 = new Data3D();
//_3d05.mode = SelectMode.invert;
//_3Ds.Add(_3d05);
m_manager.SetHighlight(_3Ds);
}
Объяснение кода: используются 4 геометрии, где Box1, Box2 и Sphere — обычные выделения, а Box3 — стирающее выделение, то есть стирание ранее выделенной области. При закомментированном коде инверсии эффект примера следующий:

Эффект подсветки 3D-геометрией
Раскомментируйте код инверсии, чтобы инверсия вступила в силу; эффект примера следующий. Инверсия переворачивает ранее выделенную область; это команда, и её не нужно связывать с данными операции.
Особо отметьте, что список упорядочен; разные шаги операции дают разные конечные эффекты.

Эффект подсветки 3D-геометрией + инверсия
Подсветка в смешанном режиме
Смешайте записи 2D-текстуры и 3D-геометрии в одном списке; каждая запись указывает свой способ обработки через editType.
public void onMixHighlight()
{
// --- Подготовка 2D-выделения ---
// Размер текстуры фиксирован 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<DataMix> _Mixs = new List<DataMix>();
DataMix _mix01 = new DataMix();
_mix01.editType = EditType.Edit2D;
_mix01.mv = m_camera.worldToCameraMatrix;
_mix01.texture = _texture;
_mix01.mode = SelectMode.normal;
_mix01.mvp = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true) * m_camera.worldToCameraMatrix;
_Mixs.Add(_mix01);
// --- Подготовка 3D-выделения ---
var _mat1 = m_Box1.transform.worldToLocalMatrix;
var _mat2 = m_Box2.transform.worldToLocalMatrix;
var _mat3 = m_Box3.transform.worldToLocalMatrix;
var _mat4 = m_Clipsphere.transform.worldToLocalMatrix;
// Выделение боксом
DataMix _mix02 = new DataMix();
_mix02.editType = EditType.Edit3D;
_mix02.type = ShapeType.box;
_mix02.operation = OperationMode.normal;
_mix02.mode = SelectMode.normal;
_mix02.invMat = _mat1;
_Mixs.Add(_mix02);
DataMix _mix03 = new DataMix();
_mix03.editType = EditType.Edit3D;
_mix03.type = ShapeType.box;
_mix03.operation = OperationMode.normal;
_mix03.mode = SelectMode.normal;
_mix03.invMat = _mat2;
_Mixs.Add(_mix03);
// Выделение сферой
DataMix _mix04 = new DataMix();
_mix04.editType = EditType.Edit3D;
_mix04.type = ShapeType.sphere;
_mix04.operation = OperationMode.normal;
_mix04.mode = SelectMode.normal;
_mix04.invMat = _mat4;
_Mixs.Add(_mix04);
// Стирание бокса/сферы (разность)
DataMix _mix05 = new DataMix();
_mix05.editType = EditType.Edit3D;
_mix05.type = ShapeType.box;
_mix05.operation = OperationMode.erase;
_mix05.mode = SelectMode.normal;
_mix05.invMat = _mat3;
_Mixs.Add(_mix05);
// Инверсия (включите по мере необходимости)
DataMix _mix06 = new DataMix();
_mix06.editType = EditType.Edit3D;
_mix06.type = ShapeType.box;
_mix06.mode = SelectMode.invert;
//_Mixs.Add(_mix06);
m_manager.SetHighlight(_Mixs);
}
Объяснение кода: используются 4 геометрии и 1 2D-текстура, что позволяет смешанную обработку 2D и 3D. Эффект примера следующий:

Эффект подсветки в смешанном режиме
Шаг 8: Выход из подсветки
Вызовите QuitHighlightMode() для очистки текущей подсветки и восстановления обычного отображения сцены.
public void onClearHighlight()
{
m_manager.QuitHighlightMode();
}
Ключевые шаги
Ключевые шаги для подсветки сцены 3DGS:
- Вызовите
SetEditorMode(true)перед загрузкой данных, чтобы войти в состояние редактирования. - Вызовите
SetHighlightпосле завершения загрузки данных (после срабатывания обратного вызоваonLoadCallbackили через кнопку/событие). - Выберите 2D-текстуру, 3D-геометрию или смешанный режим по мере необходимости и убедитесь, что порядок добавления в список выделения соответствует вашим ожиданиям.
- 2D-текстура маски фиксирована на 1024 × 1024,
R8один канал; заполняйте значения пикселей согласно соглашению (128по умолчанию,240выделено). - При очистке или переключении подсветки сначала вызовите
QuitHighlightMode().