Implementación de oclusión con el complemento Mega
La oclusión (Occlusion) es una tecnología clave para mejorar la inmersión en la fusión de realidad aumentada (AR). Este artículo le guiará sobre cómo lograr efectos de oclusión en el entorno de xr-frame utilizando el posicionamiento en la nube y las anotaciones de EasyAR.
Antes de comenzar
- Ser capaz de usar Mega Studio en Unity.
- Ser capaz de crear y cargar anotaciones usando el editor de Unity.
- Ser capaz de crear contenido alineado con el mundo real.
Métodos de implementación de oclusión
Modelado offline: Utilice el editor de Unity para crear geometrías coincidentes 1:1 con entidades del mundo real (como paredes, columnas, equipos grandes) en el sistema de coordenadas del Block; o mediante el recorte y optimización del modelo denso del Block.
Alineación en tiempo de ejecución: Durante la ejecución de xr-frame, alinee el sistema de coordenadas del Block con el espacio físico mediante posicionamiento en la nube y cargue la geometría correspondiente.
Reemplazo de material: Asigne materiales de oclusión especiales a estas geometrías.
Efecto visual: Cuando la GPU renderiza otros objetos virtuales, los píxeles ocluidos se descartan automáticamente debido a pruebas de profundidad fallidas, haciendo que los objetos virtuales sigan la lógica de oclusión del espacio físico real.
Cómo configurar la oclusión de geometría simple
Coloque anotaciones de cubo con precisión, alineadas con el modelo denso y las imágenes panorámicas. Después de la colocación, las anotaciones deben verse como una "pared" o "columna".

Modifique el nombre de la anotación (por ejemplo,
occlusion_wall), registre su ID y cárguela.En la mini-app de xr-frame, utilice su geometría incorporada para cargar la anotación como oclusión.
En la devolución de llamada de carga de EMA, use
scene.createElement(xrFrameSystem.XRMesh,{})para crear geometría simple y asignarle el materialeasyar-occulusion.Nota
La carga, registro, desregistro y descarga del material
easyar-occulusionson controlados por la AR Session.
handleEmaResult(ema: easyar.ema.v0_5.Ema) {
let blockHolder: easyar.BlockHolder = session.blockHolder;
ema.blocks.forEach(emaBlock => {
const blockInfo: easyar.BlockInfo = {
id: emaBlock.id
};
// Si el nodo Block no existe, crea el nodo Block
blockHolder.holdBlock(blockInfo, easyarPlugin.toXRFrame(emaBlock.transform));
});
ema.annotations.forEach(annotation => {
if (annotation.type != mega.EmaV05AnnotationType.Node) {
return;
}
const nodeAnnotation = annotation as easyar.ema.v0_5.Node;
const xrNode: xrfs.XRNode = easyarPlugin.createXRNodeFromNodeAnnotation(nodeAnnotation, blockHolder);
const emaName: string = nodeAnnotation.name;
const geometryStr: string = nodeAnnotation.geometry === "cube" ? "cube" : "sphere";
const assetInfo = AnnotationMetaData[nodeAnnotation.id as keyof typeof AnnotationMetaData];
let model: xrfs.Element;
if (assetInfo) {
// Parte de GLTF
} else {
model = scene.createElement(
xrFrameSystem.XRMesh,
{
// Usa el material de oclusión registrado por el plugin
material: "easyar-occlusion",
// Usa geometría incorporada de xr-frame, aquí también puedes usar directamente "cube"
geometry: geometryStr,
name: emaName,
"receive-shadow": "false",
"cast-shadow": "false"
// Nota: no modifique Scale
}
);
xrNode.addChild(model);
}
})
}
<video src="https://doc-asset.easyar.com/develop/wechat/mega/media/occlusion03.mp4" style="width:480px; max-width:100%; height:auto;" muted playsinline controls></video>
> Con la oclusión implementada, este panda puede bailar escondido detrás de la pared.
Cómo configurar la oclusión de geometría compleja
Adecuado para escenarios que requieren alta precisión, como equipos de forma irregular o edificios no convencionales.
Puede utilizar el modelo denso del Block, recortarlo y reducir su geometría para obtener un modelo blanco de oclusión.
En la escena de Unity, haga clic en el nodo Mega Block y registre el BlockID en el panel Inspector.

En Block de Mega Studio, seleccione exportar.

Modifique las opciones de exportación y exporte.

El punto 1 indica el nivel de LOD; niveles más bajos significan modelos más simples con menos polígonos. Para máxima precisión elija 2; para reducir polígonos aceptando menor precisión, elija 1 o 0.
El punto 2 es la opción de exportar texturas. Como solo necesitamos un modelo blanco para oclusión, no se requieren texturas.
Recorte y reduzca la geometría del modelo exportado en software de creación de contenido digital (por ejemplo, Blender), y guárdelo como
Glb.Consejo
Este ejemplo utiliza el Decimate Modifier de Blender.

Después del recorte y reducción de geometría:

Aloje el archivo
Glbde oclusión en un servidor de archivos para obtener una URL de carga.En la mini-app de xr-frame, cargue el GLTF como oclusión.
Primero cargue el modelo GLTF de oclusión, luego use
scene.createElement(xrFrameSystem.XRGLTF,options)para crear el modelo GLTF.Use
assets.getAsset("material", "easyar-occlusion")para obtener el objeto de material.Use
model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {m.setData({ neverCull: true, material: occlusionMaterial });}para modificar el material del modelo GLTF.Nota
La carga, registro, desregistro y descarga del material
easyar-occulusionson controlados por la AR Session.
const sampleAssets = {
occlusion1: {
assetId: "occlusion1",
type: "gltf",
src: "url/occlusion1.glb",
options: {}
}
}
async loadAsset() {
if (!scene) {console.error("Empty scene"); return;}
try {
await scene.assets.loadAsset(sampleAssets.occlusion1);
} catch (err) {
console.error(`Failed to load assets: ${err.message}`);
}
},
addOcclusion() {
model = scene.createElement(
xrFrameSystem.XRGLTF,
{
"model": assetInfo.assetId,
"anim-autoplay": assetInfo.animation ? assetInfo.animation : "",
"scale": assetInfo.scale ? assetInfo.scale : "1 1 1",
name: "tree"
}
);
const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456" //aquí debe ingresar el Block ID
if (!blockHolder.getBlockById(blockParent.id)) {
// Si no existe un nodo Block, crea uno
blockHolder.holdBlock({
id: blockID
})
}
// Obtiene el nodo Block en la escena de xr-frame
let blockElement = blockHolder.getBlockById(blockParent.id).el;
// Monta el modelo de oclusión recortado bajo el nodo Block como hijo
blockElement.addChild(model);
/**
* Debido a diferencias en los cargadores de GLTF, para garantizar que la orientación del modelo en xr-frame
* coincida exactamente con el resultado de renderizado de Unity
* a veces es necesario rotar el modelo cargado 180 grados alrededor del eje Y
*/
let modelTransform = model.getComponent(xrFrameSystem.Transform);
let currentRotation = modelTransform.quaternion.clone();
let targetRotation = currentRotation.multiply(new xrFrameSystem.Quaternion().setValue(0, 1, 0, 0));
modelTransform.quaternion.set(targetRotation);
//Nota: debe modificar el material después de ajustar el Transform
if (assetInfo.assetId == 'occlusion1') {
//Obtiene el material de oclusión del plugin mega
let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion");
//Modifica el material de oclusión
model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
m.setData({ neverCull: true, material: occlusionMaterial });
});
}
}
> [!NOTE]
> Al usar el modelo denso de Mega Block recortado como oclusión, no es necesario usar anotaciones para sincronizar la posición espacial. Esto se debe a que en software de creación de contenido (como Blender) se puede reducir y recortar el modelo sin alterar su sistema de coordenadas.
>
> Si necesita colocar con precisión un modelo GLTF de oclusión propio, consulte [cómo colocar modelos de oclusión alineados espacialmente](./sample.md#wechat-mega-sample-precise-occulusion-model)
El efecto final en dispositivo se muestra en el video al inicio del artículo.
Expectativas del efecto de oclusión
La efectividad de la oclusión en mini-apps de xr-frame depende principalmente de:
- La precisión inherente del seguimiento de posicionamiento.
- La exactitud en la colocación del modelo.
- La precisión del modelo mismo (si no es geometría simple).
Es normal observar desalineaciones de varios centímetros durante deriva del posicionamiento.
Los modelos de oclusión con demasiados polígonos pueden afectar el rendimiento. Se recomienda usarlos solo en áreas necesarias y preferir geometrías simples.