Usando o plug-in Mega para implementar oclusão
Oclusão (Occlusion) é uma tecnologia essencial para melhorar a sensação de imersão na fusão de realidade aumentada (AR). Este guia explicará como implementar efeitos de oclusão usando o EasyAR Cloud Spatial Anchor e anotações em um ambiente xr-frame.
Antes de começar
- Ser capaz de usar o Mega Studio no Unity.
- Ser capaz de criar e carregar anotações usando o editor Unity.
- Ser capaz de criar conteúdo alinhado ao mundo real.
Métodos de implementação de oclusão
Modelagem offline: Utilize o editor Unity para criar geometrias correspondentes 1:1 a entidades do mundo real (como paredes, pilares, equipamentos grandes) no sistema de coordenadas Block; ou obtenha modelos otimizados através do recorte e redução de faces do modelo denso Block.
Alinhamento em tempo de execução: Durante a execução no xr-frame, alinhe o sistema de coordenadas Block ao espaço físico usando cloud localization e carregue a geometria correspondente.
Substituição de material: Atribua materiais especiais de oclusão a essas geometrias.
Efeito visual: Quando a GPU renderiza outros objetos virtuais, os pixels das partes ocluídas são automaticamente descartados devido ao teste de profundidade (depth test), fazendo com que os objetos virtuais sigam a lógica de oclusão do espaço físico real.
Como configurar oclusão com geometria simples
Posicione anotações cúbicas com precisão, alinhando-as ao modelo denso e imagens panorâmicas. Após o posicionamento, as anotações devem parecer uma "parede" ou "pilar".

Modifique o nome da anotação (ex:
occlusion_wall), registre o ID e faça o upload.No miniprograma xr-frame, utilize sua geometria embutida para carregar a anotação como oclusão.
No callback de carregamento do EMA, use
scene.createElement(xrFrameSystem.XRMesh,{})para criar uma geometria simples e atribua o materialeasyar-occulusion.Nota
O carregamento, registro, desregistro e descarregamento do material
easyar-occulusionsão controlados pela 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
};
// Se o nó Block não existir, crie o nó 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 GLTF
} else {
model = scene.createElement(
xrFrameSystem.XRMesh,
{
// Use o material de oclusão registrado pelo plug-in
material: "easyar-occlusion",
// Use a geometria integrada do xr-frame, também pode usar "cube" diretamente aqui
geometry: geometryStr,
name: emaName,
"receive-shadow": "false",
"cast-shadow": "false"
// Observe não modificar 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>
> Com a oclusão implementada, este panda pode dançar atrás da parede.
Como configurar oclusão com geometria complexa
Adequado para cenários que exigem alta precisão de oclusão, como equipamentos irregulares ou estruturas arquitetônicas complexas.
Você pode usar o modelo denso Block, recortá-lo e reduzir suas faces para obter um modelo branco (white model) para oclusão.
Clique no nó Mega Block na cena Unity e registre o BlockID no painel Inspector.

No Mega Studio, selecione Block > Exportar.

Ajuste as opções de exportação e exporte.

O item 1 indica o nível de LOD (Level of Detail). Níveis mais baixos resultam em modelos mais simples com menos faces. Para máxima precisão escolha 2; para reduzir faces aceitando menor precisão, escolha 1 ou 0.
O item 2 controla a exportação de texturas. Como precisamos apenas de um modelo branco para oclusão, desative esta opção.
Recorte e reduza as faces do modelo exportado em um software de criação de conteúdo digital (ex: Blender) e salve como
Glb.Dica
Este exemplo usa o Decimate Modifier do Blender.

Após recorte e redução de faces:

Hospede o arquivo
Glbde oclusão em um servidor de arquivos para obter uma URL de carregamento.Carregue o GLTF como oclusão no miniprograma xr-frame.
Primeiro carregue o modelo GLTF de oclusão. Em seguida, use
scene.createElement(xrFrameSystem.XRGLTF,options)para criar o modelo GLTF.Use
assets.getAsset("material", "easyar-occlusion")para obter o objeto de material.Use
model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {m.setData({ neverCull: true, material: occlusionMaterial });}para modificar o material do modelo GLTF.Nota
O carregamento, registro, desregistro e descarregamento do material
easyar-occulusionsão controlados pela 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" //Preencher com o Block ID aqui
if (!blockHolder.getBlockById(blockParent.id)) {
// Se não existir um nó Block, criar um
blockHolder.holdBlock({
id: blockID
})
}
// Obter o nó Block na cena do xr-frame
let blockElement = blockHolder.getBlockById(blockParent.id).el;
// Montar o modelo de oclusão recortado como filho do nó Block
blockElement.addChild(model);
/**
* Devido a diferenças no comportamento do carregador GLTF, para garantir que a orientação do modelo no xr-frame
* corresponda exatamente ao resultado de renderização do Unity
* às vezes é necessário girar o modelo carregado 180 graus em torno do eixo 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);
//Atenção: modificar o material APÓS alterar o Transform
if (assetInfo.assetId == 'occlusion1') {
//Obter material de oclusão fornecido pelo plug-in mega
let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion");
//Modificar material de oclusão
model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
m.setData({ neverCull: true, material: occlusionMaterial });
});
}
}
> [!NOTE]
> Ao usar o modelo denso Mega Block recortado para oclusão, **não** é necessário usar anotações para sincronizar a posição espacial. Isso ocorre porque softwares como Blender permitem reduzir e recortar modelos sem alterar a definição do sistema de coordenadas.
>
> Para posicionar com precisão um modelo GLTF de oclusão personalizado, consulte [Como posicionar modelos de oclusão alinhados espacialmente](./sample.md#wechat-mega-sample-precise-occulusion-model)
O resultado final em execução no dispositivo está no vídeo do topo do artigo.
Expectativas do efeito de oclusão
A eficácia da oclusão no miniprograma xr-frame é influenciada por:
- Precisão inerente do rastreamento de localização
- Precisão do posicionamento do modelo
- Precisão do próprio modelo (se não for uma geometria simples)
Desalinhamentos de alguns centímetros durante deriva (drift) de localização são normais.
Modelos de oclusão com muitas faces podem impactar o desempenho. Recomenda-se usar apenas em áreas necessárias e preferir geometrias simples.