Отчёт BrowserLeaks WebGL: сбор и отсутствующие данные
Проследите поля WebGL в BrowserLeaks от выбора контекста до параметров, расширений, точности и пикселей, не угадывая причину пропуска.
BotBrowser Team
Нужна структурированная документация по теме Отпечатки?
Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.
Если в отчёте BrowserLeaks WebGL поле рендерера или хеш изображения пустое, это само по себе не указывает на причину. Публичная страница объединяет выбор контекста, чтение обычных параметров, необязательные метаданные рендерера, проверки точности шейдера и хеш от отрисованных пикселей. BotBrowser может сохранять объявленный профиль для разрешённой проверки WebGL, но не может объяснить пропуск в стороннем отчёте или предсказать решение другого сервиса. Разбор исходного кода CreepJS WebGL описывает другой сборщик и его сравнения контекстов.
TL;DR
- BrowserLeaks пробует фиксированную последовательность имён контекстов WebGL, прежде чем собирать строки для выбранного контекста.
- Обычные строки
getParameter, необязательноеWEBGL_debug_renderer_info, точность шейдера и последующий хешreadPixelsотносятся к разным путям. - Отсутствие незамаскированного рендерера не доказывает блокировку расширения, конкретную модель GPU, использование средства приватности или автоматизацию.
- Запишите ревизию страницы и этап, на котором пропало значение; повторите этот этап с той же версией браузера и тем же источником перед сравнением.
- BotBrowser документирует настройки профиля для проверки WebGL, но не гарантирует конкретное значение в BrowserLeaks или на другом сайте.
Contents
- Посмотреть видео
- Начните с этапов сбора
- Обычные параметры и необязательные данные рендерера
- Точность и пиксели: разные сигналы
- Сначала классифицируйте пропуск
- Ведите контролируемую запись отчёта
- Практический вывод
Посмотреть видео
Это видео на английском языке. Оно разбирает пять этапов сбора, а затем запускает управляемый fixture из пяти этапов в настоящем Chrome: нативный результат getContext('webgl2'), строку рендерера из отладочного расширения, целое число точности шейдера и реальный буфер readPixels. Fixture воспроизводит опубликованный порядок этапов и не измеряет устройство конкретного человека.
Начните с этапов сбора
Публичная страница BrowserLeaks WebGL представляет собой шаблон отчёта с отдельными разделами проверки поддержки, отпечатка WebGL, хеша отчёта, хеша изображения и самой картинки. Исходный код страницы и скрипт показывают порядок сбора, но скачивание файлов не запускает отчёт в браузере. Поэтому приведённые выводы описывают исходный код, а не результат работы профиля в реальном браузере.
Скрипт пробует имена контекстов в таком порядке: webgl2, webgl, moz-webgl, webkit-3d, webgl2-compute. Для каждого кандидата он создаёт canvas и вызывает getContext; первый пригодный контекст сохраняется и используется дальше. Переход к запасному кандидату не равен успеху первого, даже если в обоих случаях страница в итоге показывает строки.
В этом цикле есть две детали, важные, когда отчёт выглядит неверным. Во-первых, canvas создаётся фиксированного размера 256 на 128 и повторно используется на этапе отрисовки, поэтому размеры буфера отрисовки описывают этот canvas, а не окно браузера. Во-вторых, каждая попытка передаёт failIfMajorPerformanceCaveat: false и отбрасывает контекст, у которого isContextLost() уже вернул истину. Кандидат, не прошедший любую из двух проверок, пропускается молча, и цикл продолжается, поэтому запасное имя может дать полный отчёт, тогда как первое не даёт ничего.
Сборщик сохраняет все полученные контексты, а не только выбранный. Селектор контекста на странице строится по этому списку, поэтому число предложенных имён фиксирует, сколько попыток удалось. Если селектор показывает только webgl, значит webgl2 был опрошен и отклонён; это не объясняет причину и не означает, что в браузере вообще нет WebGL2.
| Этап | Действие публичного скрипта | Что позволяет сузить отсутствие данных |
|---|---|---|
| Выбор контекста | Пробует имена кандидатов на новом canvas | Был ли получен кандидатный контекст; не объясняет пропуски последующих полей |
| Строки параметров | Сопоставляет ID элемента со свойством контекста и передаёт в getParameter полученную константу | Какой обычный запрос не дал отображаемого значения |
| Отладочный рендерер | Запрашивает WEBGL_debug_renderer_info и читает незамаскированные константы только при наличии объекта расширения | Вернула ли необязательная ветка значение; не сама идентичность GPU |
| Точность | Отдельно вызывает помощники точности шейдера | Получен ли пригодный итог проверки точности |
| Хеш изображения | Рисует отдельную сцену, читает буфер пикселей, сериализует его и вычисляет хеш | Завершился ли путь отрисовки и чтения; не успешность сборщика параметров |
| Хеш отчёта | Сериализует собранный объект и вычисляет хеш сериализации | Осталась ли сериализация стабильной между съёмками; не правильность отдельной строки |
Таблица помогает читать отчёт, но не перечисляет все причины отказа браузера. Разные этапы могут оставить одинаково пустое место, а сама страница не всегда показывает, какой именно этап не удался. Общий материал об отпечатке WebGL рассматривает более широкую поверхность сигналов и документированные настройки профиля; здесь разбирается именно конвейер BrowserLeaks.
Обычные параметры и необязательные данные рендерера
Для обычных строк BrowserLeaks перебирает элементы .pname, читает ID каждого, находит свойство с таким именем в выбранном контексте WebGL и передаёт в getParameter полученную константу. Поэтому таблица отчёта служит полезным перечнем запросов, но каждая строка свидетельствует только об одном запросе в одном контексте. Она не описывает GPU целиком, а пустая строка не сообщает, был ли запрос пропущен, вернул ли он значение, которое интерфейс не отобразил, или произошла более ранняя ошибка.
Использование ID элементов как имён свойств имеет следствие: имена строк задаёт страница, а запрашиваемые константы берутся из выбранного контекста WebGL. В опубликованном скрипте n обозначает этот контекст, а каждый указанный ID передаётся как getParameter(n[id]). Константа из спецификации не появится в таблице, если её нет в разметке; добавление ID, соответствующего свойству контекста, изменит собранный объект без изменений в браузере.
После цикла сборщик объединяет в один объект три источника, не являющиеся параметрами: атрибуты из getContextAttributes(), свойства drawingBufferColorSpace и unpackColorSpace, а также список поддерживаемых расширений. Атрибуты контекста это значения, с которыми контекст создавался, а не сведения браузера о железе; два свойства цветового пространства это строки, следующие настройкам canvas. Читать их в одной плоской таблице удобно, но они отвечают на другие вопросы, чем строка getParameter.
Поля незамаскированного производителя и рендерера идут по другой ветке. Сначала скрипт вызывает getExtension('WEBGL_debug_renderer_info'); только если получен объект расширения, он читает UNMASKED_RENDERER_WEBGL и UNMASKED_VENDOR_WEBGL. В документации MDN указано, что getExtension() возвращает объект при поддержке расширения и null, если оно недоступно. Это объясняет условие ветки, но не причину отсутствия незамаскированной строки в конкретном отчёте. Отдельный разбор границ приватности WEBGL_debug_renderer_info отличает состояние API от выводов об идентичности.
Ещё два параметра читаются через собственные расширения, а не через обычный список: MAX_DRAW_BUFFERS_WEBGL из WEBGL_draw_buffers и MAX_TEXTURE_MAX_ANISOTROPY_EXT из первого сработавшего среди EXT_texture_filter_anisotropic, WEBKIT_EXT_texture_filter_anisotropic и MOZ_EXT_texture_filter_anisotropic. Оба зависят от поиска расширения, поэтому оба могут остаться пустыми по той же причине, что и незамаскированный рендерер. В разметке эти строки стоят рядом с обычными параметрами, из-за чего разницу легко пропустить.
Разделяйте эти случаи в заметке к отчёту:
| Наблюдение | Обоснованная формулировка | Необоснованный вывод |
|---|---|---|
| Обычная строка рендерера есть, незамаскированная пустая | Обычная строка показана, необязательное незамаскированное значение: нет | «Браузер скрывает конкретный GPU» |
| Поиск расширения не вернул объект | Необязательной ветке было нечего опрашивать | «Средство приватности заблокировало расширение» |
| Контекст не выбран | Сборщик не продолжил работу с выбранным контекстом | «В браузере нет GPU» |
| В сохранённом отчёте нет поля | В сохранённом артефакте поле отсутствует | «Исходный вызов API завершился ошибкой» |
Каждый необоснованный вывод придумывает ненаблюдавшуюся причину. Вторая съёмка помогает проверить повторяемость того же этапа, но не устанавливает причину без фиксации изменившихся условий.
Точность и пиксели: разные сигналы
Точность шейдера получается отдельными вызовами getShaderPrecisionFormat, а не выводится из строки отладочного рендерера. Поэтому итог точности и метка рендерера могут различаться, не будучи повреждёнными копиями одного значения. Если потребитель отчёта показывает эти данные, отдельно запишите этап шейдера, класс точности, возвращённые диапазон и точность, а также исключение или отсутствие результата.
Отчёт показывает два разных итога точности. Один сравнивает результат высокой точности с плавающей запятой с результатом средней точности для того же этапа шейдера и берёт средний результат, если высокий сообщает нулевую точность. Другой сводит два отдельных запроса, HIGH_FLOAT и HIGH_INT, к короткой метке highp/mediump и highp/lowp. Таким образом, одна метка в таблице представляет до трёх вспомогательных вызовов, и значение, которое кажется грубым, может происходить из резервной ветки, а не из реальной поддержки точности браузером.
Хеш изображения рассчитывается ещё одним путём. BrowserLeaks рисует небольшую сцену WebGL, через readPixels считывает пиксели в Uint8Array, сериализует массив и вычисляет хеш сериализации. Этот хеш описывает такую сцену в выбранном контексте и условиях выполнения. Это не параметр API и не доказательство идентификации человека или устройства.
Рисунок представляет собой фиксированный веер отрезков, построенный циклом из 128 шагов между 45 и 315 градусами и нарисованный через LINE_STRIP с жёстко заданной матрицей проекции. Поскольку геометрия берётся из констант, изменение хеша изображения указывает на путь отрисовки, размер canvas, цветовое пространство или чтение, а не на другую модель GPU. Хеш отчёта покрывает другой вход: это хеш сериализованного объекта, поэтому он меняется при изменении любой собранной строки, включая строки, не связанные с отрисовкой.
Для контролируемого сравнения сохраняйте ревизию отчёта, сборку браузера, ОС, источник, имя выбранного контекста, область просмотра и время сбора. Сравнивайте строки параметров с такими же строками, данные расширения с ними же, точность для того же запроса, а хеши: только при неизменных сцене и чтении. Если изменился только хеш, проверьте входные данные сцены и этап чтения, прежде чем приписывать отличие рендереру или профилю.
Не сводите всё к одному полю «отпечаток WebGL». Такая метка скрывает вызов, который произвёл значение, и то, что можно повторить. Компактная запись с отдельными результатами по этапам полезнее при диагностике экспорта отчёта или совместимости страницы.
Сначала классифицируйте пропуск
Используйте первую подходящую строку. Последующая проверка помогает отличить проблему этапа сбора от отображения отчёта и не предполагает заранее конкретный дефект браузера.
Перед таблицей стоит разделить два состояния. Значение, показанное как empty,: это null или пустая строка, возвращённые getParameter, то есть пустой ответ, а не отсутствующий вызов. Значение, показанное как undefined, означает, что в собранном объекте не было ключа для этой строки, и указывает на этап сбора, а не на сам запрос. На снимке эти метки похожи, но ведут к разным проверкам.
| Что отсутствует | Первая проверка | Повторяемое продолжение |
|---|---|---|
| Все разделы WebGL | Выполнялись ли проверка поддержки и выбор контекста | Один раз перезагрузите страницу с тем же источником и версией; сохраните выбранный контекст либо точный этап ошибки |
| Один параметр | Есть ли соответствующий ID строки в скачанной ревизии | Повторите этот запрос на собственной диагностической странице и сохраните тип/значение или исключение |
| Только незамаскированный производитель или рендерер | Получила ли необязательная ветка объект расширения | Запишите доступность расширения отдельно от обычной строки; не выводите блокировку из отсутствия |
| Итог точности | Какой этап шейдера и класс точности запрашивался | Повторите тот же вызов и сохраните результат или исключение |
| Только хеш изображения | Завершились ли рисование, readPixels, сериализация и вычисление хеша | Сохраните ревизию рисунка и результат чтения; не сравнивайте разные сцены |
| Только хеш отчёта | Изменилась ли какая-либо собранная строка между съёмками | Сначала сравните значения по строкам; другой хеш при неизменных строках указывает на смену порядка сериализации |
Если два отчёта расходятся, запишите, что осталось постоянным и что изменилось. Другая ревизия страницы, запасной контекст, источник, настройки экрана или сцена способны изменить путь без доказательства смены идентичности браузера. И наоборот, совпадение значений в одном отчёте не доказывает эквивалентность несвязанных приложений.
На странице есть переключатель исходных ключей, который переписывает первый столбец таблицы. Он меняет только метку, которую видит читатель, а не собранный объект, поэтому два снимка одной и той же съёмки могут различаться в этом столбце. Проверяя, собрали ли два отчёта одинаковые строки, сравнивайте имена ключей, а не подписи.
Ведите контролируемую запись отчёта
Это схема записи, а не пример результата. Заполните поля по отчёту и своему снимку; не копируйте ожидаемое значение в поле наблюдения.
{
"toolUrl": "https://browserleaks.com/webgl",
"capturedAt": "YYYY-MM-DDTHH:mm:ssZ",
"pageRevision": "сохранить URL скрипта или хеш содержимого",
"browserBuild": "указать фактическую сборку",
"origin": "указать источник отчёта",
"selectedContext": "указать фактическое имя контекста или null",
"ordinaryParameterRows": "есть, нет или ошибка для каждой строки",
"debugRendererExtension": "объект, null или ветка не достигнута",
"precisionChecks": "записать каждый класс и результат",
"pixelRead": "завершено, отсутствует или ошибка",
"imageDigest": "записать, только если он действительно есть"
}
Эта схема хранит ревизию и состояние сбора рядом со значениями, чтобы при следующем сравнении можно было повторить тот же путь. Здесь намеренно нет поля вердикта: вывод о принятии среды приложением требует данных из его документированного и разрешённого контекста.
Запись, заполненная по одной съёмке, отвечает на более узкий вопрос, чем запись по нескольким. Одна съёмка устанавливает, что ветка дала значение при записанных условиях. Несколько съёмок с изменённым условием могут показать, чувствительна ли ветка к этому изменению, но только если все остальные поля остались теми же. Схема фиксирует условия и не выставляет странице оценку.
FAQ
Пустой незамаскированный рендерер означает, что расширение заблокировано?
Нет. Это означает, что в сохранённом отчёте такого значения нет. Прежде чем делать более узкий вывод, запишите, достиг ли сборщик ветки расширения и что вернул getExtension().
Является ли хеш изображения ещё одним идентификатором GPU?
Это хеш пикселей, отрисованных скриптом. Он может помочь сравнить одну и ту же процедуру рисунка, но сам по себе не определяет GPU, устройство или человека.
Гарантирует ли BotBrowser совпадение этих полей с BrowserLeaks?
Нет. BotBrowser документирует настройки профиля для разрешённой проверки браузерных поверхностей. Отчёт зависит от своего скрипта, ревизии страницы и условий выполнения, поэтому настройка не гарантирует чужой вывод или классификацию.
Sources
- Отчёт BrowserLeaks WebGL и его опубликованный сборщик, просмотренные как исходный код 2026-11-04.
- MDN:
WebGLRenderingContext.getExtension()иgetParameter(). - BotBrowser: настройки отпечатка WebGL и практики согласованности автоматизации.
- Сборщик WebGL и сигналы возможностей CreepJS: о другом сборщике CreepJS.
Практический вывод
Рассматривайте отчёт BrowserLeaks WebGL как несколько путей сбора, а не единый результат «пройдено/не пройдено». Фиксируйте отдельно контекст, параметры, необязательное расширение, точность и чтение пикселей; повторяйте только отсутствующий этап при записанных условиях. Так получится обоснованно сравнить данные, не угадывая причину пропуска и не превращая отличие отрисовки в вердикт о человеке или боте.
Эта статья входит в руководство: Что такое отпечаток браузера?
Похожие статьи
Отчёт CreepJS WebGL: контексты и сигналы
ОтпечаткиWEBGL_debug_renderer_info: границы приватности и renderer
ОтпечаткиНет рендерера WebGL: приватность или состояние контекста?
Отпечаткиwebgl_debug_renderer_info: что GPU раскрывает страницам
ОтпечаткиОтчёт BrowserLeaks Canvas: сигналы и ограничения
ОтпечаткиПрограммный рендеринг WebGL, откат возможностей и приватность
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.