| Component name | webgl_params |
|---|---|
| In the visitorId | yes |
| structuredId group | gpu (graphics) |
| Hashing | always a digest (first 128 bits of SHA-256) |
| Excluded under | no browser class |
| Inner timeout | 1000 ms |
| Added in | signalsVersion 1 |
Every graphics setup tells web pages what it can do: the biggest texture it can handle, how many inputs a shader may have, how precise its numbers are, and which optional features (extensions) it supports. WhiskerJS reads that list and turns it into one short code. Different GPUs, drivers and browsers report different lists.
What it reads
From the shared WebGL 1 context of the collection:
- 21 parameters with
getParameter():ALIASED_LINE_WIDTH_RANGE,ALIASED_POINT_SIZE_RANGE,ALPHA_BITS,BLUE_BITS,DEPTH_BITS,GREEN_BITS,MAX_COMBINED_TEXTURE_IMAGE_UNITS,MAX_CUBE_MAP_TEXTURE_SIZE,MAX_FRAGMENT_UNIFORM_VECTORS,MAX_RENDERBUFFER_SIZE,MAX_TEXTURE_IMAGE_UNITS,MAX_TEXTURE_SIZE,MAX_VARYING_VECTORS,MAX_VERTEX_ATTRIBS,MAX_VERTEX_TEXTURE_IMAGE_UNITS,MAX_VERTEX_UNIFORM_VECTORS,MAX_VIEWPORT_DIMS,RED_BITS,SHADING_LANGUAGE_VERSION,STENCIL_BITSandVERSION; - with
getShaderPrecisionFormat(), the range and precision ofHIGH_FLOAT,MEDIUM_FLOAT,LOW_FLOATandHIGH_INTin both the vertex and the fragment shader (eight entries); - the list from
getSupportedExtensions(), sorted alphabetically.
How the technique works
Each value is written as NAME=value (arrays joined with commas, ! when a call throws, an empty value when it returns nothing), the precision entries as SHADER.PRECISION=rangeMin,rangeMax,precision, and the extensions as one comma-separated list. All parts are joined with semicolons into one string, which is always hashed with SHA-256 because webgl_params is a large component. Sorting the extension list makes the value independent of the order the browser returns them in.
Why it helps
Limits and extensions come from the GPU, the driver and the browser’s graphics layer together. A laptop’s integrated GPU, a desktop card and a phone’s GPU report different texture limits and precisions, and browsers expose different extension sets. The combination separates graphics setups that a renderer name alone might group together. It is part of the gpu group.
Stability
These values change rarely. They can change with a browser update (new or removed extensions, changed limits), a driver update, switching hardware acceleration, or a different GPU being used. They do not depend on the page, the zoom level or the window size.
Browser support and what blocks it
ok wherever a WebGL 1 context can be created. It is not in the exclusion table, so it is collected in Brave and in Firefox resistFingerprinting too (those modes change the rendered image and the GPU strings, not this list). Without WebGL it is unavailable / no_context, together with the other WebGL components.
Privacy
It reveals the capabilities of the graphics stack, not what the user does. The whole list leaves the library only as a 32-character digest. No permission, no prompt, no request.
How WhiskerJS handles noise and failures
| Status | ruleId | When |
|---|---|---|
ok |
none | the list was read; value is a digest |
unavailable |
no_document, no_api, no_context |
no document, no getContext, or no WebGL context |
unavailable |
no_digest |
no Web Crypto |
blocked |
security_error, threw |
a WebGL call threw outside the per-parameter guards |
excluded |
caller_excluded |
your exclude list |
timed_out |
timeout, aborted |
1000 ms inner timeout, overall budget, abort |
A single parameter that throws does not fail the component: it is written as ! inside the hashed string.
Example value
From a headless Chromium test browser in a container:
"webgl_params": { "status": "ok", "value": "79906793c9fee64879c122d10676691b", "hashed": true }
Questions and answers
Why is webgl_params not checked for noise?
It reads numbers and names the browser reports, not rendered pixels, so there is nothing for readback noise to change. The rendered image is checked separately in webgl_image.
Can a browser update change it?
Yes. A new browser version can add or remove WebGL extensions or change a reported limit, and the digest then changes.