Многопроходный накопительный рендеринг в three.js - PullRequest
0 голосов
/ 09 сентября 2018

Я написал код для рендеринга сцены, содержащей источники света, которые работают как проекторы. Но их много (больше, чем можно представить при фиксированном количестве источников света в одном шейдере). Итак, прямо сейчас я рендерил это, создавая собственный шейдер и визуализируя сцену один раз для каждого источника света. Каждый проход фрагментного шейдера определяет вклад для этого источника света, и блендер добавляет этот вклад в буфер. Мне было очень неудобно настраивать в three.js. Я не мог найти способ сделать несколько проходов, как этот, где были разные материалы и разные геометрии, необходимые для разных проходов. Я должен был сделать это, имея несколько сцен. Проблема в том, что у меня не может быть object3d, который находится в нескольких сценах (пожалуйста, исправьте меня, если я ошибаюсь). Поэтому мне нужно создать дубликаты объектов - по одному для каждой сцены, в которой он находится. Все это начинает быстро выглядеть по-хакерски. Все это настолько особенное, что кажется несовместимым с различными функциями фреймворка three.js, такими как VR Rendering. Каждый источник света требует затенения, но у меня нет памяти для буфера теней для каждого источника света, поэтому он чередуется между рендерингом буфера теней для источника света, затем фазы накопления для этого источника света, затем буфера теней для следующего источника света, затем аккумулятор следующий свет и т. д.

Я бы предпочел сделать это более "тройным" способом. Кажется, я пишу "взломать взлом", чтобы заставить это работать, каждый раз отказываясь от еще одной фреймворковой функции Three.js, которая не работает должным образом в сочетании с моей многопроходной техникой. Но не похоже, что то, что я делаю, настолько необычно.

Моим главным сюрпризом является то, что я не могу найти способ настроить многопроходную сцену, которая выполняет рендеринг и накопление назад и вперед. И второе удивление в том, что создаваемые мной Object3D не любят, когда их добавляют в несколько сцен одновременно, поэтому мне приходится создавать дубликаты каждого объекта для каждой сцены, в которой он хочет находиться, чтобы их состояние не изменялось. мешая друг другу.

Так есть ли способ сделать этот вид многопроходной накопительной сцены лучше? Опять же, я бы описал это как сцену с> максимальным количеством источников света, которые допускаются за один проход шейдера, так что их вклады должны отображаться альтернативно (теневые буферы), а затем аддитивно накапливаться за несколько проходов. Огни работают как обычные кинопроекторы, которые проецируют изображение (в отличие от однородного однотонного источника света).

Как я могу сделать многопроходный рендеринг, как это, и при этом использовать преимущества таких базовых элементов, как стерео рендеринг для виртуальной реальности и автоматическое создание теневого буфера?

Вот упрощенный фрагмент, который демонстрирует вовлеченные сцены:

  renderer.render(this.environment.scene, camera, null);
  for (let i = 0, ii = this.projectors.length; i < ii; ++i) {
    let projector = this.projectors[i];
    renderer.setClearColor(0x000000, 1);
    renderer.clearTarget(this.shadowRenderTarget, true, true, false);
    renderer.render(projector.object3D.depthScene, projector.object3D.depthCamera, this.shadowRenderTarget);
    renderer.render(projector.object3D.scene, camera);
  }

  renderer.render(this.foreground.scene, camera, null);

Есть сцена, которая отображает освещение из окружающей среды (выполняется при нормальном освещении), затем есть сценарий для каждого проектора, который вычисляет карту теней для проектора, а затем добавляет вклад света от каждого проектора, после чего возникает " передний план »сцена с оверлеями и пользовательским интерфейсом.

Есть ли еще способ "three.js"?

1 Ответ

0 голосов
/ 10 сентября 2018

К сожалению, я думаю, что ответ no.

Я бы предпочел сделать это более "тройным" способом. Я, кажется, пишу взломать взломать, чтобы заставить это работать,

и добро пожаловать в мир развития three.js:)

граф сцены

Вы не можете иметь узел, принадлежащий нескольким родителям. Я считаю, что три также не позволяют вам сделать это:

const myPos = new THREE.Vector3()

myMesh_layer0.position = myPos
myMesh_layer1.position = myPos

Не работает с эйлерами, кватернионами или матрицами.

Управление обновлениями матрицы в нескольких сценах также было бы непросто.

путь Three.js

Невозможно заниматься "взломом взлома", если только вы не начнете взламывать ядро.

Обратите внимание, что это 2018 год, но официальный способ включения three.js в ваше веб-приложение - через <src> теги.

Это отличный пример того, где, вероятно, было бы лучше не делать что-то the three.js way, а modern javascript way, то есть использовать импорт, установки npm и т. Д.

Three.js также не имеет надежного ядра, которое позволяет вам быть гибким с кодом вокруг него. Это довольно запутанно и смешано с ограниченным количеством открытых хуков, которые позволят вам писать эффекты, которые вы хотите.

Три часто сопоставляют с примерами. Если вы выберете случайный вариант, он будет написан в виде Three.js, но далеко от того, каковы лучшие практики JavaScript / кодирования, по крайней мере сегодня.

Вы часто будете находить большие монолитные файлы, которые будут полезны, если их разбить.

Я считаю, что все еще невозможно импортировать примеры в виде модулей.

Посмотрите примеры расширений материалов и подумайте, хотите ли вы применить этот шаблон в вашем проекте.

Возможно, вы можете столкнуться с большим количеством болевых точек, но этого достаточно, чтобы проиллюстрировать, что three.js way не всегда может быть желательным.

1043 * средства * Мало и далеко друг от друга. Я потратил больше года, пытаясь подтолкнуть крючки onBeforeRender и onAfterRender. Это кажется полезным и допускается для некоторых рефакторингов, но сначала нужно было обнулить другую функцию. Другая функция использовалась в течение этого года и затрагивала только один пример, пока не стало очевидным, что onBeforeRender рассмотрит оба примера и позволит гораздо больше. Это, к сожалению, также похоже на путь three.js. Поскольку база настолько велика и включает в себя очень много примеров, более вероятно, что кто-то попытается оптимизировать отдельный пример, а затем попытается найти общий шаблон для рефакторинга целой их совокупности. Вы могли бы пойти и подать проблему на github, но было бы очень трудно спорить о чем-то более общем, чем это. Скорее всего, вам придется написать код в качестве предложения. Это может облагаться налогом довольно быстро, потому что его можно отклонить, проигнорировать, или вас могут попросить предоставить примеры или реорганизовать существующие. Вы упомянули, что ваши хаки не работают с различными функциями, такими как VR. Я думаю, что это проблема с тремя, VR был центром развития, по крайней мере, последние пару лет, но без решения основных проблем. Хорошая новость заключается в том, что три являются более модульными, чем когда-либо прежде, поэтому вы можете раскошелиться на проект и настроить нужные вам детали. Проблемы, связанные с тремя, могут перейти на более высокий уровень, если, например, вы обнаружите некоторую связь в рендере, которая затрудняет синхронизацию вашего форка, это будет легче объяснить, чем всю цель вашего конкретного проекта.

...