2012-10-01 17 views
11

W Three.js można narysować bezpośrednio w obszarze WebGL (na przykład w widoku z góry lub w elementach interfejsu użytkownika) w taki sposób, w jaki zwykły element canvas HTML5?Rysowanie elementów interfejsu użytkownika bezpośrednio w obszarze WebGL za pomocą Three.js

Jeśli tak, jak uzyskać kontekst i jakie polecenia do rysowania są dostępne?

Jeśli nie, czy jest inny sposób, aby to osiągnąć, za pomocą innych poleceń rysunkowych opartych na Three.js lub WebGL, które współpracowałyby z Three.js?

Mój plan tworzenia kopii zapasowych polega na użyciu elementów div HTML jako nakładek, ale uważam, że powinno być lepsze rozwiązanie.

Dzięki!

+1

Brandon Jones ma dobry demo elementów wykonanych z hud div: http://media.tojicode.com/webgl-samples/hud-test.html – Anton

+0

Zobacz również ten wątek: https://github.com/mrdoob/three.js/issues/1959 – WestLangley

+0

dzięki, to są naprawdę pomocne – Dev

Odpowiedz

9

Nie można rysować bezpośrednio na kanwie WebGL w taki sam sposób, jak w przypadku normalnego płótna. Istnieją jednak inne metody, np.

  • Draw do ukrytego płótnie 2D jak zwykle i przenieść to do WebGL używając go jako tekstury do quad
  • Draw obrazów z wykorzystaniem tekstur odwzorowany Quady (np klatek skrzynce zdrowia)
  • ścieżki Draw (i kształty) poprzez umieszczenie ich wierzchołków w VBO i narysowanie tego za pomocą odpowiedniego typu wielokąta:
  • Narysuj tekst za pomocą czcionki bitmapowej (zasadniczo teksturowane kwadraty) lub rzeczywistej geometrii (trójdźwięk ma przykłady i pomocników).

Korzystanie z nich zwykle oznacza ustawienie kamery ortograficznej.

Jednak to wszystko wymaga sporo pracy i np. rysowanie tekstu o prawdziwej geometrii może być kosztowne. Jeśli możesz sobie poradzić z divami HTML z stylem CSS, powinieneś ich używać, ponieważ jest bardzo szybki w konfiguracji. Również rysowanie na płótnie WebGL, być może za pomocą przezroczystości, powinno być silną wskazówką dla przeglądarki, aby GPU przyspieszyło jej rysunek div, jeśli jeszcze nie przyspiesza wszystkiego.

Pamiętaj też, że możesz osiągnąć wiele przy pomocy CSS3, np. zaokrąglone rogi, przezroczystość alfa, a nawet transformacje perspektywy 3D, o czym świadczy link Antona w komentarzu do pytania.

+0

świetna odpowiedź, dzięki .. zobacz także komentarze powyżej, jak Anton & WestLangley miał dobry wgląd – Dev

+0

hmmmm ... ... Zastanawiam się, czy na całym tle mojej strony puste płótno webgl zmusi przeglądarkę do przyspieszenia wszystkiego na podstawie Twojego komentarza. Z jakiegoś powodu nie sądzę, że to zadziała. – trusktr

5

Miałem dokładnie ten sam problem. Próbowałem utworzyć HUD (wyświetlacz Head-up) bez DOM i ostatecznie stworzyłem to rozwiązanie:

  1. Stworzyłem oddzielną scenę z aparatem ortograficznym.
  2. Utworzono element canvas i użyłem prymitywów rysunku 2D do renderowania grafiki.
  3. Następnie utworzyłem płaszczyznę pasującą do całego ekranu i użyłem elementu canvas 2D jako tekstury.
  4. I renderowane tę scenę drugorzędną na wierzchu oryginalnego sceny

to jak kod HUD wygląda następująco:

// 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); 

I to właśnie dodałem do mojego renderowania pętli:

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

Można odtwarzać z pełnym kodem źródłowym tutaj: http://codepen.io/jaamo/pen/MaOGZV

I czytaj więcej o realizacji na moim blogu: http://www.evermade.fi/pure-three-js-hud/