Three.js: CubeTexture orientation

Creado en 25 abr. 2019  ·  31Comentarios  ·  Fuente: mrdoob/three.js

En mi aplicación, me gustaría rotar CubeTexture que define el fondo de la escena y los reflejos del mapa del entorno en 180 ° a lo largo del eje y vertical.
Mi rotación está definida por las especificaciones VRML y X3D sobre los campos de fondo.

Intenté modificar varios parámetros como los campos mapping , flipY y rotation Texture. Sin embargo, no encontré ninguna buena manera de hacerlo.

  • ¿Hay alguna forma obvia de hacerlo que me perdí?
  • ¿Alguna posibilidad de ver esto venir en three.js ?
  • Si quisiera implementarlo, ¿qué parámetros le gustaría ver (por ejemplo, Texture.flipX y CubeTexture.flipZ )? ¿Estaría interesado en esta función?
Enhancement

Comentario más útil

¿Te refieres a poder rotar scene.background ? Si es así ... sí, definitivamente interesado.

Sin embargo, probablemente necesitemos una nueva API ...

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

Todos 31 comentarios

¿Te refieres a poder rotar scene.background ? Si es así ... sí, definitivamente interesado.

Sin embargo, probablemente necesitemos una nueva API ...

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

Estoy luchando exactamente con esto en este momento. Intentando obtener sombras del suelo horneadas para que coincidan con la dirección del sol de un mapa de cubos.
Parece que en algún punto del camino mi mapa de cubos se está volteando 180 grados. Sería genial si pudiera arreglar eso aquí en lugar de volver a renderizar mi mapa de cubos varias veces y tratar de averiguar dónde está sucediendo.

@fabienrohrer Probar

scene.rotation.y = Math.PI;

Si eso no funciona, proporcione un ejemplo en vivo para demostrar exactamente lo que está haciendo.

Oh, eso funciona? 😮 Sin embargo, ¿la cámara debe ser una hija de la escena?

Sin embargo, ¿la cámara debe ser una hija de la escena?

No creo que eso importe.

@mrdoob esto es exactamente lo que necesito también :-)

@WestLangley :

La rotación de la escena general es excesiva y puede causar muchos efectos secundarios en mi aplicación.

Me gustaría poder rotar solo el fondo y, por supuesto, los mapas del entorno deberían funcionar de la misma manera.

No es posible hacer una demostración en vivo porque falta la API. Es cuestión de tomar cualquier ejemplo que tenga un mapa de cubos de fondo (como https://threejs.org/examples/#webgl_materials_cubemap) y poder rotar solo el fondo alrededor del eje y. O de manera más general, para aplicar cualquier rotación al fondo.

Ser capaz de aplicar una matriz / cuaternión de rotación personalizada a cualquier mapa de cubos parece ser la solución más genérica para mí.

three.js se asegura de que los reflejos del material sean coherentes con el material envMap , que se define en el sistema de coordenadas del espacio mundial. Permitir a los usuarios rotar el fondo de la escena daría como resultado un fondo que no coincide con los reflejos del material.

¿Por qué no crea el mapa de cubos del espacio mundial correcto en su aplicación?

Sin embargo, ¿la cámara debe ser una hija de la escena?

No creo que eso importe.

Intenté hacer scene.rotation.y ++ en la consola en webgl_materials_standard y la pistola gira. Luego intenté hacer scene.add( camera ) y luego, si hago scene.rotation.y ++ , hace lo que buscamos, pero luego los controles de la cámara se estropean 😁

Si introducimos un objeto THREE.Background , podríamos agregar API para manejar esto, además en el renderizador también podemos introducir la idea de:

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

yo dije

Pruebe scene.rotation.y = Math.PI; Si eso no funciona, ...

Eso significa que puede que no funcione. :-)

Depende del caso de uso. Intenté con OrbitControls y funcionó bien.

no relacionado: el ejemplo webgl_materials_standard debería estar usando controles de órbita, de todos modos IMO.

¿Te refieres a poder rotar la escena del fondo? Si es así ... sí, definitivamente interesado.

Tiene más sentido hacer esto a nivel de textura, de lo contrario, supongo que cualquier iluminación IBL no coincidirá con el fondo.

Permitimos la rotación de texturas normales, ¿hay alguna razón por la que no quisiéramos hacer lo mismo con las texturas de cubos? ¿Es demasiado complejo de implementar?

¿Por qué no crea el mapa de cubos del espacio mundial correcto en su aplicación?

Esto consume mucho tiempo. He estado trabajando en la generación de mapas de cubos durante los últimos días, y hacer cambios y luego volver a renderizar el mapa de cubos me lleva entre 15 y 20 minutos para cada cambio.

Otro caso de uso potencialmente interesante para esto es que podría cambiar la dirección de la iluminación ambiental en tiempo real. Actualmente estoy combinando un mapa de entorno PMREM con una luz direccional para sombras en tiempo real y usando el mapa como un skybox, lo que da un efecto de luz diurna bastante decente.
Obviamente, hay un límite para lo que puede hacer sin cambiar el color del mapa del entorno, pero puede simular al menos un par de horas de luz del día girando el mapa en sincronía con la luz direccional mientras ajusta el .envMapIntensity .

Mi preocupación también se centra en el rendimiento. Actualmente implementé un truco para rotar la textura superior e inferior e intercambiar las otras. Se necesitan aproximadamente 10 ms para rotar una textura de 1024x1024 en JS.

Alternativamente, ¿podría ser posible tener solo dos opciones para la orientación de CubeTexture, la que tiene actualmente y otra (con la rotación de 180 grados) que sería amigable con el otro estándar ampliamente utilizado en formatos 3D (X3D, VRML, etc.) .). Probablemente podríamos adaptar fácilmente la consistencia con los reflejos del material para manejar ambos formatos.

Esto suena familiar # 11103

Si implementara CubeMap.rotation = matrix3 , ¿se fusionaría en r105?

Mi preocupación también se centra en el rendimiento. Actualmente implementé un truco para rotar la textura superior e inferior e intercambiar las otras. Se necesitan aproximadamente 10 ms para rotar una textura de 1024x1024 en JS.

¿Y con qué frecuencia haces esto en tu aplicación?

@WestLangley Solo te doy una respuesta detallada aquí: https://github.com/mrdoob/three.js/pull/16507#discussion_r286337864

¿Y con qué frecuencia haces esto en tu aplicación?

Poco. Una vez al cargar por cliente, y una vez cada vez que se cambia el fondo (caso muy raro). A DEFINE también haría el trabajo.

Mi preocupación también es el rendimiento ... Tarda unos 10 ms.

¿Y con qué frecuencia haces esto en tu aplicación?

Poco. Una vez al cargar por cliente, y una vez cada vez que se cambia el fondo (caso muy raro).

Lo siento, no estoy siguiendo la lógica de eso.

Desafortunadamente, @WestLangley no quiere fusionar mi modificación sobre CubeTexture.rotation debido a la sobrecarga del tiempo de ejecución (una multiplicación suplementaria de mat3). En este caso, me estoy quedando sin ideas para resolver esto limpiamente en threejs.
Si los colaboradores de threejs no resuelven este problema, ciérrelo.

Espero la implementación de esta función.

@FishOrBear Desafortunadamente, los threejs decidieron no implementar esto. Puede aplicar este parche no combinado en una bifurcación, si desea tener esto en su proyecto:

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

@mrdoob ¿ Quizás podamos reconsiderar las solicitudes de esta función en # 18157?

Estoy usando threejs para hacer una aplicación similar a AutoCAD, por lo que usamos xy para sentarnos como un avión.

El CubeTexture actual entra en conflicto un poco con el nuestro.

Por cierto: con Babylon.js, al menos es posible rotar un skybox alrededor del eje y:

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

El motor apoya esto transformando el vector de reflexión en el sombreador de fragmentos. Así que exactamente el enfoque que no se aceptó en el n. ° 16507. Código del sombreador de fragmentos Babylon.js:

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

@mrdoob Creo que deberíamos implementar esta función. Hay otra solicitud en el foro:

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

Dudo que una única multiplicación adicional de matriz / vector por fragmento afecte notablemente el rendimiento.

Todavía tengo el mismo problema en mi aplicación, y el truco para resolverlo es feo y muy costoso ... También recomiendo aceptar esta mejora.

También me encantaría ver esta función agregada.

Parece que el bloqueador es una posible disminución del rendimiento, pero debería ser fácil de probar. Podemos intentar agregarlo, y si hay una caída de rendimiento inaceptable, podemos eliminarlo nuevamente.

Lo mismo aquí, podría usar esta función en lugar de volver a implementar mi renderizado de fondo :)

No estoy seguro de seguir la cuestión del rendimiento. ¿Nada nos impide generar la dirección del rayo directamente en el sombreador de vértices? Entonces costaría tanto como cualquier otra transformación modelMatrix .

En mi caso, podría usar esta función porque estoy renderizando mapas de cubos capturados por cámaras y cargados por usuarios. Las fotos no siempre están orientadas correctamente hacia el norte, por lo que necesitan una corrección manual después de la carga.

Una forma en que lo he hecho es almacenar la rotación como una variable, aplicarla a la escena justo antes de renderizar y luego restablecer la rotación de las escenas al quat de identidad justo después de renderizar.

Esto provoca dos actualizaciones innecesarias en todas las matrices del mundo de mis objetos de escena. También significa que no puedo hacer actualizaciones de posición en onBeforeRender. Pero mantiene la escena en un estado normal de otra manera.

Por cierto (ya que nadie lo mencionó), parece posible hacer un skybox "clásico" que gira usando una variedad de 6 materiales.

algo como esto :

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;

Como se demuestra aquí: https://woodenraft.games/demos/skybox-rotation-threejs.html

@wmcmurray Tendrás que mover este skybox con la cámara para que funcione correctamente, y tendrás que asegurarte de que tu caja tenga una dimensión X <Math.sqrt (0.75 * camera.far * camera.far) por lo que las esquinas siempre encaja en la vista, pero eso parece más fácil que mi truco de rotar / desrotar la escena.

¿Deberíamos reabrir un PR para eso? Hay dos casos de uso y si no queremos afectar el rendimiento, podemos usar una definición de sombreado:

  • Caso de uso 1: el entorno se calcula previamente una vez y no debería ser necesario rotarlo en el sombreador. Esto lo puede hacer el usuario en la CPU o incluso en la GPU si así lo desea.
  • Caso de uso 2: cuando se trabaja en un visor, es bastante común rotar el fondo en tiempo real usando el mouse, por ejemplo.

Para evitar que el usuario con el caso de uso 1 se vea afectado por la multiplicación de matrices, tal vez podamos simplemente agregar una bandera como:

renderer.dynamicBackground = true;

y compila el sombreador de fondo en consecuencia?

Mientras tanto

Como señalaron @wmcmurray y @capnmidnight , básicamente puede volver a codificar su propia representación de fondo y no es tan difícil. Solo tenga mucho cuidado con el plano de visualización (valores cercanos y lejanos).

En lugar de usar MeshBasicMaterial , también puede crear directamente su propio sombreador extendiendo ShaderMaterial y probar el mapa de cubos.

¿Fue útil esta página
0 / 5 - 0 calificaciones