Guía de desarrollo de resaltado
El LCC Unity SDK admite operaciones de edición como el resaltado y el recorte en escenas 3DGS. Esta guía presenta las operaciones relacionadas con el resaltado: seleccionar un área mediante texturas proyectadas 2D, geometría 3D o una mezcla de ambas, de modo que el área seleccionada quede resaltada, con compatibilidad para la selección normal y la selección invertida.
Nota:
La función de resaltado actual es solo un efecto de visualización en tiempo de ejecución; no modifica el archivo de datos original de ninguna manera y no admite guardar ni exportar el resultado de la edición. Si necesitas ajustar el color, recortar y guardar datos, usa la herramienta de software XGRIDS LCC Editor.
Si no quieres modificar los datos, también puedes registrar las operaciones y reproducirlas después de que los datos terminen de cargarse la próxima vez.
Requisitos previos
Resaltar una escena a través del SDK requiere las siguientes condiciones:
- Entrar en el estado de edición antes de cargar los datos. El SDK está en el estado de navegación (View) por defecto, que proporciona el mejor rendimiento y se recomienda para la navegación normal. Para realizar operaciones de edición como el resaltado, cambia al estado de edición mediante
SetEditorMode(true)antes de llamar aLoad. Este método solo surte efecto si se llama antes de cargar todos los datos. - Realizar la operación de resaltado después de que los datos terminen de cargarse. La interfaz de resaltado debe llamarse después de que los datos de la escena se hayan cargado por completo.
Paso 1: Configurar la escena
Prepara los GameObjects necesarios para el resaltado en la escena como se muestra a continuación.

Estructura de jerarquía de la escena para el ejemplo de resaltado
- Main Camera: la cámara de la escena; el resaltado 2D usa sus matrices de vista y proyección.
- LCCManager: un GameObject vacío con un Transform normalizado, con el script
LCCManagerañadido. - LCCRenderer: un GameObject vacío con el Transform establecido como Rotation.x = -90, Scale.x = -1 (alineado con el sistema de coordenadas de los datos LCC), usado para adjuntar el script
Highlightescrito más adelante. - Geometría de selección 3D: objetos auxiliares para el resaltado 3D. El ejemplo prepara 3 Cubes (
Box1,Box2,Box3) y 1 Sphere (Clipsphere); mover y escalar estos objetos controla la posición y el tamaño de la selección de resaltado.
Nota:
Para los ajustes relacionados con los GameObjects de la cámara de renderizado, LCCManager y LCCRenderer, consulta las secciones relevantes de Guía de inicio rápido para PC y Guía de optimización de ajustes del proyecto.

Geometría de selección usada para el resaltado 3D (Box1 / Box2 / Box3 / Clipsphere)
Paso 2: Comprender las estructuras de datos
El resaltado implica tres métodos de operación — 2D, 3D y mixto 2D/3D. Los enums y structs usados son los siguientes.
public enum SelectMode { normal, invert, clip } // selección normal, inversión, recorte en tiempo real
public enum OperationMode { normal, erase } // selección normal, borrar selección
public enum ShapeType { box, sphere } // selección 3D Box, selección 3D Sphere
public enum EditType { Edit2D, Edit3D } // edición 2D, edición 3D
// Selección por textura 2D
public struct Data2D
{
public Texture2D texture; // textura de máscara 2D
public Matrix4x4 mv; // matriz de vista de la cámara
public Matrix4x4 mvp; // matriz de vista-proyección de la cámara
public SelectMode mode; // modo de selección
}
// Selección por geometría 3D
public struct Data3D
{
public ShapeType type; // tipo de geometría (box / sphere)
public Matrix4x4 invMat; // matriz inversa mundo-a-local de la geometría
public OperationMode operation; // tipo de operación (unión normal / diferencia de borrado)
public SelectMode mode; // modo de selección
}
// Selección mixta 2D / 3D
public struct DataMix
{
public EditType editType; // tipo de edición (obligatorio; determina si se usan los campos 2D o 3D)
public Texture2D texture; // textura de máscara 2D (usada por Edit2D)
public Matrix4x4 mv; // matriz de vista de la cámara (usada por Edit2D)
public Matrix4x4 mvp; // matriz de vista-proyección de la cámara (usada por Edit2D)
public ShapeType type; // tipo de geometría (usado por Edit3D)
public Matrix4x4 invMat; // matriz inversa de la geometría (usada por Edit3D)
public OperationMode operation; // tipo de operación (usado por Edit3D)
public SelectMode mode; // modo de selección (obligatorio)
}
Hay tres puntos a tener en cuenta sobre la lista de selección:
- La lista está ordenada. Ya sea 2D o 3D, las entradas de la lista surten efecto en orden; asegúrate de que el orden de adición coincide con tu expectativa.
- Invertir es un comando de operación y no necesita asociarse con datos de selección específicos. Simplemente añade una entrada con
mode = SelectMode.invertpara invertir el área seleccionada actualmente. - El número máximo de entradas en una sola lista es 255. Superarlo devuelve un código de error.
Paso 3: Comprender las API de resaltado
Todas las interfaces relacionadas con el resaltado las proporciona LCCManager, incluidas tres sobrecargas de SetHighlight y un método de salida.
SetHighlight (resaltado por textura 2D)
// Valor de retorno: int
// 0: éxito
// 1: la lista es null o tiene 0 elementos
// 2: los elementos de la lista superan el máximo de 255
public int SetHighlight(List<Data2D> _2Ds)
Resalta la escena usando una máscara de textura proyectada 2D; la parte fuera del área resaltada se oscurece.
SetHighlight (resaltado por geometría 3D)
// Valor de retorno: int
// 0: éxito
// 1: la lista es null o tiene 0 elementos
// 2: los elementos de la lista superan el máximo de 255
// 3: el número de cajas de geometría de selección es 0
public int SetHighlight(List<Data3D> _3Ds)
Define el área de resaltado usando geometría 3D (cuboide, cubo, esfera), admitiendo combinaciones de unión y diferencia. Se requiere al menos una geometría con operation == OperationMode.normal.
SetHighlight (resaltado en modo mixto)
// Valor de retorno: int
// 0: éxito
// 1: la lista es null o tiene 0 elementos
// 2: los elementos de la lista superan el máximo de 255
public int SetHighlight(List<DataMix> _Mix)
Define el área de resaltado usando texturas 2D y geometría 3D al mismo tiempo; cada entrada determina si se procesa como 2D o 3D mediante editType.
QuitHighlightMode
// Valor de retorno: void
public void QuitHighlightMode()
Sale del modo de resaltado y restaura la visualización normal de la escena.
Consejo:
Las tres sobrecargas de
SetHighlightson mutuamente excluyentes. Al cambiar de método de resaltado o limpiar el resaltado actual, llama primero aQuitHighlightMode()y luego establece el nuevo resaltado.
Paso 4: Especificación de la textura de máscara 2D
El resaltado 2D describe la selección mediante una textura de máscara, admitiendo varios métodos de selección como cuadriláteros, triángulos, pinceles y lazos — simplemente marca los píxeles correspondientes en la textura con el valor seleccionado. Al usar operaciones 2D, la cámara debe estar bloqueada y la textura marcada desde un punto de vista fijo. La textura y los valores de píxel tienen las siguientes convenciones:
- La textura está fijada en 1024 × 1024,
R8de un solo canal, sin Mipmap, con filtrado por puntos (FilterMode.Point) y muestreo limitado (TextureWrapMode.Clamp). - Convenciones de valor de píxel:
| Valor de píxel | Significado |
|---|---|
128 | Por defecto (no seleccionado) |
240 | Seleccionado |
180 | Deseleccionar (borrar el área ya seleccionada) |
0 | Recorte |
En un escenario de resaltado, normalmente solo se usan los dos valores 128 (por defecto) y 240 (seleccionado).
Paso 5: Escribir el script
Crea un nuevo script C# llamado Highlight.cs. Primero completa el esqueleto básico: en Start, entra en el estado de edición y carga los datos; después de que la carga finalice, establece el indicador de carga para que los métodos de resaltado posteriores lo comprueben.
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);
// Entra en el modo de edición; debe llamarse antes de Load
m_manager.SetEditorMode(true);
m_renderer = m_manager.GetRender(this.transform);
if (m_renderer == null)
Debug.LogError("Error en GetRender, comprueba que el manager esté configurado correctamente y que la ruta del archivo sea válida.");
m_renderer.Load(m_FilePath, onLoadProgress, onLoadCallback);
}
private void onLoadProgress(float value)
{
Debug.Log($"progreso de carga: {value}");
}
private void onLoadCallback()
{
Debug.Log("datos cargados !!!");
m_isLoaded = true;
}
// métodos de resaltado 2D / 3D / mixto a continuación
}
Nota:
SetEditorMode(true)debe llamarse antes deLoadpara surtir efecto; ySetHighlightdebe llamarse después de que los datos terminen de cargarse (después de que se dispare la devolución de llamadaonLoadCallback).
Paso 6: Adjuntar el script y establecer propiedades
- Adjunta el script
Highlight.csal GameObject LCCRenderer. - En la ventana Inspector, arrastra el GameObject LCCManager a la propiedad Manager del script.
- Rellena la ruta del archivo LCC en la propiedad File Path.
- Arrastra
Box1,Box2,Box3yClipspherede la escena a las propiedades correspondientes del script respectivamente.

Establecer las propiedades del script Highlight en el Inspector
Paso 7: Ejemplos de operación de resaltado
Añade los métodos siguientes a la clase Highlight y llama al método correspondiente después de ejecutar y después de que los datos terminen de cargarse.
Resaltado por textura 2D
Construye dos texturas de máscara R8, marca los píxeles a resaltar como 240 y el resto como 128, luego construye Data2D con las matrices de la cámara y añádelos a la lista.
public void on2DHighlight()
{
// El tamaño de la textura está fijado en 1024*1024; mantén las demás propiedades igual que el ejemplo
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 significa seleccionado, 128 significa por defecto, 0 significa recorte
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);
}
Explicación del código: se construyen dos texturas de máscara. La primera máscara selecciona la mitad inferior de la pantalla (el origen de la pantalla es la esquina inferior izquierda), y la segunda máscara selecciona la región de 0.75 a 0.9 de la mitad superior de la pantalla. El efecto del ejemplo es el siguiente.
En el uso real, puedes usar varias herramientas de selección como rectángulos, triángulos, pinceles y lazos para seleccionar las posiciones correspondientes en la máscara.

Efecto de resaltado por textura 2D
Resaltado por geometría 3D
Usa el worldToLocalMatrix de la geometría como matriz inversa de selección, combina unión (normal) y diferencia (erase) mediante operation, e implementa la selección invertida mediante una entrada con 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;
// Selección de caja
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);
// Selección de esfera
Data3D _3d04 = new Data3D();
_3d04.type = ShapeType.sphere;
_3d04.operation = OperationMode.normal;
_3d04.mode = SelectMode.normal;
_3d04.invMat = _mat4;
_3Ds.Add(_3d04);
// Borrar caja/esfera (diferencia)
Data3D _3d03 = new Data3D();
_3d03.type = ShapeType.box;
_3d03.operation = OperationMode.erase;
_3d03.mode = SelectMode.normal;
_3d03.invMat = _mat3;
_3Ds.Add(_3d03);
// Invertir
//Data3D _3d05 = new Data3D();
//_3d05.mode = SelectMode.invert;
//_3Ds.Add(_3d05);
m_manager.SetHighlight(_3Ds);
}
Explicación del código: se usan 4 geometrías, donde Box1, Box2 y Sphere son selecciones normales, y Box3 es una selección de borrado, es decir, borrar el área seleccionada previamente. Con el código relacionado con la inversión comentado, el efecto del ejemplo es el siguiente:

Efecto de resaltado por geometría 3D
Descomenta el código de inversión para que la inversión surta efecto; el efecto del ejemplo es el siguiente. La inversión invierte el área seleccionada previamente; es un comando y no necesita asociarse con datos de operación.
En particular, ten en cuenta que la lista está ordenada; diferentes pasos de operación producen diferentes efectos finales.

Efecto de resaltado por geometría 3D + inversión
Resaltado en modo mixto
Mezcla entradas de textura 2D y geometría 3D en la misma lista; cada entrada especifica su método de procesamiento mediante editType.
public void onMixHighlight()
{
// --- Preparación de la selección 2D ---
// El tamaño de la textura está fijado en 1024*1024; mantén las demás propiedades igual que el ejemplo
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 significa por defecto, 240 significa seleccionado, 0 significa recorte
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);
// --- Preparación de la selección 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;
// Selección de caja
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);
// Selección de esfera
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);
// Borrar caja/esfera (diferencia)
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);
// Invertir (habilítalo según sea necesario)
DataMix _mix06 = new DataMix();
_mix06.editType = EditType.Edit3D;
_mix06.type = ShapeType.box;
_mix06.mode = SelectMode.invert;
//_Mixs.Add(_mix06);
m_manager.SetHighlight(_Mixs);
}
Explicación del código: se usan 4 geometrías y 1 textura 2D, permitiendo el procesamiento mixto 2D y 3D. El efecto del ejemplo es el siguiente:

Efecto de resaltado en modo mixto
Paso 8: Salir del resaltado
Llama a QuitHighlightMode() para limpiar el resaltado actual y restaurar la visualización normal de la escena.
public void onClearHighlight()
{
m_manager.QuitHighlightMode();
}
Pasos clave
Los pasos clave para resaltar una escena 3DGS:
- Llama a
SetEditorMode(true)antes de cargar los datos para entrar en el estado de edición. - Llama a
SetHighlightdespués de que los datos terminen de cargarse (después de que se dispare la devolución de llamadaonLoadCallback, o se active mediante un botón/evento). - Elige textura 2D, geometría 3D o modo mixto según sea necesario, y asegúrate de que el orden de adición de la lista de selección coincide con tu expectativa.
- La textura de máscara 2D está fijada en 1024 × 1024,
R8de un solo canal; rellena los valores de píxel según la convención (128por defecto,240seleccionado). - Al limpiar o cambiar de resaltado, llama primero a
QuitHighlightMode().