2012-10-01 15 views
11

En Three.js, es posible dibujar directamente en el área WebGL (para una pantalla de inicio o elementos de la interfaz de usuario, por ejemplo) de la manera que podría con un elemento de lienzo HTML5 normal?Dibujar elementos de la interfaz de usuario directamente en el área WebGL con Three.js

Si es así, ¿cómo puede obtener el contexto y qué comandos de dibujo están disponibles?

Si no es así, ¿hay otra forma de lograr esto, a través de otros comandos de dibujo específicos de Three.js o WebGL que cooperarían con Three.js?

Mi plan de copia de seguridad es usar divisiones HTML como superposiciones, pero creo que debería haber una solución mejor.

Gracias!

+1

Brandon Jones tiene una buena demostración de elementos de HUD hechos de divs: http://media.tojicode.com/webgl-samples/hud-test.html – Anton

+0

También eche un vistazo a este hilo: https://github.com/mrdoob/three.js/issues/1959 – WestLangley

+0

gracias chicos, estos son realmente útiles – Dev

Respuesta

9

No puede dibujar directamente en el lienzo WebGL de la misma manera que lo hace con lienzo normal. Sin embargo, hay otros métodos, p.

  • Draw para un lienzo 2D oculto como de costumbre y transferir eso a WebGL, utilizándola como una textura a un quad
  • dibujar imágenes utilizando quads textura mapeada (por ejemplo, marcos de la caja de la salud)
  • caminos Draw (y formas) al poner sus vértices en una VBO y dibujar con el tipo de polígono apropiado
  • Dibujar texto usando una fuente de mapa de bits (básicamente quads con textura) o geometría real (three.js tiene ejemplos y ayudantes para esto)

Usar estos generalmente significa configurar una cámara ortográfica.

Sin embargo, todo esto es bastante trabajo y p. dibujar texto con geometría real puede ser costoso. Si puede arreglárselas con los divs HTML con estilo CSS, debe usarlos ya que es muy rápido de configurar. Además, dibujar sobre el lienzo de WebGL, tal vez usando transparencias, debería ser una buena pista para que el navegador acelere su dibujo div si no lo acelera todo.

Recuerde también que puede lograr mucho con CSS3, p. esquinas redondeadas, transparencia alfa, incluso transformaciones de perspectiva en 3D como lo demuestra el enlace de Anton en el comentario de la pregunta.

+0

excelente respuesta, gracias ... también vea los comentarios anteriores ya que Anton & WestLangley tuvo una buena idea – Dev

+0

hmmmm ... ... Me pregunto si al hacer que todo el fondo de mi página sea un lienzo vacío de webgl forzará al navegador a acelerar todo en función de su comentario. Por alguna razón, no creo que funcione. – trusktr

5

Tuve exactamente el mismo problema. Estaba tratando de crear un HUD (pantalla Head-up) sin DOM y terminé creando esta solución:

  1. Creé una escena separada con una cámara ortográfica.
  2. Creé un elemento de lienzo y utilicé primitivas de dibujo 2D para representar mis gráficos.
  3. Luego creé un plano que se adapta a toda la pantalla y utilicé un elemento de lienzo 2D como textura.
  4. I emitió esa escena secundaria en la parte superior de la escena original

Así es como se ve el código HUD como:

// We will use 2D canvas element to render our HUD. 
var hudCanvas = document.createElement('canvas'); 

// Again, set dimensions to fit the screen. 
hudCanvas.width = width; 
hudCanvas.height = height; 

// Get 2D context and draw something supercool. 
var hudBitmap = hudCanvas.getContext('2d'); 
hudBitmap.font = "Normal 40px Arial"; 
hudBitmap.textAlign = 'center'; 
hudBitmap.fillStyle = "rgba(245,245,245,0.75)"; 
hudBitmap.fillText('Initializing...', width/2, height/2); 

// Create the camera and set the viewport to match the screen dimensions. 
var cameraHUD = new THREE.OrthographicCamera(-width/2, width/2, height/2, -height/2, 0, 30); 

// Create also a custom scene for HUD. 
sceneHUD = new THREE.Scene(); 

// Create texture from rendered graphics. 
var hudTexture = new THREE.Texture(hudCanvas) 
hudTexture.needsUpdate = true; 

// Create HUD material. 
var material = new THREE.MeshBasicMaterial({map: hudTexture}); 
material.transparent = true; 

// Create plane to render the HUD. This plane fill the whole screen. 
var planeGeometry = new THREE.PlaneGeometry(width, height); 
var plane = new THREE.Mesh(planeGeometry, material); 
sceneHUD.add(plane); 

Y eso es lo que he añadido a mi bucle de render:

// Render HUD on top of the scene. 
renderer.render(sceneHUD, cameraHUD); 

Puede jugar con el código fuente completo aquí: http://codepen.io/jaamo/pen/MaOGZV

y leer más acerca de la aplicación en mi blog: http://www.evermade.fi/pure-three-js-hud/

Cuestiones relacionadas