Окклюзия реальных объектов с использованием three.js

Я использую three.js внутри экспериментального веб-браузера с дополненной реальностью. (Браузер называется Argon. По сути, Argon использует Vuforia AR SDK от Qualcomm для отслеживания изображений и объектов в камере телефона. Argon отправляет информацию об отслеживании в Javascript, где он использует прозрачные веб-страницы с Three.js для создания 3D-графики поверх видео по телефону.) Мой вопрос, однако, о three.js.

Данные, которые Argon отправляет на веб-страницу, позволяют мне выровнять 3D-камеру с физической камерой телефона и рисовать 3D-графику так, чтобы она соответствовала реальному миру, как и ожидалось. Я также хотел бы, чтобы некоторые вещи в физическом мире перекрывали 3D-графику (у меня есть 3D-модели физических объектов, потому что я настроил сцену или потому что они представляют собой подготовленные объекты, такие как коробки, которые отслеживаются Vuforia).

Мне интересно, есть ли у людей предложения о том, как лучше всего выполнить эту окклюзию с помощью three.js. Благодарю.

1 ответ

РЕДАКТИРОВАТЬ: кажется, что следующая версия three.js (R71) будет иметь более простой способ сделать это, поэтому, если вы можете использовать ветку dev (или просто подождать), вы можете сделать это намного проще. Смотрите этот пост: Three.js прозрачный объект окклюзии


МОЙ ОРИГИНАЛЬНЫЙ ОТВЕТ (без использования новых функций в R71):

Я думаю, что лучший способ сделать это (чтобы избежать дополнительной работы, например, путем создания новых проходов рендеринга), изменить модуль рендеринга WebGL (src/renderers/WebGLRenderer.js) и добавить поддержку для нового типа объектов, возможно, назвать их " occlusionObjects".

Если вы заглянете в средство визуализации, вы увидите два текущих списка объектов: opaqueObjects и transparentObjects. Средство рендеринга сортирует объекты рендеринга в эти два списка, так что оно может сначала отобразить непрозрачные объекты, а затем прозрачные объекты после них. Что вам нужно сделать, это сохранить все ваши новые объекты в списке occlusionObjects, а не эти два. Вы увидите, что непрозрачные и прозрачные объекты отсортированы по свойствам материала. Я думаю, что здесь вы можете добавить свойство к объекту, которым хотите быть окклюдером (возможно, "myObject.occluder = true"), и просто вытянуть эти объекты.

Когда у вас есть три списка, посмотрите, что функция render() делает с этими списками объектов. Вы увидите пару мест с обработкой вызовов, подобной этой:

renderObjects( opaqueObjects, camera, lights, fog, true, material );

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

context.colorMask( false, false, false, false);
renderObjects( occluderObjects, camera, lights, fog, true, material );
context.colorMask(true, true, true, true);

Вам нужно будет сделать это в нескольких местах, но это должно сработать.

Теперь вы можете просто пометить любые объекты в вашей сцене как "occluder = true", и они будут визуализироваться только в буфере глубины, позволяя видео просвечивать и перекрывая любые непрозрачные или прозрачные объекты, визуализированные позади них.

Другие вопросы по тегам