Рисование элементов пользовательского интерфейса непосредственно в области WebGL с помощью Three.js
В файле Three.js можно ли рисовать непосредственно в области WebGL (например, для отображения хедз-ап или элементов пользовательского интерфейса), как вы могли бы с помощью обычного элемента холста HTML5?
Если да, как вы можете получить контекст и какие команды рисования доступны?
Если нет, есть ли другой способ выполнить это, используя другие команды чертежа, которые будут взаимодействовать с Three.js?
Мой план резервного копирования состоит в том, чтобы использовать HTML-div как оверлеи, но я думаю, что должно быть лучшее решение.
Спасибо!
Ответы
Ответ 1
Вы не можете рисовать непосредственно на холсте WebGL так же, как с обычным холстом. Однако существуют и другие способы, например
- Нарисуйте скрытый 2D-холст, как обычно, и перенесите его в WebGL, используя его как текстуру для четырехъядерного
- Нарисуйте изображения, используя отображаемые на карте квадраты (например, рамки вашего окна здоровья)
- Нарисуйте пути (и фигуры), поместив их вершины в VBO и нарисуйте их с помощью соответствующего типа многоугольника
- Нарисуйте текст, используя растровый шрифт (в основном текстурированные квадрациклы) или реальную геометрию (у трех .js есть примеры и помощники для этого)
Использование обычно означает установку орфографической камеры.
Однако все это довольно много работы и, например, рисование текста с реальной геометрией может быть дорогостоящим. Если вы можете обойтись с помощью HTML-разделов с стилем CSS, вы должны использовать их так, как это очень быстро настроить. Кроме того, рисование поверх холста WebGL, возможно, с использованием прозрачности, должно быть сильным намеком на то, чтобы браузер на GPU ускорил его рисование div, если он еще не ускорил все.
Также помните, что вы можете достичь довольно многого с помощью CSS3, например. закругленные углы, альфа-прозрачность, даже 3D-перспективные преобразования, о чем свидетельствует ссылка Антона в комментарии к вопросу.
Ответ 2
У меня была точно такая же проблема. Я пытался создать HUD (Head-up display) без DOM, и я решил создать это решение:
- Я создал отдельную сцену с орфографической камерой.
- Я создал элемент холста и использовал примитивы 2D-чертежа для рендеринга графики.
- Затем я создал плоскость, соответствующую всему экрану, и использовал 2D-холст в качестве текстуры.
- Я сделал эту вторичную сцену поверх оригинальной сцены
Как выглядит код HUD:
// 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 );
И что я добавил в мой цикл рендеринга:
// Render HUD on top of the scene.
renderer.render(sceneHUD, cameraHUD);
Вы можете играть с полным исходным кодом здесь:
http://codepen.io/jaamo/pen/MaOGZV
И читайте больше о реализации в своем блоге:
http://www.evermade.fi/pure-three-js-hud/