Three.js: Ориентация куба

Созданный на 25 апр. 2019  ·  31Комментарии  ·  Источник: mrdoob/three.js

В моем приложении я хотел бы повернуть CubeTexture, который определяет фон сцены и отражения карты окружения, на 180 ° по вертикальной оси y.
Мое вращение определяется спецификациями VRML и X3D о фоновых полях.

Я попытался изменить несколько параметров, таких как поля mapping , flipY и rotation Texture. Однако я не нашел хорошего способа сделать это.

  • Есть какой-нибудь очевидный способ сделать так, чтобы я пропустил?
  • Есть ли шанс увидеть это в three.js ?
  • Если бы я хотел реализовать это, какие параметры вы бы хотели видеть (например, Texture.flipX и CubeTexture.flipZ )? Вас заинтересует эта функция?
Enhancement

Самый полезный комментарий

Вы имеете в виду возможность вращать scene.background ? Если так ... да, определенно интересно.

Хотя нам, вероятно, понадобится новый API ...

scene.background = new THREE.Background( cubeTexture );`
scene.background.rotation.y = Math.PI / 2;

Все 31 Комментарий

Вы имеете в виду возможность вращать scene.background ? Если так ... да, определенно интересно.

Хотя нам, вероятно, понадобится новый API ...

scene.background = new THREE.Background( cubeTexture );`
scene.background.rotation.y = Math.PI / 2;

Я борюсь именно с этим прямо сейчас. Попытка получить запеченные тени земли, чтобы они соответствовали направлению солнца от кубической карты.
Кажется, что где-то по пути моя кубическая карта переворачивается на 180 градусов. Было бы здорово, если бы я мог просто исправить это здесь, вместо того, чтобы повторно визуализировать свою кубическую карту несколько раз и пытаться выяснить, где это происходит.

@fabienrohrer Попробуй

scene.rotation.y = Math.PI;

Если это не работает, приведите живой пример, чтобы точно продемонстрировать, что вы делаете.

О, это работает? 😮 Однако камера должна быть дочерним элементом сцены?

Но ведь камера должна быть дочерью сцены?

Я не думаю, что это важно.

@mrdoob это именно то, что мне нужно :-)

@ ВестЛэнгли :

Вращение всей сцены слишком сложно и может вызвать множество побочных эффектов в моем приложении.

Я хотел бы иметь возможность вращать только фон, и, конечно, карты окружения должны работать точно так же.

Живую демонстрацию сделать невозможно, потому что API отсутствует. Можно взять любой пример с кубической картой фона (например, https://threejs.org/examples/#webgl_materials_cubemap) и иметь возможность вращать только фон вокруг оси y. Или, в более общем смысле, применить любое вращение к фону.

Возможность применить настраиваемую матрицу / кватернион вращения к любой кубической карте кажется мне наиболее универсальным решением.

three.js тщательно следит за тем, чтобы отражения материала соответствовали материалу envMap , который определен в системе координат мирового пространства. Разрешение пользователям вращать фон сцены приведет к тому, что фон будет несовместим с отражениями материала.

Почему бы вам не создать правильную кубическую карту мира и пространства в своем приложении?

Но ведь камера должна быть дочерью сцены?

Я не думаю, что это важно.

Я попытался сделать scene.rotation.y ++ в консоли в webgl_materials_standard, и пистолет вращается. Затем я попытался сделать scene.add( camera ) а затем, если я сделаю scene.rotation.y ++ он сделает то, что нам нужно, но затем управление камерой перестанет работать 😁

Если мы введем объект THREE.Background , мы могли бы добавить API для обработки этого, плюс в рендерере мы также можем представить идею:

var envMap = material.envMap;
if ( scene.background && scene.background.isBackground && envMap === null ) {
    envMap = scene.background.texture;
}

я сказал

Попробуйте scene.rotation.y = Math.PI; Если это не сработает, ...

Значит, это может не сработать. :-)

Это зависит от варианта использования. Я пробовал с OrbitControls и он работал нормально.

несвязанный: в примере webgl_materials_standard любом случае должны использоваться элементы управления орбитой, ИМО.

Вы имеете в виду возможность вращать scene.background? Если так ... да, определенно интересно.

Имеет смысл делать это на уровне текстуры, иначе, я полагаю, любое освещение IBL не будет соответствовать фону.

Мы разрешаем вращение текстур нормалей, есть ли причина, по которой мы не хотели бы делать то же самое для текстур куба? Это слишком сложно реализовать?

Почему бы вам не создать правильную кубическую карту мира и пространства в своем приложении?

На это уходит очень много времени. Я работал над созданием кубических карт последние пару дней, и внесение изменений с последующим повторным рендерингом кубической карты занимает у меня около 15-20 минут для каждого изменения.

Еще один потенциально интересный вариант использования этого состоит в том, что вы можете изменять направление освещения окружающей среды в реальном времени. В настоящее время я комбинирую карту среды PMREM с направленным светом для теней в реальном времени и использую карту в качестве скайбокса, что дает довольно приличный эффект дневного света.
Очевидно, что есть предел тому, что вы можете делать, не меняя цвет карты окружения, но вы можете имитировать как минимум пару часов дневного света, вращая карту синхронно с направленным светом при настройке .envMapIntensity .

Меня беспокоит также производительность. В настоящее время я реализовал хак, чтобы повернуть верхнюю и нижнюю текстуры и поменять местами другие текстуры. Вращение текстуры 1024x1024 в JS занимает около 10 мс.

В качестве альтернативы, можно было бы иметь только два варианта ориентации CubeTexture: тот, который у вас есть в настоящее время, и другой (с поворотом на 180 градусов), который был бы совместим с другим стандартом, широко используемым в 3D-форматах (X3D, VRML и т. Д. .). Возможно, мы могли бы легко адаптировать согласованность с материальными отражениями для работы с обоими форматами?

Звучит знакомо # 11103

Если бы я реализовал CubeMap.rotation = matrix3 , вы бы слились с r105?

Меня беспокоит также производительность. В настоящее время я реализовал хак, чтобы повернуть верхнюю и нижнюю текстуры и поменять местами другие текстуры. Вращение текстуры 1024x1024 в JS занимает около 10 мс.

И как часто вы делаете это в своем приложении?

@WestLangley Я просто дам вам подробный ответ здесь: https://github.com/mrdoob/three.js/pull/16507#discussion_r286337864

И как часто вы делаете это в своем приложении?

Немного. Один раз при загрузке для каждого клиента и один раз при каждой смене фона (очень редкий случай). DEFINE также подойдет.

Меня беспокоит также производительность ... Это занимает около 10 мс.

И как часто вы делаете это в своем приложении?

Немного. Один раз при загрузке для каждого клиента и один раз при каждой смене фона (очень редкий случай).

Извините, я не следую логике этого.

К сожалению, @WestLangley не хочет объединять мою модификацию CubeTexture.rotation из-за накладных расходов времени выполнения (дополнительное умножение mat3). В этом случае у меня заканчиваются идеи, чтобы решить эту проблему с помощью threejs.
Если участники threejs не могут решить эту проблему, закройте эту проблему.

Жду реализации этой функции.

@FishOrBear К сожалению, разработчики threejs решили не реализовывать это. Вы можете применить этот не объединенный патч в вилке, если хотите, чтобы это было в вашем проекте:

https://github.com/mrdoob/three.js/pull/16507

@mrdoob Может быть, мы сможем пересмотреть запросы на эту функцию в # 18157?

Я использую threejs для создания приложения, похожего на AutoCAD, поэтому мы используем xy, чтобы сидеть как плоскость.

Текущая CubeTexture немного конфликтует с нашей.

Кстати: с Babylon.js, по крайней мере, можно повернуть скайбокс вокруг оси y:

https://www.babylonjs-playground.com/#UU7RQ # 447

Движок поддерживает это, преобразовывая вектор отражения во фрагментном шейдере. Это как раз тот подход, который не был принят в # 16507. Код из фрагментного шейдера Babylon.js:

https://github.com/BabylonJS/Babylon.js/blob/1c4627141f83c08fe4a7e30e2621c916b4e6c9c9/src/Shaders/ShadersInclude/reflectionFunction.fx#L114 -L117

@mrdoob Я думаю, нам следует реализовать эту функцию. Еще одна просьба на форуме:

https://discourse.threejs.org/t/rotate-a-scenes-background-skybox-texture/12199

Я сомневаюсь, что однократное дополнительное умножение матрицы / вектора на фрагмент заметно повлияет на производительность.

У меня все еще есть та же проблема в моем приложении, и взломать ее уродливо и так дорого ... Я также рекомендую принять это улучшение.

Я также хотел бы, чтобы эта функция была добавлена.

Кажется, что блокировщик потенциально снижает производительность, но это должно быть легко проверить. Мы можем попробовать добавить его, и если произойдет резкое падение производительности, мы сможем удалить его снова.

То же самое здесь, можно было бы использовать эту функцию вместо повторной реализации моего фонового рендеринга :)

Я не уверен, что буду следить за производительностью. Ничего не мешает сгенерировать направление луча прямо в вершинном шейдере? Тогда это будет стоить столько же, сколько любое другое преобразование modelMatrix .

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

Один из способов, которым я это сделал, - сохранить вращение как переменную, применить его к сцене непосредственно перед рендерингом, а затем сбросить вращение сцены на quat идентичности сразу после рендеринга.

Это вызывает два ненужных обновления мировых матриц всех моих объектов сцены. Это также означает, что я не могу обновлять позицию в onBeforeRender. Но в противном случае он сохраняет сцену в нормальном состоянии.

Кстати (поскольку никто об этом не упомянул), кажется, можно сделать "классический" скайбокс, который вращается, используя массив из 6 материалов.

что-то вроде этого :

const urls = [
  '/assets/skybox/right.png',
  '/assets/skybox/left.png',
  '/assets/skybox/top.png',
  '/assets/skybox/bottom.png',
  '/assets/skybox/front.png',
  '/assets/skybox/back.png',
];

const materials = urls.map((url) => {
  const texture = new THREE.TextureLoader().load(url);

  return new THREE.MeshBasicMaterial({
    map: texture,
    side: THREE.BackSide,
    fog: false,
    depthWrite: false,
  });
});

const skybox = new THREE.Mesh( new THREE.BoxBufferGeometry(10000, 10000, 10000), materials );
scene.add(skybox);

skybox.rotation.y = Math.PI / 2;

Как показано здесь: https :

@wmcmurray Вам нужно будет переместить этот скайбокс с камерой, чтобы он работал правильно, и вам нужно будет убедиться, что размер вашего бокса X <Math.sqrt (0,75 * camera.far * camera.far), поэтому углы всегда вписывается в вид, но это кажется проще, чем мой способ поворота / отмены вращения сцены.

Должны ли мы заново открывать PR для этого? Есть два варианта использования, и если мы не хотим влиять на производительность, мы можем использовать определение шейдера:

  • Пример использования 1: среда предварительно вычисляется один раз, и ее не нужно вращать в шейдере. Это может быть сделано пользователем либо на CPU, либо даже на GPU, если он хочет
  • Вариант использования 2: при работе со средством просмотра довольно часто можно повернуть фон в реальном времени, например, с помощью мыши.

Чтобы предотвратить влияние умножения матриц на пользователя с вариантом использования 1 , возможно, мы можем просто добавить такой флаг, как:

renderer.dynamicBackground = true;

и соответственно скомпилировать шейдер фона?

В это время

Как указали @wmcmurray и @capnmidnight , вы можете перекодировать свой собственный фоновый рендеринг, и это не так уж сложно. Только будьте особенно осторожны с плоскостью обзора (ближние и дальние значения).

Вместо использования MeshBasicMaterial вы также можете напрямую создать свой собственный шейдер, расширяющий ShaderMaterial и пробовать кубическую карту.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги