Привет, ребята !
Прежде всего, спасибо за Pixi.js, это отличный инструмент, мне он нравится! идеальная противоположность three.js для 2D-мира.
Я работаю над проектом, в котором хотел бы иметь такую конфигурацию:
Как бы вы приступили к инкапсуляции холста Pixi.js внутри холста Three.js?
Спасибо за ваше время !
Ура
Эммануэль
Если three.js поддерживает холст в качестве текстуры, вы можете визуализировать pixi на внеэкранном холсте и использовать его в качестве текстуры в своей сцене three.js.
Пятно! именно так мы это делаем!
В среду, 21 января 2015 г., в 16:45, Чад Энглер [email protected]
написал:
Если three.js поддерживает холст в качестве текстуры, вы можете визуализировать pixi в
закадровый холст и используйте его как текстуру в своей сцене three.js.-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/GoodBoyDigital/pixi.js/issues/1366#issuecomment -70872648
.
Мэт Гровс
_Технический партнер_
Телефон: 07708 114496 :: www.goodboydigital.com
Первый этаж, блок 9B, Queens Yard, White Post Lane, Лондон, E9 5EN
Goodboy ©. Все права защищены.
Вау ... Большое спасибо, ребята! :)
Это то, что я называю быстрой обратной связью!
Я просто думаю о маленькой детали.
Мне нужно иметь возможность рисовать панель 2D UI (Pixi.js), которая будет отображаться в Top of a 3D World (Three.js).
Но важно, чтобы эта 2D-панель пользовательского интерфейса имела следующие свойства.
Если я использую приемы рендеринга своего холста и применяю его как текстуру. Боюсь, что размытие фона будет невозможно?
Я прилагаю изображение, чтобы проиллюстрировать это.
Есть ли размытие на стороне Three.js? Просто сделайте объект pixi прозрачным, а затем смешайте текстуру с вашей 3D-сценой, как хотите.
В очередной раз благодарим за помощь ! Теперь, когда вы это сказали ... это определенно самый логичный путь! :)
Ура
E
Я РЕДАКТИРУЮ сообщение, поскольку я решил мою проблему, я публикую рабочий код на случай, если кто-то столкнется с той же проблемой и понадобится пример.
<body>
<script src="js/pixi.js"></script>
<script src="js/three.min.js"></script>
<script>
width = window.innerWidth;
height = window.innerHeight;
//-------------------------------------------------------------------------------------
// 3D Scene canvas
//-------------------------------------------------------------------------------------
var scene_3D = new THREE.Scene();
scene_3D.fog = new THREE.Fog( "#a1a1a1", 2000, 4000 );
var camera = new THREE.PerspectiveCamera( 75, width / height, 1, 10000 );
camera.position.set( 0, 0, 700);
camera.updateProjectionMatrix();
var canvas_3D = new THREE.WebGLRenderer( { antialias: true } );
canvas_3D.setSize( width, height );
canvas_3D.setClearColor( scene_3D.fog.color, 1 );
document.body.appendChild( canvas_3D.domElement );
var geometry = new THREE.BoxGeometry( 500, 500, 500 );
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh( geometry, material );
cube.position.z = -500;
cube.rotation.z = -45;
scene_3D.add( cube );
//-------------------------------------------------------------------------------------
// 2D UI canvas
//-------------------------------------------------------------------------------------
var scene_UI = new PIXI.Stage( 0x66FF99 );
var canvas_UI = PIXI.autoDetectRenderer(width, height, {transparent:true});
canvas_UI.view.style.position = "absolute";
canvas_UI.view.style.top = "0px";
canvas_UI.view.style.left = "0px";
var graphics = new PIXI.Graphics();
graphics.beginFill( 0xe60630 );
graphics.moveTo( width/2-200, height/2+100 );
graphics.lineTo( width/2-200, height/2-100 );
graphics.lineTo( width/2+200, height/2-100 );
graphics.lineTo( width/2+200, height/2+100 );
graphics.endFill();
scene_UI.addChild( graphics );
//-------------------------------------------------------------------------------------
// Map 2D UI canvas on 3D Plane
//-------------------------------------------------------------------------------------
var texture_UI = new THREE.Texture( canvas_UI.view );
texture_UI.needsUpdate = true;
var material_UI = new THREE.MeshBasicMaterial( {map: texture_UI, side:THREE.DoubleSide } );
material_UI.transparent = true;
var mesh_UI = new THREE.Mesh( new THREE.PlaneGeometry(width, height), material_UI );
mesh_UI.position.set(0,0,0);
scene_3D.add( mesh_UI );
//-------------------------------------------------------------------------------------
// Render Animation
//-------------------------------------------------------------------------------------
function animate() {
requestAnimationFrame( animate );
canvas_UI.render( scene_UI );
cube.rotation.y += 0.01;
canvas_3D.render( scene_3D, camera );
}
animate();
</script>
</body>
Мы делаем что-то подобное в проекте. Это становится немного сложно, поскольку оба движка (pixi и ThreeJS) отслеживают состояние GL, чтобы минимизировать избыточные вызовы. Это означает, что они плохо взаимодействуют друг с другом, поэтому вам нужно сбросить их флаги перед запуском рендереров.
В новых версиях ThreeJS вы можете использовать renderer.resetGLState()
.
В PIXI все немного сложнее. Такие вещи было бы полезно иметь в качестве метода в WebGLRenderer. Это необходимо перед
gl.disable(gl.DEPTH_TEST)
gl.enable(gl.BLEND)
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
gl.disable(gl.STENCIL_TEST)
gl.disable(gl.CULL_FACE)
gl.frontFace( gl.CCW )
gl.cullFace( gl.FRONT )
gl.colorMask(true, true, true, true)
gl.activeTexture(gl.TEXTURE0)
var shaderManager = session.shaderManager
shaderManager._currentId = undefined
for (var i=0; i<shaderManager.attribState.length; i++)
shaderManager.attribState[i] = false
shaderManager.setShader(shaderManager.currentShader)
var blend = session.blendModeManager.currentBlendMode
if (blend in PIXI.blendModesWebGL) {
session.blendModeManager.currentBlendMode = undefined
session.blendModeManager.setBlendMode(blend)
}
Это позволяет отображать пользовательский интерфейс поверх 3D-сцены без переключения буфера кадра.
Достичь размытия под вашим пользовательским интерфейсом значительно сложнее. Вам необходимо:
Спасибо за очень точный и задокументированный отзыв, Мэтт! :)
Поскольку я новичок в программировании на WebGL, это очень полезно.
Сначала я не решался использовать библиотеку Mix 2, особенно то, что взломанный Three.js может в некоторой степени заменить pixi тем, что мне нужно.
Но превосходные примеры, само внимание разработчиков к 2D, действительно убедили меня использовать pixi для вызовов gl2d.
Поскольку вы, похоже, тоже выбрали подход Mix, я думаю, это подтверждает, что Pixi определенно является более эффективным выбором для рисования 2D-элементов с помощью WebGL.
Ура
E
Поскольку вы, похоже, тоже выбрали подход Mix, я думаю, это подтверждает, что Pixi определенно является более эффективным выбором для рисования 2D-элементов с помощью WebGL.
Что же, может быть. В большинстве случаев дополнительная производительность является спорным (как часто вам нужно 3000 кнопки анимации сразу?), И такие вещи, как надежный рендеринга текста, ввод текста и событий прокрутки может быть невероятно сложной в WebGL.
Самый простой способ - просто использовать DOM / CSS для пользовательского интерфейса. Если вам абсолютно необходимо выбрать WebGL (например, для определенных эффектов, тестирования глубины и т.д.), то Pixi, вероятно, будет проще, чем ThreeJS для 2D-интерфейса.
Собираюсь закрыть это, поскольку кажется, что ответ.
Этот поток был автоматически заблокирован, поскольку после его закрытия в последнее время не было никаких действий. Пожалуйста, откройте новую проблему для связанных ошибок.
Самый полезный комментарий
Я РЕДАКТИРУЮ сообщение, поскольку я решил мою проблему, я публикую рабочий код на случай, если кто-то столкнется с той же проблемой и понадобится пример.