# 3D-сцена на three.js Модели пишут на JavaScript модуль для three.js, который превращает JSON-описание в 3D-сцену: иерархию объектов с поворотами и масштабом, примитивы, выдавленные контуры, тысячи экземпляров, свет и камеру. Каждую сцену сравнивают с эталоном по мировым матрицам, габаритам, цветам и попаданиям лучей из камеры. 29 октября 2026. Интерактивная версия: [report.html](report.html), все бенчмарки: [../index.html](../index.html) ## Полоса тестов ![Полоса тестов](charts/strip.svg) Каждая строка показывает один прогон модели, а каждое деление в ней означает один тест. Тёмное деление значит, что тест пройден, красное значит провал, серое значит, что код не запустился. Столбцы общие для всех прогонов и отсортированы от лёгких тестов к трудным. ## Как модели построили контрольную сцену Одна и та же сцена, отрендеренная WebGL в Chrome без окна одним и тем же рендерером. Отличаются только сами сцены, которые построил код модели. Переключатель «Отличия от эталона» подсвечивает красным пиксели, которые не совпали. **Эталон** ![Эталон](gallery/reference.png) **Qwen3.8-Max**, совпало 100.0% пикселей ![Qwen3.8-Max](gallery/qwen.png) **Kimi K3.1 Pro**, совпало 100.0% пикселей ![Kimi K3.1 Pro](gallery/kimi.png) **Claude Opus 5.5 (агент)**, совпало 100.0% пикселей ![Claude Opus 5.5 (агент)](gallery/opusagent.png) **Claude Opus 5.5 (агент, effort max)**, совпало 100.0% пикселей ![Claude Opus 5.5 (агент, effort max)](gallery/opusagentmax.png) **GPT-6.1 Sol**, совпало 100.0% пикселей ![GPT-6.1 Sol](gallery/gpt.png) **DeepSeek Flash (V4.1)**, совпало 100.0% пикселей ![DeepSeek Flash (V4.1)](gallery/dsflash.png) **Claude Opus 5.5 (effort max)**, совпало 100.0% пикселей ![Claude Opus 5.5 (effort max)](gallery/opusmax.png) ## Что выяснили **Пять моделей прошли всё.** Opus 5.5 агентом, Qwen3.8-Max, Kimi K3.1 Pro, GPT-6.1 Sol и DeepSeek Flash прошли 164 сцены из 164: совпали матрицы, габариты, цвета в линейном пространстве, матрицы экземпляров и все 63 луча из камеры. Ловушки three.js вроде `lookAt`, который у объекта и у камеры смотрит в разные стороны, никого не поймали. **Фраза в задании выключила размышление у Opus через API.** «Ответь ТОЛЬКО кодом» адаптивный Opus 5.5 понимает как «не размышляй», даже при `effort: max`, и пишет код с 5-й секунды. Проверка шлюза показала, что `effort` передаётся правильно. С формулировкой «сначала продумай» Opus думал 6 тысяч токенов и прошёл 161 сцену вместо 158. В следующих тестах формулировка заменена. **Скорость кода здесь не различает модели.** Все решения строят 50 000 экземпляров и тысячи объектов с `lookAt` за сотые доли секунды. Места среди безошибочных определяются суммарным временем замеров, а эта разница на уровне погрешности. **Время ответа различается почти в 70 раз.** Opus через API ответил за 30 секунд, Opus-агент за 2 минуты 40 секунд, DeepSeek Flash за 3,5 минуты, GPT за 5 минут, Kimi за 12 минут, Qwen за 34 минуты. Колонка «Токенов/с» в таблице показывает, кто медленно пишет, а кто много думает. ## Все прогоны | Место | Модель | Тесты | Ловушки | Случайные | Ошибки | Скорость | Время | Рассуждение | Всего токенов | Токенов/с | Строк кода | С правкой | |---|---|---|---|---|---|---|---|---|---|---|---|---| | 🥇 1 | Qwen3.8-Max | 164 (100.0%) | 38/38 | 120/120 | 6/6 | 3/3 | 34 мин 12 с | 81.5K | 85.2K | 42 | 446 | — | | 🥈 2 | Kimi K3.1 Pro | 164 (100.0%) | 38/38 | 120/120 | 6/6 | 3/3 | 11 мин 56 с | 17K | 19.2K | 27 | 341 | — | | 🥉 3 | Claude Opus 5.5 (агент) | 164 (100.0%) | 38/38 | 120/120 | 6/6 | 3/3 | 2 мин 40 с | 8.5K* | 13K | 81* | 277 | — | | 4 | Claude Opus 5.5 (агент, effort max) | 164 (100.0%) | 38/38 | 120/120 | 6/6 | 3/3 | 12 мин 05 с | 80.8K* | 83.7K | 115* | 325 | — | | 5 | GPT-6.1 Sol | 164 (100.0%) | 38/38 | 120/120 | 6/6 | 3/3 | 5 мин 11 с | скрыто | 13.4K | 43 | 415 | — | | 6 | DeepSeek Flash (V4.1) | 164 (100.0%) | 38/38 | 120/120 | 6/6 | 3/3 | 3 мин 33 с | 38.8K | 41.4K | 194 | 336 | — | | 7 | Claude Opus 5.5 (effort max) | 158 (96.3%) | 38/38 | 117/120 | 3/6 | 3/3 | 30 с | 0 | 4.2K | 140 | 284 | — | В колонке «С правкой» указан результат того же кода после исправления одной-двух строк. В рейтинг он не входит. «Токенов/с» показывает, как быстро модель пишет: все токены ответа, включая рассуждение, делённые на полное время ответа. ## Время ответа ![Время ответа](charts/time.svg) ## Сколько модель написала ![Токены](charts/tokens.svg) Синим показано рассуждение, бирюзовым код и ответ. Серый цвет значит, что провайдер не показывает, сколько ушло на рассуждение. ## Разбор по участникам ### Qwen3.8-Max 164 сцены из 164 и все три замера скорости, причём самые быстрые: 0,01, 0,02 и 0,01 секунды. Зато ответ занял больше всех, 34 минуты: около 81 тысячи токенов рассуждения при скорости около 40 токенов в секунду. Код 446 строк. ### Kimi K3.1 Pro 164 сцены из 164 и все три замера скорости. Ответ занял 12 минут, из них около 17 тысяч токенов рассуждения. Код 340 строк. Третий тест подряд у Kimi без ошибок или почти без них. ### Claude Opus 5.5 (агент) 164 сцены из 164 и все три замера скорости. Решение заняло 2 минуты 40 секунд и 277 строк. Агент работал вслепую: одно чтение задания, одна запись решения, код не запускался (протокол проверен). Это третий тест подряд, где Opus-агент проходит всё. Свои допущения агент перечислил в отчёте сам, и все они совпали с эталоном. ### Claude Opus 5.5 (агент, effort max) 164 сцены из 164 и все три замера скорости. Ответ занял 12 минут, на рассуждение ушло около 81 тысячи токенов. Opus через API на том же `effort: max` не рассуждал вовсе и прошёл 158 сцен, так что разница в шесть сцен целиком объясняется размышлением. Протокол соблюдён: одно чтение задания и одна запись решения. ### GPT-6.1 Sol 164 сцены из 164 и все три замера скорости. Ответ пришёл за 5 минут 10 секунд, рассуждение провайдер не показывает. Код самый длинный среди безошибочных, 414 строк. ### DeepSeek Flash (V4.1) 164 сцены из 164 и все три замера скорости, и снова самый быстрый ответ среди безошибочных: 3,5 минуты. На рассуждение ушло почти 39 тысяч токенов, код 335 строк. ### Claude Opus 5.5 (effort max) 158 сцен из 164 и все три замера скорости, ответ за 30 секунд без размышления. В трёх случайных сценах не совпали мировые матрицы: модель один раз обновляет матрицы и потом применяет все `lookAt` подряд, поэтому потомок поворачивается по устаревшему положению родителя, у которого тоже есть `lookAt`. Ещё три промаха на проверке ввода: не ловятся неверный цвет, цвет из четырёх цифр и неверный порядок поворота у узла без `rotation`. Отдельная проверка показала, что размышление отключает последняя фраза задания «Ответь ТОЛЬКО кодом»: с фразой «сначала продумай» тот же Opus думал 6 тысяч токенов и прошёл 161 сцену. ## Задача Нужно написать ES-модуль с функцией `buildScene(THREE, spec)`, которая возвращает `{ scene, camera }`. Описание задаёт дерево узлов с позицией, поворотом в градусах и порядком Эйлера, масштабом (в том числе отрицательным) и `lookAt`, примитивы `box`, `sphere`, `cylinder`, `torus`, `plane`, выдавленные контуры с отверстиями, `InstancedMesh`, три вида света и перспективную или ортографическую камеру. Цвета задаются в sRGB. Полный текст: [task/task.md](task/task.md) ## Как проверяли - 38 ручных сцен с ловушками. Среди них градусы вместо радиан, порядки поворота `YXZ` и `ZYX`, глубокая иерархия с масштабом, отрицательный масштаб, `lookAt`, который у обычного объекта направляет к цели ось +Z, а у камеры ось −Z, `lookAt` внутри повёрнутого родителя и у родителя с потомком, цвет `#ff8800`, который three.js хранит в линейном пространстве, короткие записи цвета, контур с отверстием, пустой список экземпляров, цель направленного света, ортографическая камера и камера с осью `up`. - 120 случайных сцен из генератора с фиксированным seed: деревья до четырёх уровней из всех типов узлов, случайные повороты, порядки, масштабы, `lookAt`, прозрачность, невидимые объекты, свет и камеры. - 6 описаний, которые обязаны закончиться исключением: неизвестный тип, неверный цвет, цвет из четырёх цифр, контур из двух точек, неизвестный порядок поворота, неизвестная геометрия экземпляров. - 3 замера скорости: 3000 объектов с `lookAt`, цепочка из 1500 вложенных групп с `lookAt` и 50 000 экземпляров. На каждый даётся 2 секунды, эталон укладывается в 0,11 секунды. - Каждая сцена сравнивается с эталоном по всем именованным объектам: тип, родитель, видимость, мировая матрица, число вершин и габариты в мире, цвет, прозрачность и сторона материала, матрицы экземпляров, параметры света. У камеры сравниваются матрица проекции и положение. Затем из камеры пускаются 63 луча, и для каждого первый задетый объект должен совпасть с эталоном. - Сам стенд проверен эталоном: 164 сцены из 164 и все три замера. ## Условия - Участвуют модели, которые дали рабочий код в предыдущих тестах. Каждая получила задание слово в слово, одним сообщением, без системного промпта и без инструментов, и не могла запустить свой код. - Параметры рассуждения такие же, как раньше: у Qwen включён `enable_thinking`, у GPT `reasoning_effort: high`, Opus через API получал `thinking: adaptive` и `effort: max` через нативный `/messages` партнёрского шлюза, Kimi и DeepSeek работали в режиме по умолчанию. - Opus 5.5 дополнительно решал задачу агентом Claude Code с чистым контекстом: одно чтение задания и одна запись решения, без запуска кода. - Grok 4.7 не участвует: в двух прошлых тестах партнёрский шлюз обрывал все его попытки. - В зачёт идёт код как есть. Вариант с правкой одной строки считается отдельно, только для понимания. ## Нюансы - Задание заканчивалось фразой «Ответь ТОЛЬКО кодом модуля». Для моделей с адаптивным мышлением она оказалась невыгодной, это видно по Opus через API. Начиная со следующего теста задания заканчиваются фразой «Сначала продумай решение, затем ответь модулем». - Проверка шлюза: на задаче-головоломке Opus с `effort: low` думал 700 токенов, с `max` 19 тысяч. Значит, `effort` доходит до модели, и дело не в коннекторе. - Диагностические прогоны Opus с другой формулировкой в рейтинг не входят, в рейтинге прогон по общему заданию. - Все замеры скорости уложились с большим запасом, поэтому места среди решений без ошибок условны: разница во времени замеров на уровне погрешности. - Галерея рендерится одним и тем же кодом WebGL в Chrome без окна (SwiftShader). Отличия на картинках бывают только от разной сцены, которую построила модель. - Время и токены Opus-агента оценочные, по объёму кэша контекста. Протокол агента проверен: одно чтение задания и одна запись решения. - Opus-агент с `effort: max` добавлен 29.10.2026, после основного прогона, по тому же протоколу: одно чтение задания и одна запись решения, без запуска кода. Его запустили, чтобы сравнить с Opus через API на том же `effort: max`: через партнёрский шлюз модель рассуждает заметно меньше. ## Участники | Модель | Разработчик | ID | Доступ | Лимит ответа | |---|---|---|---|---| | Claude Opus 5.5 (агент) | Anthropic | `claude-opus-5-5` | субагент Claude Code, чистый контекст, без запуска кода | — | | Claude Opus 5.5 (агент, effort max) | Anthropic | `claude-opus-5-5` | субагент Claude Code, `effort: max`, чистый контекст, без запуска кода | — | | Kimi K3.1 Pro | Moonshot AI | `kimi-k3.1-pro` | API api.moonshot.ai (через VPN роутера) | 128K | | Qwen3.8-Max | Alibaba | `qwen3.8-max` | API token-plan.maas.qwencloudapi.com | 131.1K | | GPT-6.1 Sol | OpenAI | `gpt-6.1-sol` | партнёрский шлюз, `reasoning_effort: high` | 128K | | DeepSeek Flash (V4.1) | DeepSeek | `deepseek-flash` | API api.deepseek.com | 384K | | Claude Opus 5.5 (effort max) | Anthropic | `claude-opus-5-5` | партнёрский шлюз, нативный `/messages`, `thinking: adaptive`, `effort: max` | 128K | ## Файлы | Путь | Что это | |---|---| | `README.md` | отчёт в формате Markdown | | `report.html` | страница отчёта с графиками и галереей | | `bench.json` | метаданные: участники, условия, нюансы и выводы, из них собирается отчёт | | `task/task.md` | задание, которое получили модели | | `harness/runner.mjs` | скрытые тесты на Node: сцены, генератор, сравнение с эталоном, лучи | | `harness/reference.mjs` | эталонная сборка сцены | | `harness/test_three.py` | обёртка стенда и рендер галереи в Chrome | | `gallery/` | контрольная сцена в исполнении каждой модели и карты отличий | | `answers/.json` | метаданные ответа: время и токены | | `solutions//solution.mjs` | код, который написала модель | | `grades/.txt` | результаты тестов и список падений |