Three.js: Как загрузить анимированную модель.json от веб-работника?
преамбула
Я бьюсь головой об этом уже почти две недели, и я не ближе к решению. Я задал подвопросы, которые, как я думал, приведет меня в правильном направлении:
- Three.js - Как десериализовать geometry.toJSON ()? (где geometry.fromJSON?)
- Three.js: Как создать новую "изменяющуюся" геометрию, если у меня есть все необходимые буферы?
Из них второй по-прежнему актуален, но, похоже, никто не кусается, несмотря на щедрость. Поэтому сейчас я задаю полный вопрос напрямую и постараюсь не делать никаких предположений. (Намек на) решение будет принята с благодарностью.
Вопрос
У меня есть несколько больших анимированных 3D-моделей в .json
файлы, такие как могут быть загружены с THREE.JSONLoader
, У них есть формат примерно так:
{
"metadata": { "formatVersion": 3, ... },
"vertices": [...],
"normals": [...],
"faces": [...],
"morphTargets": [
{ "name": "...", "vertices": [...] },
...
],
"morphNormals": [
{ "name": "...", "normals": [...] },
...
]
}
Я смог заставить анимацию работать, когда делал все из основного потока. Но загрузка и обработка этих больших файлов надолго останавливает графический интерфейс. Поэтому мне нужно передать все это веб-работнику, а затем успешно создать анимацию в главном потоке.
Более того, мне нужно отправить результат обратно в основной поток через переносимые объекты, чтобы не было клонирования необработанных данных, блокирующих основной поток. Насколько я понимаю, WebGL использует Float32Array
s, буферы которых являются переносимыми объектами. Так что я уверен, что это можно сделать.
Требуемый процесс, как я понимаю, заключается в следующем:
- (Пользовательский интерфейс) ➝ отправить имя файла ➝ (работник)
- (рабочий) ➝ скачать ➝ процесс ➝ отправить буферы (включая morphTargets) ➝ (пользовательский интерфейс)
- (Пользовательский интерфейс) ➝ реконструировать анимацию без копирования каких-либо буферов
Это 2 и 3 у меня проблемы с. Какие именно буферы нужно создать в работнике, и как мне заставить их вести себя как надо (Buffer
) Geometry
на стороне пользовательского интерфейса?
Что я пробовал
Мне известен уже существующий смежный вопрос:
Но вопрос кажется устаревшим. Вполне вероятно, что я должен использовать THREE.BufferGeometry
, который не упоминается (возможно, потому что это еще не существовало). Принятый ответ немного запутан и требует, чтобы я все еще выполнял некоторую необработанную работу в главном потоке, например, загружал модель и рендерил ее для генерации буферов.
Как выясняется, BufferGeometry
пока не поддерживает анимацию. Один satori99 недавно отправил запрос на добавление, чтобы добавить эту поддержку. Я играл с этим кодом, но пока не смог применить его в моей ситуации. Кажется, поддержка все еще не завершена.
Вот моя последняя попытка заставить это работать:
1 ответ
Я думаю, что у меня могли быть те же проблемы, что и у вас, когда я решил их взломать.
Я пришел к выводу, что использование THREE.Geometry было проблемой, и было лучше сосредоточиться на создании файлов JSON, напрямую использующих JSON Object Format 4.3.
Этот формат хранит все данные в TypedArrays, и при загрузке / разборе на них не требуется никаких вычислений. Так что загружать его намного быстрее, и в большинстве случаев мне не приходилось беспокоиться об обычных работниках, поскольку больше не было никаких пауз во время загрузки.
К сожалению, в этом формате отсутствуют многие функции, которые старый формат JSON уже поддерживает. Но это будущий предпочтительный формат для ресурсов Three.js JSON, поэтому он изменится.
Что касается морфируемой анимации, то существующие шейдеры будут работать нормально, пока они проходят правильные буферы для морфируемых данных, но текущий WebGLRenderer не делает этого для BufferGeometry, только для обычной Geometry.
Это главное препятствие для морфов BufferGeometry.
Я следовал той же внутренней логике, которую использует WebGLRenderer для создания буферов для обычной геометрии, когда создавал этот PR, но возможно, что код визуализации с тех пор немного изменился. Особенно в ветке разработчиков.
Я еще раз посмотрю на это на этой неделе. Потому что мне нужно, чтобы это работало и на мой проект:)