Renderização

Esta página foi traduzida automaticamente e pode conter erros. Encontrou um problema? Use o link "Edit this page" para ajudar a corrigir.

A Turian renderiza 3D com um único renderizador SDL3-GPU (Vulkan / Metal / D3D12) compartilhado pela viewport do editor e pelo jogo finalizado (shipped game) — portanto, o que você vê ao editar é o que o jogo desenha: PBR metallic-roughness, mapeamento de sombras direcionais (directional shadow mapping), mapeamento de normais (normal mapping) e suporte direto para texturas compactadas (BCn / KTX2).

Dois pequenos módulos

O renderizador é dividido em pacotes independentes do engine para que não fique atrelado ao toolkit de UI do editor:

  • gpu — uma fina camada de plataforma de janela + dispositivo GPU (window + GPU device) sobre a API GPU do SDL3. Ela possui a janela do SO, o dispositivo e a swapchain, e expõe a API traduzida do SDL3 mais um buffer de comandos por quadro (frame). Também oferece um utilitário de captura de tela (screenshot - leitura da textura → TGA) muito útil para depuração.
  • render — o renderizador de cena (scene renderer): pipeline PBR, passagem de sombra (shadow pass), upload de mesh/textura e o loop de desenho (draw loop). Ele depende de gpu e dos tipos de cena/asset do engine, e recebe um dispositivo GPU, um alvo de cor (color target), os nós da cena e os bytes de asset via callbacks — sem dependência de UI.

O editor alimenta o render com o dispositivo do dvui e um alvo fora da tela (offscreen target); o jogo o alimenta com a swapchain de uma janela SDL. Ambos resolvem assets (meshes, texturas, materiais) por GUID através da mesma costura de fonte de bytes — a partir do .cache compilado no editor, e do .oap empacotado no jogo.

Recurso de software alternativo (Software fallback)

Quando o SDL3 GPU não está disponível (por exemplo, em CI sem interface gráfica/headless), o jogo reverte para um rasterizador de software de CPU. O caminho de GPU é o padrão para builds normais.

Iluminação

Até 8 luzes (directional / point / spot) são suportadas por quadro (frame). A primeira luz direcional emissora de sombra controla um mapa de sombras em cascata (cascaded shadow map — 4 divisões, cada uma com sua própria faixa filtrada por PCF do atlas de sombras), de modo que o detalhe da sombra permanece nítido perto da câmera sem abrir mão da cobertura em uma cena grande. Os metais recebem um termo especular ambiente para que não fiquem pretos na ausência de uma sonda de ambiente (environment probe). Consulte Componentes para os componentes Light e MeshRenderer, e Assets e Materiais para o modelo de material PBR.

Iluminação baseada em imagem (Image-based lighting)

Um componente Environment (no máximo um ativo por cena) aponta para um mapa HDR equirretangular e controla tanto o fundo do skybox quanto a iluminação ambiente:

  • Skybox — a textura equirretangular é amostrada diretamente pela direção do raio de visão; desative show_skybox para manter a contribuição ambiente enquanto volta à cor de limpeza simples do renderizador, útil ao iterar em geometria/materiais sem um HDRI ocupado competindo pela atenção.
  • Irradiância difusa — projetada uma vez por upload de ambiente em uma base de harmônicos esféricos de ordem 2 (barata de avaliar por pixel e já correta para um termo apenas difuso — sem necessidade de uma convolução completa de cubemap difuso).
  • Reflexões especulares — um cubemap pré-filtrado amostrado por importância GGX: no upload, o mapa equirretangular é convertido em um cubemap base, então cada mip é pré-filtrado com rugosidade crescente (a abordagem padrão split-sum), amostrado no momento da sombreamento pela direção de reflexão e um mip selecionado por rugosidade. Isso substituiu uma aproximação anterior de equirretangular-mip que aplicava box filter no espaço UV — ela desfocava excessivamente perto dos polos e não tinha uma forma de lobo GGX real em ângulos rasantes. O termo ambiente-BRDF usa a aproximação analítica de Karis em vez de uma LUT 2D pré-calculada.

Tudo isso acontece uma vez por upload de textura de ambiente, não por quadro — sem custo de execução além da geração inicial do cubemap.

Gerenciamento de cor

A iluminação é executada em espaço linear: texturas de cor (albedo, emissiva) são amostradas como sRGB — decodificadas para linear pelo sampler da GPU para texturas DDS/KTX2 etiquetadas, ou através de um pequeno envelope que o importador incorpora em fontes PNG/JPEG — enquanto mapas de dados (normal, metallic-roughness, oclusão) permanecem lineares durante todo o processo. A passagem principal renderiza em um alvo HDR (R16G16B16A16_FLOAT) em vez de escrever a cor tonemapeada diretamente; a passagem composta de pós-processamento aplica um tonemap fílmico ACES seguido de codificação gamma-2.2 no final, uma vez que os alvos de renderização e a swapchain são UNORM (não sRGB). O rasterizador de software espelha ambas as etapas diretamente em sua função de sombreamento para paridade entre os caminhos de GPU e CPU (ele não possui um estágio de pós-processamento separado).

Pós-processamento

Uma pilha de pós-processamento apenas em GPU é executada após a passagem iluminada e antes/em conjunto com o tonemapping: vinheta, correção de cor RGB Lift/Gamma/Gain por canal e bloom. As configurações ficam em um componente PostProcessVolume, não na câmera — adicione-o a qualquer objeto da cena e ele será global (afeta toda a cena) ou local (uma região de caixa/esfera ao redor desse objeto, com uma queda blend_distance na borda). Cada categoria de efeito tem sua própria alternância de ativação:

  • Vinhetaintensity (0 = desligado), radius e smoothness controlam um escurecimento radial do centro para fora.
  • Correção de corlift, gamma e gain (cada um um trio RGB) aplicam o mesmo modelo Lift/Gamma/Gain das rodas de correção do Unity: lift desloca sombras, gamma desloca meios-tons, gain desloca realces, cada um independentemente por canal para que você possa alterar o balanço de cor (ex.: sombras quentes, realces frios) e não apenas o brilho.
  • Bloomthreshold (brilho HDR linear acima do qual os pixels brilham), intensity (0 = desligado) e radius (espalhamento do brilho) acionam um bloom de filtro duplo multi-mip, de modo que superfícies emissivas ou com estouro especular brilhem com um halo suave e amplo em vez de um pequeno borrão de raio fixo.

Um PostProcessVolume com todas as categorias desativadas é um no-op absoluto — uma cena sem volumes nenhuns renderiza de forma bit- idêntica a não ter pós-processamento.

Volumes sobrepostos

Múltiplos volumes podem afetar a câmera ao mesmo tempo — um "visual" global para todo o nível mais volumes locais para salas ou momentos específicos, por exemplo. A sobreposição é resolvida por prioridade (a maior vence) e peso baseado em distância (1 dentro da forma de um volume local, desvanecendo para 0 ao longo de seu blend_distance), mesclado por categoria para que um volume possa substituir apenas a vinheta enquanto a correção de cor e o bloom ainda venham de qualquer outro volume ativo. A mesclagem é avaliada contra a posição real da câmera a cada quadro, então voar através do limite de um volume no editor pré-visualiza o mesmo desvanecimento que o jogo finalizado exibirá.

Efeitos personalizados

O código do engine/plugin pode registrar uma passagem de pós-processamento adicional — lendo e escrevendo o buffer HDR diretamente, para que possa fazer seu próprio bright-pass ou trabalho de correção em espaço HDR — através de postprocess.registerEffect em subsystems/render/postprocess.zig. Os efeitos registrados são executados na ordem de registro, após a geração de bloom embutida e antes da composição final; este é um ponto de extensão em nível Zig (registrar uma vez na inicialização), não um sistema de shaders ao vivo/autoral no editor.

Como o bloom precisa de dados de brilho HDR sem clamping, o pós-processamento requer a passagem principal HDR acima — não está disponível no renderizador de software.


← Toda a documentação Editar esta página