NNTC latent viewer WebGPU v1.00

Load
Your files
the .json and its .dds files - together (Ctrl+A), or a few at a time, from any folders
or drag the files onto this page
Loaded files
nothing loaded yet
Show

Applies to all three views above. A four-channel latent's fourth channel can only be seen this way; in Decode, A is 1.0 by construction and draws white.

View
Geometry C

A material with more than one output texture draws them side by side, so two can be compared without switching between them. N, and the Texture pulldown above, then slide which texture sits on which object rather than picking one to look at: with the row on, that control is an offset into the row.

Unpack, unit length, repack. Grey-ish and black-ish pixels and those with z < 0 are left alone, as the native viewers leave them.

Sample
Filter

The level-1 shift is the encoder's 1:1 mip rule: off is visibly wrong from mip 1 down, and that is what it is for. It is applied to the GRADIENTS, because WebGPU's sampler has no LOD bias field at all.

Camera

Arrows move, W/S zoom, A/D yaw, Q/E pitch, with Shift for one third the speed; dragging the view and the wheel do the same. Space, or "Reset view" at the foot of the Show group, puts the camera and every mode above back.

Decode

Display

Display only: it relabels the canvas and changes no pixel, so the same numbers look more saturated on a wide-gamut screen. The native viewers have no such control, so anything but sRGB is a picture they cannot draw.

Keys

Click the view first: the keys go to the canvas, so typing in the panel never moves the camera.

Every key is listed in Help (the button at the top, or F1), and every one of them is a control in this panel as well.

About

The NNTC asset on a real hardware sampler, in the browser. The decode is a port of viewer/bin/nntc_view.hlsl, which the Direct3D 11 and Direct3D 12 viewers share; see webgpu/README.md beside this page.

Frame

A capture never contains the overlay, so two of them can be compared byte for byte. Copy link carries the camera and every mode, and the material when it is one of the bundled ones - a folder of your own is not something a link can reach.

Messages

This does not turn validation on: WebGPU checks every call already, always, and anything it refuses reaches the log below - tagged [WebGPU] - whatever this box says. What it changes is the RESPONSE: an error becomes a stop, with the message held in front of you and drawing halted on the last good frame, instead of a line the moving picture carries past your attention.

Every message this page shows is kept here in order, each one numbered, timed, and tagged with where it came from: [WebGPU] for anything the device or driver refused, [page] for the viewer's own. The status line at the top of the panel shows only the newest.

no messages

    

click the view for keys

NNTC latent viewer WebGPU v1.00

What this is

An NNTC material is two small latent textures and a handful of weights. This page samples each latent once per pixel with the GPU's own sampler - the same filtering, mips and anisotropy a game would use - and runs the decoder in the fragment shader, so what you see is what a real renderer would get rather than an offline decode. The shader is a transliteration of viewer/bin/nntc_view.hlsl, the file the Direct3D 11 and Direct3D 12 viewers both compile, and this page's keys are those viewers' keys.

Where the GPU has no texture-compression-bc, the page unpacks BC4 and BC5 on the CPU in plain JavaScript and binds uncompressed planes instead; the shader does not change. The Decode block in the panel says which path drew level 0.

The workflow

  1. Open a bundled material. The pulldown at the top of the panel lists the materials that ship with this page; one is already open. Picking another resets the view, because a new material is a new thing to look at.
  2. Or give the page a folder. Drop a folder on the page, or press "Select working directory..." where your browser has that button (Chrome and Edge do, and the panel says so when yours does not). The page treats the two the same way. Every material in the folder joins the same pulldown. You can open one of them by picking or dropping its .json on its own, because the page reads the .dds files it names out of that folder. Reload re-reads those files from disk and lists the folder again, so a material you encode while the page is open shows up too. The page only reads your files. It never writes. A folder you pick with the button is remembered for your next visit, though the browser may ask you once more before the page may read it. A folder you drop in a browser that has no such button cannot be stored at all, so you drop it again next time. The panel says which of the two you have.
  3. Or bring your own files. Select a material's PREFIX_nntc.json and its .dds files together (open the folder, Ctrl+A, Open), or drag the group - or the folder itself - onto the page. No browser hands a page a file's siblings, so the descriptor alone cannot load on its own - but the page keeps every file you offer it, so picking the .json and then picking its .dds files works, in as many goes as it takes and from as many folders. Until the set is complete the top of the panel says what is still wanted, by name, the rows under "Your files" list what is in hand, and the material on screen does not move.
  4. Look. Drag the view to yaw and pitch, the wheel zooms, and the keys below do the rest. The Loaded files block is the asset's own facts: both latents side by side, the four bitrates and the decoder's weight count. Channel(s) to view, in the Show group, draws one channel at a time - R, G, B or A - in all three views, and draws it as grey rather than in its own colour, so what you read is a magnitude and not a hue. It is the only way to see a four-channel latent's fourth channel. In Decode, alpha is 1.0 by construction and A therefore draws white.
  5. Re-encode and press R. Reload re-reads the same files and keeps the camera and every mode, which is the whole point of it: the same angle and the same settings, the new encode. It is the opposite of Reset.

Reset, and what it covers

Space, the Reset view button at the foot of the Show group and the button below all do the same thing: the camera, the filter, anisotropy, mips, the level-1 LOD shift, the geometry, the raw views, the renormalise flag, the channels shown and the shown texture all go back to where a fresh load leaves them. It is there for when a few keystrokes have left the picture looking wrong and you cannot remember which one did it.

Four things it deliberately leaves alone. Three are about the device or the display rather than the view: the CPU unpack checkbox (which path level 0 is bound through), the canvas colour space, and "Stop on a WebGPU error" beside the message log. The fourth is the drawn frame-rate and camera strip, which is a thing over the picture and not part of it.

Keys

Click the view first - the keys go to the canvas, so typing in the panel never moves the camera. Every key here is also a control in the left panel, and the two always agree.

Camera (hold)
arrowsmove the quad or cube left / right / up / down
W / Szoom in / out
A / Dyaw
Q / Epitch
Shiftwith any of the above: one third the speed
Spacereset: the camera and every mode below, back to a fresh load
Display
Cquad, cube, sphere
Gone object per output texture, in a row; N then slides which texture is on which
Oturn the view by itself, 30 degrees a second
Nnext output texture of a material (cycles)
1show level 0's texture as stored (toggle)
2show level 1's texture as stored (toggle)
Vrenormalise the shown texture as a tangent-space normal (toggle)
Sampling
P / B / Tpoint / bilinear / trilinear filter
Xanisotropic filtering on / off (trilinear filtering only)
Mmips on / off (off: the sampler is held at mip 0, nothing is reloaded)
Llevel 1's LOD shift on / off (its gradients x 2^lod_bias_level1)
Other
Rreload the asset, keeping the camera and every mode
Shift+Rreload the shader (nntc_view.wgsl)
F1this page
Escclose this page
drag, wheelyaw and pitch; zoom

Three differences from the native viewers, and no others. R reloads the asset here and Shift+R the shader, because the asset is the thing that changes ten times an hour in an encode-look-encode loop; Ctrl+R stays the browser's. Esc closes this page rather than quitting, since a page cannot close itself. And the native 4 (level 0 from a BC pack made at load) and 5-8 (the shader's spare debug constants) are not bound: the pack applies only to an uncompressed level 0 and is not implemented here, and nothing in the shipped shader reads the spare constants.

URL fields

They mirror the native viewers' flag names: ?asset=, ?tex=, ?cube, ?z= ?yaw= ?pitch= ?x= ?y=, ?nomips ?nobias ?noaniso ?renorm ?raw0 ?raw1, and beside them ?unpack=0|1, ?overlay=0, ?geom=quad|cube|sphere, ?row=1, ?orbit=1, ?filter=point|bilinear|trilinear and ?chan=rgb|r|g|b|a. A URL that sets a mode is honoured on the first load and is not undone by it.

Part of the NNTC tree; see webgpu/README.md beside this page, and docs/FORMAT.md for the format itself.