Co nowego w WebGPU (Chrome 129)

François Beaufort
François Beaufort

Obsługa HDR w trybie mapowania tonów na płótnie

Deweloperzy stron internetowych mają ograniczone możliwości dostarczania treści HDR, głównie za pomocą elementów <img><video>. Element <canvas> pozostaje jednak ograniczony do SDR. Generowanie dynamicznych treści HDR w obszarze roboczym wymaga zakodowania ich zawartości jako obrazu HDR przed wyświetleniem (przykład znajdziesz w tym demo).

Nowy parametr GPUCanvasToneMappingMode w konfiguracji obszaru rysowania WebGPU umożliwia teraz rysowanie kolorów jaśniejszych niż biały (#FFFFFF). Odbywa się to w tych trybach:

  • "standard": domyślne zachowanie ogranicza treści do zakresu SDR ekranu. Ten tryb jest realizowany przez ograniczenie wszystkich wartości kolorów w przestrzeni kolorów ekranu do przedziału [0, 1].

  • "extended": odblokowuje pełny zakres HDR ekranu. Ten tryb dopasowuje "standard" do [0, 1] zakresu ekranu. Przycinanie lub projekcja jest wykonywana na rozszerzonym zakresie dynamicznym ekranu, ale nie na [0, 1].

Poniższy fragment kodu pokazuje, jak skonfigurować obszar roboczy pod kątem wysokiego zakresu dynamiki.

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",
  toneMapping: { mode: "extended" },
});

Poznaj HDR w WebGPU, sprawdzając przykładowe cząsteczki (HDR)przykład HDR w WebGPU, oraz zapoznaj się z wpisem na chromestatus.

Laptop z ekranem HDR wyświetlający żywy obraz.
Próbka Particles (HDR) wyświetlana na ekranie HDR.

Obsługa rozwiniętych podgrup

Po ogłoszeniu eksperymentów z podgrupami funkcje wbudowane podgrup są teraz dostępne do użycia zarówno w shaderach obliczeniowych, jak i w shaderach fragmentów. Nie są już ograniczone tylko do shaderów obliczeniowych. Zobacz problem 354738715.

Pamiętaj, że wbudowana wartość subgroup_size jest obecnie wadliwa w shaderach fragmentów. Na razie tego unikaj.

Dodano też te wbudowane funkcje podgrup:

  • subgroupAdd(value): zwraca sumę wszystkich aktywnych wywołań values w podgrupie.
  • subgroupExclusiveAdd(value): zwraca wyłączną sumę skanowania wszystkich aktywnych wywołań values w podgrupie.
  • subgroupMul(value): zwraca iloczyn wszystkich aktywnych wywołań values w podgrupie.
  • subgroupExclusiveMul(value): Zwraca wyłączny iloczyn skanowania wszystkich aktywnych wywołań values w podgrupie.

  • subgroupAnd(value): zwraca wynik operacji AND na wszystkich aktywnych wywołaniach values w podgrupie.
  • subgroupOr(value): zwraca binarną operację OR wszystkich aktywnych wywołań values w podgrupie.
  • subgroupXor(value): zwraca binarną operację XOR wszystkich aktywnych wywołań values w podgrupie.

  • subgroupMin(value): zwraca minimalną wartość wszystkich aktywnych wywołań values w podgrupie.
  • subgroupMax(value): zwraca maksymalną wartość wszystkich aktywnych wywołań values w podgrupie.

  • subgroupAll(value): zwraca wartość „true” (prawda), jeśli warunek value jest spełniony we wszystkich aktywnych wywołaniach w podgrupie.
  • subgroupAny(value): zwraca wartość „true” (prawda), jeśli value ma wartość „true” (prawda) w przypadku dowolnego aktywnego wywołania w podgrupie.

  • subgroupElect(): zwraca wartość „prawda”, jeśli to wywołanie ma najniższą wartość subgroup_invocation_id spośród aktywnych wywołań w podgrupie.
  • subgroupBroadcastFirst(value): value z aktywnego wywołania z najniższym subgroup_invocation_id w podgrupie są przesyłane do wszystkich innych aktywnych wywołań.

  • subgroupShuffle(value, id): zwraca value z aktywnego wywołania, którego subgroup_invocation_id pasuje do id.
  • subgroupShuffleXor(value, mask): zwraca value z aktywnego wywołania, którego subgroup_invocation_id pasuje do subgroup_invocation_id ^ mask. mask musi być dynamicznie jednolity.
  • subgroupShuffleUp(value, delta): zwraca value z aktywnego wywołania, którego subgroup_invocation_id pasuje do subgroup_invocation_id - delta.
  • subgroupShuffleDown(value, delta): zwraca value z aktywnego wywołania, którego subgroup_invocation_id pasuje do subgroup_invocation_id + delta.

  • quadBroadcast(value, id): emituje value z wywołania czwórkowego o identyfikatorze id. id musi być wyrażeniem stałym.
  • quadSwapX(value): zamienia value między wywołaniami w kwadracie w kierunku X.
  • quadSwapY(value): zamienia value między wywołaniami w kwadracie w kierunku Y.
  • quadSwapDiagonal(value): zamienia value między wywołaniami w kwadracie po przekątnej.

Aktualizacje Dawn

Struktura wgpu::PrimitiveState zawiera teraz bezpośrednio ustawienie sterowania przycinaniem głębi, co eliminuje potrzebę stosowania osobnej struktury wgpu::PrimitiveDepthClipControl. Więcej informacji znajdziesz w tym fragmencie kodu i w żądaniu wycofania webgpu-headers.

// Before
wgpu::PrimitiveState primitive = {};
wgpu::PrimitiveDepthClipControl depthClipControl;
depthClipControl.unclippedDepth = true;
primitive.nextInChain = &depthClipControl;
// Now
wgpu::PrimitiveState primitive = {};
primitive.unclippedDepth = true;

To tylko niektóre z najważniejszych zmian. Pełną listę zmian znajdziesz w repozytorium.

Nowości w WebGPU

Lista wszystkich tematów omówionych w serii Nowości w WebGPU.

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