Substituição de estado hierárquico

Em muitos casos, é necessário alterar dinamicamente a aparência de partes de um modelo, por exemplo, ocultar subgrafos ou alternar partes para renderização transparente. A alteração dos materiais de cada parte envolvida não é prática, pois requer iteração em todo o grafo de cena e o gerenciamento da clonagem e da atribuição de material em cada nó.

Para realizar esse caso de uso com a menor sobrecarga possível, use o HierarchicalStateOverrideComponent. Esse componente implementa atualizações de estado hierárquicas em ramificações arbitrárias do grafo de cena. Isso significa que um estado pode ser definido em qualquer nível no grafo de cena e perpassa a hierarquia até que seja substituído por um novo estado ou aplicado a um objeto folha.

Como exemplo, considere o modelo de um carro, o qual você deseja alternar completamente para ser transparente, exceto a parte interna do motor. Esse caso de uso envolve apenas duas instâncias do componente:

  • O primeiro componente é atribuído ao nó raiz do modelo e ativa a renderização transparente para o carro inteiro.
  • O segundo componente é atribuído ao nó raiz do motor e substitui o estado novamente, desativando de forma explícita o modo de transparência.

Observação

As nuvens de ponto não expõem um grafo de cena completo (consulte diferenças de tipo de malha). Portanto, atribuir uma substituição hierárquica à entidade raiz de um modelo de nuvem de ponto aplicará o estado à nuvem de ponto completo. Além disso, não há suporte para alguns recursos de substituição de estado para nuvens de ponto, conforme mencionado na respectiva seção.

Recursos

O conjunto fixo de estados que podem ser substituídos é:

  • Hidden: as respectivas malhas no grafo de cena são ocultas ou aparentes.

  • Tint color: um objeto renderizado pode ser colorido com uma cor de tonalidade individual e um peso de tonalidade. A imagem abaixo mostra a coloração do aro de uma roda.

    Tint color used to turn an object green

  • See-through: a geometria é renderizada de maneira semitransparente, por exemplo, para revelar as partes internas de um objeto. A seguinte imagem mostra todo o carro sendo renderizado no modo de transparência, exceto a pinça de freio vermelha:

    See-through mode used to make selected objects transparent

    Importante

    O efeito de transparência só funciona quando é usado o modo de renderizaçãoTileBasedComposition.

    Observação

    O efeito de transparência é ignorado para nuvens de ponto.

  • Shell: a geometria é renderizada como um shell transparente e dessaturado. Esse modo permite esmaecer partes não importantes de uma cena, mantendo simultaneamente uma noção de formato e posicionamento relativo. Para alterar a aparência da renderização do shell, use o estado ShellRenderingSettings. Confira a seguinte imagem para que o modelo de carro seja totalmente renderizado pelo shell, exceto pelas molas azuis:

    Shell mode used to fade out specific objects

    Importante

    O efeito de shell só funciona quando o modo de renderizaçãoTileBasedComposition é usado.

    Observação

    O efeito de shell é ignorado para nuvens de ponto.

  • Selected: a geometria é renderizada com um contorno de seleção.

    Outline option used to highlight a selected part

    Observação

    A renderização do contorno de seleção é ignorada para nuvens de ponto.

  • DisableCollision: a geometria é isenta de consultas espaciais. O sinalizador Hidden não afeta o sinalizador de estado de colisão, portanto, esses dois sinalizadores geralmente são definidos juntos.

  • TransparencyWritesDepth: Ativa a escrita de profundidade e See-through transparências de material na árvore de cena da entidade do componente. Usando esse sinalizador, as transparências podem ter a gravação em profundidade habilitada ou desabilitada em uma subárvore, See-through mesmo que TransparencyWritesDepth seja forçada globalmente. Para transparência material, o sinalizador se comporta de forma inclusiva, ou seja, se TransparencyWritesDepth estiver habilitado com substituição, globalmente forçado ou por meio dos sinalizadores do material, a escrita de profundidade será habilitada para objetos renderizados com esse material.

  • UseCutPlaneFilterMask: use uma máscara de bits de filtro individual para controlar a seleção do plano de recorte. Esse sinalizador determina se a máscara de filtro individual deve ser usada ou herdada do respectivo pai. A máscara de bit de filtro propriamente dita é definida por meio da propriedade CutPlaneFilterMask. Para obter informações detalhadas sobre como a filtragem funciona, confira o parágrafo Planos de corte seletivo. Confira o exemplo a seguir, em que apenas o pneu e o aro são recortados, enquanto o restante da cena permanece inalterado. Selective cut planes

Dica

Como alternativa para desativar as consultas de visibilidade e espaciais para um subgrafo completo, o estado enabled de um objeto de jogo pode ser alternado. Se uma hierarquia estiver desabilitada, isso terá preferência sobre qualquer HierarchicalStateOverrideComponent.

Substituições hierárquicas

O HierarchicalStateOverrideComponent pode ser anexado em vários níveis de uma hierarquia de objetos. Como só pode haver um componente de cada tipo em uma entidade, cada HierarchicalStateOverrideComponent gerencia os estados de hidden, see-through, selected, color tint e collision.

Dessa forma, cada estado pode ser definido como:

  • ForceOn – o estado está habilitado para toda a malha nesse nó e abaixo dele
  • ForceOff – o estado está desabilitado para todas as malhas nesse nó e abaixo dele
  • InheritFromParent – o estado não é afetado por esse componente de substituição

Os estados podem ser alterados diretamente ou por meio da função SetState:

HierarchicalStateOverrideComponent component = ...;

// set one state directly
component.HiddenState = HierarchicalEnableState.ForceOn;

// set a state with the SetState function
component.SetState(HierarchicalStates.SeeThrough, HierarchicalEnableState.InheritFromParent);

// set multiple states at once with the SetState function
component.SetState(HierarchicalStates.Hidden | HierarchicalStates.DisableCollision, HierarchicalEnableState.ForceOff);
ApiHandle<HierarchicalStateOverrideComponent> component = ...;

// set one state directly
component->SetHiddenState(HierarchicalEnableState::ForceOn);

// or: set a state with the SetState function
component->SetState(HierarchicalStates::SeeThrough, HierarchicalEnableState::InheritFromParent);

// set multiple states at once with the SetState function
component->SetState(
    (HierarchicalStates)((int32_t)HierarchicalStates::Hidden | (int32_t)HierarchicalStates::DisableCollision), HierarchicalEnableState::ForceOff);

Cor de tonalidade

A substituição tint color é um pouco especial, pois há um estado ligado/desligado/herdado e uma propriedade de cor de tonalidade. A parte alfa da cor de tonalidade define o peso do efeito de tonalidade: Se definido como 0,0, nenhuma cor de tonalidade será visível e, se definido como 1,0, o objeto será renderizado com cor de tonalidade pura. Para valores intermediários, a cor final será misturada com a cor de tonalidade. A cor da tonalidade pode ser alterada quadro a quadro para obter uma animação colorida.

Considerações sobre o desempenho

Uma instância do HierarchicalStateOverrideComponent em si não adiciona muita sobrecarga de runtime. No entanto, é sempre uma boa prática manter um número baixo de componentes ativos. Por exemplo, ao implementar um sistema de seleção que realça o objeto selecionado, é recomendável excluir o componente quando o realce é removido. Manter os componentes com recursos neutros pode gerar acúmulo rapidamente.

A renderização transparente coloca mais carga de trabalho nas GPUs do servidor do que a renderização padrão. Se grandes partes do grafo de cena forem alternadas para see-through, com muitas camadas de geometria ficando visíveis, ele poderá se tornar um gargalo de desempenho. Isso também é válido para objetos com contornos de seleção e para renderização de shell.

Documentação da API

Próximas etapas