Novidades da WebGPU (Chrome 155-156)

Extensão fragment_depth do WGSL

Em passagens de renderização com uso intensivo de geometria, as otimizações de early-Z são as melhores amigas dos desenvolvedores. Eles oferecem um grande aumento de desempenho, permitindo que a GPU descarte pixels ocultos antes de executar sombreadores de fragmentos caros. Se uma profundidade rasterizada falhar no teste de profundidade, a GPU vai pular o shader de fragmento por completo, desde que o shader não tenha outros efeitos colaterais.

Se você quiser saber como o hardware lida com isso, o MJP tem um excelente artigo sobre When Does Early-Z Have to be Disabled? (em inglês).

Embora a manipulação de profundidade personalizada seja útil, fazer isso no sombreador de fragmentos tem um custo oculto. A gravação em @builtin(frag_depth) dentro de um sombreador de fragmento normalmente força os drivers a desativar essas otimizações de Z antecipado para toda a chamada de desenho. Isso acontece porque as heurísticas do driver não podem garantir que a profundidade de saída calculada do sombreador corresponda à profundidade interpolada pelo rasterizador.

Para resolver essa penalidade de desempenho, a extensão WGSL fragment_depth permite especificar um nome de modo de profundidade less ou greater em @builtin(frag_depth) para indicar explicitamente como a profundidade escrita se compara à profundidade interpolada, permitindo que a GPU aplique otimizações de Z antecipadas com segurança.

Essa extensão de linguagem pode ser detectada no JavaScript usando navigator.gpu.wgslLanguageFeatures. É recomendável usar uma diretiva de requisitos para sinalizar o potencial de não portabilidade com requires fragment_depth; na parte de cima do código do sombreador WGSL. Confira o exemplo a seguir e a intenção de envio.

if (!navigator.gpu.wgslLanguageFeatures.has("fragment_depth")) {
  throw new Error(`WGSL fragment depth is not available`);
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const shaderModule = device.createShaderModule({ code: `
  requires fragment_depth;

  @fragment
  fn main() -> @builtin(frag_depth, less) f32 {
    // Explicitly states that the output fragment depth is less than early-Z depth,
    // allowing the GPU to safely preserve early-Z optimizations.
    return 0.0f;
  }`,
});

Compactação de textura não alinhada

O recurso de GPU "texture-compression-unaligned" permite a criação de texturas compactadas com dimensões que não são múltiplos inteiros do tamanho do bloco (como 4x4 para os formatos BC, ETC2 e ASTC). Antes, a WebGPU exigia que os tamanhos de textura se alinhassem a esses limites de bloco. Ao remover a necessidade de preencher ou dimensionar texturas para se ajustarem aos alinhamentos de blocos, esse recurso preserva a fidelidade de compactação original sem introduzir distorção de dimensionamento. Consulte a intent to ship (em inglês).

O snippet de código a seguir verifica se o adaptador é compatível com a compactação de textura não alinhada e, se disponível, solicita um dispositivo com ela.

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("texture-compression-unaligned")) {
  throw new Error("Texture compression unaligned support is not available");
}
// Explicitly request texture compression unaligned support.
const device = await adapter.requestDevice({
  requiredFeatures: ["texture-compression-unaligned"],
});

Agradecemos ao colaborador externo Ignacio Castaño do spark.js por impulsionar esse recurso, a especificação e o trabalho do CTS.

Espaços de cores srgb-linear e display-p3-linear

Com a adição dos espaços de cores predefinidos "srgb-linear" e "display-p3-linear", o contexto de tela da WebGPU agora pode renderizar diretamente em espaços de cores lineares de alcance estendido para oferecer suporte a telas de ampla gama. Esses espaços de cores mantêm uma relação linear entre os valores de pixel e a luminância física. Isso as torna ideais para renderização de luz física em jogos, bem como tarefas de processamento espacial, como suavização, interpolação e decimação. Consulte a intenção de envio e o exemplo de partículas (HDR) PR #574.

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const canvas = document.querySelector("canvas");
const context = canvas.getContext("webgpu");

context.configure({
  device,
  format: "rgba16float",
  colorSpace: "display-p3-linear",
});

Formato de vértice snorm10-10-10-2 adicional

O formato de vértice "snorm10-10-10-2" é um formato de 32 bits compactado que contém quatro valores normalizados com sinal: três componentes de 10 bits (r, g, b) e um componente de 2 bits (a). Com esse formato, é possível armazenar atributos de maneira eficiente, como vetores normais 3D com um escalar extra de 2 bits ou uma flag de alinhamento, economizando largura de banda de memória. Consulte a especificação PR 6491.

Suporte a f16 no Linux para NVIDIA

O recurso opcional "shader-f16", que oferece suporte a valores de ponto flutuante de 16 bits em WGSL, agora é compatível com o Linux para drivers de GPU NVIDIA recentes. Consulte o problema chromium:42251215.

Atualizações do Dawn

Agora é possível consultar o LUID do DXGIAdapter de um determinado adaptador de GPU usando a struct WGPUAdapterPropertiesD3D. Consulte o problema chromium:562849566.

Este item abrange alguns dos principais destaques. Confira a lista completa de commits.

Novidades na WebGPU

Uma lista de tudo o que foi abordado na série Novidades na WebGPU.

Chrome 155-156

Chrome 153-154

Chrome 151-152

Chrome 149-150

Chrome 147-148

Chrome 146

Chrome 145

Chrome 144

Chrome 143

Chrome 142

Chrome 141

Chrome 140

Chrome 139

Chrome 138

Chrome 137

Chrome 136

Chrome 135

Chrome 134

Chrome 133

Chrome 132

Chrome 131

Chrome 130

Chrome 129

Chrome 128

Chrome 127

Chrome 126

Chrome 125

Chrome 124

Chrome 123

Chrome 122

Chrome 121

Chrome 120

Chrome 119

Chrome 118

Chrome 117

Chrome 116

Chrome 115

Chrome 114

Chrome 113