В нашей модели Обнинской АЭС можно нажать кнопку аварийной защиты и увидеть, как гаснет свет в домах посёлка. На моём телефоне это работало. А когда я отправил статью на Хабр, модератор на своём ноутбуке даже кнопкой воспользоваться не смог. Я открыл ту же ссылку на MacBook Air и наконец увидел, о чём он говорил.
Вообще-то началось всё в спортзале. Мне надо было понять, как правильно делать упражнение. В интернете попался ролик, где скелет с мышцами делает это движение и видно, что происходит внутри тела. Я подумал: как же классно.
Такие штуки мне нравились всегда. Одна из любимых передач — «Как это устроено» на Discovery: заводы, пароходы, как работает техника. Я технарь. В детстве разобрал отцовский магнитофон и пообещал собрать из него вертолёт, за что получил по шапке. А теперь у меня появился инструмент, с которым такое можно делать самому.
К тому времени я прошёл обучение у Ивана Замесина и уже вовсю возился с нейросетями. Для первого англоязычного канала мы собрали в Blender два коротких ролика — про подшипник и сцепление. А потом мне попалась интерактивная модель объектива Райана Сейла. Вот чего мне всё это время хотелось: самому покрутить механизм, разобрать и посмотреть, что внутри. Так появился проект «Изнутри». Интерактивные сцены Райана
Обнинскую АЭС я выбрал по личной причине. Я родом из Малоярославца, совсем рядом с Обнинском. Хотелось зайти в реакторный зал и своими глазами проследить, как из тепла получается электричество. Открыть Обнинскую АЭС в браузере
Общий вид Обнинской АЭС в нашей сцене

Что увидит зритель
В сцене семь шагов. Входишь с улицы в зал, где виден весь путь энергии. Реактор нагревает воду, в парогенераторе она отдаёт тепло воде второго контура. Пар крутит турбину, а та — генератор. На пульте есть кнопка «АЗ» — аварийная защита. Нажимаешь её и смотришь в зал. Стержни опускаются, мощность падает, за окнами зала гаснут дома. Это наш способ показать, что изменилось от одного нажатия.
Аварийная защита — пульт и окна посёлка

Дальше можно заглянуть в реактор, самому подвигать стержни и повторить в модели первый пуск 1954 года. Загружаешь каналы и смотришь, как меняются показания счётчика нейтронов. Затем разбираешь реактор по слоям, включаешь тепловизор у двух контуров и в конце считаешь КПД. Станция выделяла 30 МВт тепла и отдавала в сеть 5 МВт электричества. Куда делись остальные 25?
Первый пуск — что показывает счётчик при загрузке каналов

Запись первого пуска в модели, MP4
Тепловизор — как один контур нагревает другой

Почему сцена зависала на ноутбуке
До замечания модератора я проверял, как быстро появляется модель и помещается ли она на экране. В локальном тесте она появлялась примерно за полторы секунды. Когда мы вернулись к версии по ссылке из статьи, нашлись две проблемы с разными признаками.
Если модель всё-таки появлялась, высокое разрешение и дополнительные эффекты могли перегрузить графику. Для этого случая мы ограничили число пикселей, которые браузер рисует в каждом кадре, и отложили тяжёлые эффекты до нажатия кнопки. Но иногда вместо станции появлялась надпись «3D не загрузилось». Тут уменьшать модель было бессмысленно: браузер не мог получить сам движок three.js с внешнего сервера jsDelivr. Блокируем этот адрес на Mac — получаем ту же надпись.
Русская версия АЭС теперь берёт движок с нашего сайта. 11 ноября на MacBook Air оставили jsDelivr заблокированным и открыли опубликованную сцену. Первый кадр с моделью появился за 0,60 секунды. В Chrome на Windows два открытия без кеша дали 1,93 и 2,23 секунды. Прошли все семь шагов. В зале и в финале нажали защиту, дождались, пока погаснут окна, и запустили реактор снова.
Я отдельно открыл сцены на слабом ПК. С выключенными эффектами они загрузились. Когда включил эффекты, большой разницы в картинке, честно говоря, не увидел. Пока что базовый режим вполне годится, чтобы разобраться, как работает станция. А когда будем заниматься светом и материалами, у меня теперь есть простой вопрос: что именно зритель увидит после нажатия этой кнопки?
Откуда берутся показания на пульте
Изменения мощности рассчитываются на каждом шаге времени. В основе — простая модель точечной кинетики с одной группой запаздывающих нейтронов. Мы перешли на неявную численную схему после того, как расчёт начинал расходиться при глубокой подкритичности.
Фрагмент расчёта из gen/aes/v3/aes_src.html
var P_TH=30, P_EL=5, NCH=128, NCRIT=60; var BETA=0.0065, LAM=1e-3, LD=0.08, RHO_MAX=0.006, H_CRIT=0.5, RHO_SCRAM=-0.04; function pstep(dt){ if(!(dt>0)) return; // см. ниже, почему на пульте появлялось NaN // … var rho=rhoNow(), src=R.mode==='start'?1:1e-6, sub=Math.max(1,Math.ceil(dt/0.002)), h=dt/sub; for(var i=0;i<sub;i++){ R.n=Math.max(0,(R.n+h*(LD*R.C+src))/(1-h*(rho-BETA)/LAM)); R.C=(R.C+h*BETA/LAM*R.n)/(1+h*LD); } /* неявная схема: устойчива и при глубокой подкритичности */ // … }
Граница у этой модели вполне конкретная. Из истории станции мы взяли номинальные мощности, 128 каналов при полной загрузке и ориентир для первого пуска — около 60 каналов. Порог задан в коде. То, что в сцене реакция поддерживает себя на 61-м канале, говорит о выбранных настройках. Историческую загрузку с точностью до одного канала мы этим не восстановили.
Цифры и источники мы складывали в отдельный файл. На июньских датах я понял, зачем фиксировать ещё и событие, к которому относится число. 26 июня пар подали на турбину и генератор синхронизировали с сетью Мосэнерго. В сообщении ТАСС 27 июня названо днём пуска станции в эксплуатацию. В короткой подписи «дала ток» это различие легко потерять. История пуска Обнинской АЭС, библиотека Росатома
Там, где достоверных данных у нас не было, оставили условности. Например, число стержней на модели приблизительное. Голубое свечение в разрезе — художественный приём. В настоящем АМ-1 вода текла по закрытым каналам внутри графита.
Как я работал с агентами
Код руками я не пишу, но и не с нуля пришёл: я айтишник по бэкграунду, с компьютером на «ты», в своё время учил C++. Я могу поставить задачу, подключить агента к Blender или DaVinci Resolve и разобраться, что он сделал. Всё остальное делает ИИ. Моя часть — идеи, приёмка и ругань: смотрю, правлю, ругаюсь.
Начинал я с Codex и ругался с ним постоянно. Потом перешёл на Claude. В октябре у меня было несколько чатов: «отдел сцен», «отдел роликов», «штаб». В 23:45 на пятый день у аккаунта кончился недельный лимит. Встали все чаты сразу. Лимит потом сбросился, а работу никто не продолжил.
Тогда я вынес задачи из переписки в файлы. Планировщик Windows раз в полчаса запускал исполнителя, тот брал одну задачу. Для незаконченной работы оставлял короткую запись: до какого места дошёл и что проверить дальше. Следующий запуск начинался с этой записи. Тяжёлый рендер уходил в отдельную очередь Blender на моей RTX 3080 Ti.
Причина у отдельной очереди прозаическая. Однажды исполнитель запустил рендер в фоне, написал «жду уведомления» и завершил работу. Вместе с ним закончился и процесс, от которого он ждал уведомления.
Мы записали, что именно проверять перед сдачей: вес первой загрузки, время кадров, ошибки в консоли и попадание модели в кадр на пяти размерах экрана. Исполнитель приносил ссылку, я открывал её и крутил сцену. Скоро выяснилось, что некоторые из наших тестов прекрасно проходят даже на сломанной модели.
Что пропустили наши проверки
Реактор в чёрной пустоте
После переноса на новый шаблон тест не нашёл ошибок в консоли и подтвердил, что реактор помещается в кадр. Я открыл сцену. Реактор действительно помещался. Вокруг — чёрная пустота. Пропали здание, город, лес и половина кнопок.
У нас был тест на положение реактора, а на присутствие города — ни одного. Перед следующей попыткой выписали всё, что человек мог увидеть, услышать и нажать в старой сцене. Получилось 36 строк. По ним вернули окружение и все девять кнопок.
Дальний план запекли в Blender: сумеречное небо (Sky Multiple Scattering), 34 тыс. деревьев (Geometry Nodes), 900 условных кварталов с окнами. Всё это ужато в две картинки: pano_base.jpg на 105 КБ и pano_lights.jpg на 66 КБ. Огни второй картинки загораются, когда станция даёт ток. Ближний лес — 3D: 520 деревьев на телефоне, 1000 на десктопе.
Почему вместо мощности появилось NaN
На шагах 2, 5 и 7 пропадала модель, а на пульте появлялось «NaN МВт». Причина — pstep(0). В первый кадр после смены шага dt был равен 0, и производная мощности делилась на ноль. Некорректное значение попадало в следующие вычисления, а затем в матрицы отрисовки, поэтому пропадала и модель. Фикс — одна строка, if(!(dt>0)) return;. Нашёл её агент, но только после того, как скриншоты в QA показали пустые кадры.
Почему модель помещалась в кадр только по отчёту
Эту ошибку первым заметил человек, который открыл нашу микроволновку. Она сделана на том же шаблоне. На шаге «разбери печь» вся начинка уезжала в правые 45 % экрана. Алгоритм кадрирования выбирал «свободную зону» и давал больше очков узкой полосе справа от крупной формулы, чем широкой полосе под ней. Автоматическая проверка сверяла модель с той же зоной, а саму зону ни с чем не сравнивала. Поэтому 0 нарушений при явно кривом кадре.
Изменили проверку и добавили два коротких экрана — 390 × 744 и 360 × 680. На той же АЭС новый тест нашёл замечания в 19 кадрах из 58. Местами модель сдвигалась на 75–124 пикселя. Теперь у меня были конкретные кадры, на которых можно посмотреть, что уехало за панель.
Оставлю замеры октября под спойлером. В строке «4G» измерялись отдельно первая отрисовка страницы (FCP) и появление самой модели. Частота кадров с отключённой вертикальной синхронизацией относится только к тестовому прогону.
Исторические локальные замеры 24–29 октября
Что измеряли | Старая сцена (24.10) | v3 (016, 29.10 02:40) | v3b, паритет (016b, 29.10 13:15) |
|---|---|---|---|
three.js | r128 | r186 | r186 |
Страница | один HTML, 3,4 МБ, модели внутри | 1,38 МБ, 27 запросов | 1,20 МБ первая загрузка (1,61 МБ с догрузкой) |
Модель | встроена | GLB 0,52 МБ, Meshopt, 99,6 тыс. треуг. | то же |
4G | — | FCP 0,56 с, модель 1,48 с | FCP 0,52 с, модель 1,52 с |
Ошибки консоли | — | 0 на 5 размерах | 0 на 5 размерах |
Кадров > 50 мс | — | 0 (макс. кадр 4–5 мс) | 0 (FPS без vsync 670–1460) |
fit STRICT | — | 0 нарушений, 32 кадра | 1 перекрытие + 4 «мелко» из 37 кадров |
Агентное время | — | ≈ 1,5 ч (01:06 → 02:40, с одним падением) | ≈ 2,5 ч (10:36 → 13:15, с одним падением) |
С коробкой передач так и не вышло
Третий ролик, про коробку передач, мы начинали ещё с Codex, на купленной модели за $100. Задумка: либо камера из салона ныряет под тоннель и показывает, как внутри крутится механизм, либо машина снаружи разлетается на части, и камера наезжает на коробку. Для нейросети это оказалось очень сложно. Кузов машины мы собирали, наверное, неделю. Я потратил кучу денег на модели для генерации видео и моушн-дизайна, искал референсы. В итоге сделали более-менее, но кузов угловатый и разъезжается чёрт пойми как. Красивая там только купленная модель. И самое обидное: машину мы так и не доделали. Столько времени, сил и денег — а её до сих пор нет.
«Это плохо, переделывай» у меня тогда звучало по десять раз на дню. В какой-то момент Codex сам сдался: написал, что, наверное, эту работу стоит передать другому агенту. Видимо, тоже устал.
На том этапе с Claude такое случалось реже: он чётче понимал, что я прошу, часто с первого раза. Затем мы перестроили работу, и модели выглядят гораздо лучше и в 3D, и в роликах. До фотореализма, который я хочу, ещё не дошли, но я примерно понимаю, как к нему прийти.
Зато первый раз я по-настоящему офигел на двигателе МиГ-19. Мы добавили звук, пламя форсажа и помпаж. Я даже слова такого не знал, пока мы его не собрали. А смешнее всего было с микроволновкой. Дожил до сорока лет и понял, зачем крутится тарелка, только из своей же модели.
С Blender я раньше вообще не дружил — первый раз услышал о нём от племянницы, она учится на дизайнера. А недавно мы купили к нему плагины для естественного леса, дыма и огня, и мне это всё интереснее.
Во что это обошлось и кто пришёл смотреть
Когда я готовил первый черновик 6 ноября, подписка Claude обходилась мне в $100 в месяц, хостинг в Yandex Cloud — примерно в 3 800 ₽ в месяц, домен — около 500 ₽ в год. Отдельно за голос в ElevenLabs с докупками вышло около $50. Из разовых покупок — $100 за модель коробки передач и $50 за сцепление. Видеокарта у меня уже была.
Самая горькая цифра в том черновике — ноль покупателей. Ради этого я и пишу статьи и снимаю ролики: хочу понять, интересно ли это хоть кому-то ещё.
К 6 ноября четыре шортса набрали за месяц 5,6 тыс. просмотров. Ролики набирали примерно по полторы тысячи просмотров, а потом рост резко замедлялся. Почему — по этим данным не скажешь. По доле тех, кто продолжил смотреть в ленте Shorts, впереди был МиГ-19 — 70,5 %. Я как ребёнок радовался первым просмотрам, обновлял шортс каждые пять минут, а первые лайки — отдельный восторг.
За тот же месяц Метрика насчитала на сайте 13 посетителей и 40 визитов. Из них 29 — прямые заходы. Думаю, значительная часть наша: мы сами постоянно открывали сцены. Меня удивило, что туда вообще кто-то зашёл. Не хватает обратной связи. В планах — что-то вроде YouTube, только для 3D-моделей: с комментариями и предложениями, что добавить или исправить.
Кому бы я это показал
Школы и музеи. Микроволновку на урок не принесёшь и не разберёшь, а в интерактиве — пожалуйста. Я живу в Москве, хожу по выставкам и видел много интерактивных стендов, где можно покрутить модельки. Мне хочется добавить к привычному вращению модели больше действий: раздвинуть детали, запустить реактор, нажать аварийную защиту. Не «Железный человек», который руками собирает костюм в воздухе, но на экране — уже да.
Заводы — показывать свою продукцию на экране или стенде. А «Буран» — отдельная история. Мой основной бизнес — ремонт квартир и офисов, и одним из заказов был актовый зал на заводе, который делал «Буран». Мы там поставили огромный экран, контакты остались. Хочу собрать модель «Бурана» и предложить им: ролик на этот экран, интерактив для музея, стенд с сенсорным экраном. Если интересно мне и интересно за рубежом, думаю, и в России будет запрос.
Если откроете сцену АЭС, попробуйте в зале нажать аварийную защиту. Мне интересно, куда вы посмотрели после нажатия и по чему поняли, что произошло. А если сцена зависнет, напишите, пожалуйста, на каком устройстве и на каком шаге. По такому описанию я хотя бы знаю, с чего начать.

