ANGLE's translated shader is written in the dialect the renderer string implies
Check id shader-backend-vs-renderer
What an ordinary browser yields
A renderer string naming Direct3D comes with an HLSL translation; the two describe the same backend because one of them is produced by it.
What a detector infers
The UNMASKED_RENDERER_WEBGL string is a label — a piece of text a page can rewrite to name any GPU and any graphics backend. ANGLE's translated shader source is not a label: it is the compiler's own output, produced by whichever backend is actually running, and handed back through WEBGL_debug_shaders. Those are two accounts of one fact, and one of them is generated by the machinery being described. The dialects are unambiguous where it matters. ANGLE's Direct3D backend compiles GLSL down to HLSL and the translation opens with an HLSL preamble; its GL and Vulkan backends emit versioned GLSL instead. So a renderer string containing Direct3D, on a machine whose translator emits '#version 450', has named a backend the machine is not running — the classic shape of a Linux container presenting a Windows GPU. Only the Direct3D direction is asserted, deliberately: D3D always means HLSL, whereas the GL, Vulkan and Metal backends all produce GLSL-family output and separating them from the translation alone would be guesswork rather than evidence. The check declines when WEBGL_debug_shaders is unavailable — Firefox does not expose it — and when the renderer is masked, because then there is no claim to check anything against.
How to resolve it
The renderer string is a name tag; the translated shader is what the compiler actually did. Rewriting the string to say Direct3D while the machine runs Mesa or Vulkan leaves the translation speaking GLSL, and no page-world override reaches the shader translator — it runs below the JavaScript that would patch it. Present the backend the machine really has.
Read in the wild by
Kasada
Reads the unmasked renderer and vendor strings and hashes the full parameter table — the claim side of this comparison.
gl_unmasked_vendor, gl_unmasked_renderer, webgl1_unmasked_renderer, webgl2_unmasked_renderer
ips.js 427-probe teardown (emro.cat, Apr 2026)
Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Render & GPU
- SVG's screen matrix agrees with the element's client rect
svg-ctm-vs-client-rectTwo independent routes to a single fact. getScreenCTM maps an SVG element's user space into viewport coordinates, and getBoundingClientRect… - IntersectionObserver's rect agrees with getBoundingClientRect
client-rect-vs-observerA third account of where one element sits, from the most ordinary API that has one. - WebGPU's build constants are identical in every realm
webgpu-sync-surface-vs-realmWebGPU's cheapest fingerprint is not the GPU at all. navigator.gpu.getPreferredCanvasFormat() and navigator.gpu.wgslLanguageFeatures are… - the GL limits the driver reports are limits the driver will actually honour
webgl-limits-vs-driverEvery other WebGL check on this page reads what getParameter SAYS. - every extension WebGL advertises can actually be instantiated
webgl-extensions-vs-drivergetSupportedExtensions() returns a list a page can rewrite; getExtension(name) either hands back a real extension object or null, and that… - the clear path and the shader path paint opaque red to the same bytes
webgl-draw-path-invarianceOpaque red can be produced two ways: the fixed-function clear path, and a fragment shader emitting vec4(1,0,0,1). - a mediump claim of fp32 precision is delivered by the arithmetic
shader-mediump-claim-vs-arithmeticgetShaderPrecisionFormat is a claim about float precision; a shader that computes a value only fp32 can represent is the GPU keeping or… - silence renders as exact zero through the Web Audio graph
audio-render-silence-integrityThe other audio checks compare two renders of a sound; this one renders silence and asserts it stayed silent, which catches a different kind…
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Render & GPU checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Render & GPU — the family shader-backend-vs-renderer belongs to.