Проблемы с рендерингом 2D SVG в Three. js и WebGL - PullRequest
0 голосов
/ 13 февраля 2020

У меня есть Три JS Сцена (ниже или здесь на CodePen ) с некоторыми объектами в ней - один - объект кошачьего Me sh, один - куб, и теперь Я пытаюсь сделать 2D-иллюстрацию SVG Я сделал. Я хочу поместить иллюстрацию SVG в сцену между изображением кота и кубом, отображаемым так же, как изображение кота (в вертикальном положении и в 2D).

Мне понадобилось несколько дней, чтобы понять, как В рендеринге моего собственного SVG я нахожу документацию и примеры на Three Js .org для SVGRenderer и SVGLoader чрезвычайно громоздкими и трудными для выбора, применимы к моему собственному изображению (я новичок). Самое близкое к визуализации моего SVG - использование кода из этого SO-потока, который использует LegacySVG Loader. Проблема в том, что я совершенно заблудился в том, как визуализировать этот код на холсте, а не в DOM, и кажется, что этот загрузчик LegacySVG был решением ошибки, из-за которой чрезвычайно трудно находить ресурсы.

Итак, по сути, я рендерил SVG в отдельном CodePen , используя вышеупомянутые ресурсы, и теперь я теряюсь в том, как отобразить его в той же сцене, что и мои изображения куба и кошки. Можно ли использовать LegacySVG для рендеринга на холст? Или есть более простой способ перенести мой SVG на тот же холст, что и другие объекты?

let renderer;
let camera;
//let controls;

let scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(54, window.innerWidth / window.innerHeight, 0.1, 1000);

renderer = new THREE.WebGLRenderer({
    antialias: true,
    canvas: document.getElementById("viewport")
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0xfefefe));
// document.body.appendChild(renderer.domElement);

camera.position.x = 1;
camera.position.y = 1;
camera.position.z = 15;





let light = new THREE.AmbientLight(0xFFFFFF);
scene.add(light);

let gridHelper = new THREE.GridHelper(10, 10);
scene.add(gridHelper);

// example code

const geometry1 = new THREE.BoxGeometry(1, 1, 1);
const material1 = new THREE.MeshStandardMaterial({
    color: 0xff0000
});
const topBox = new THREE.Mesh(geometry1, material1);
scene.add(topBox);

var loader = new THREE.TextureLoader();

// Load an image file into a custom material
var material = new THREE.MeshLambertMaterial({
  map: loader.load('https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80')
});

// create a plane geometry for the image with a width of 10
// and a height that preserves the image's aspect ratio
var geometry = new THREE.PlaneGeometry(2, 1.5);

// combine our image geometry and material into a mesh
var mesh = new THREE.Mesh(geometry, material);

// set the position of the image mesh in the x,y,z dimensions
mesh.position.set(0,0,5);

// add the image to the scene
scene.add(mesh); 



let animate = function() {
    requestAnimationFrame(animate);

    //controls.update();
    renderer.render(scene, camera);
};
//////////////////
animate();

function updateCamera(ev) {
  
	camera.position.z = 15 - window.scrollY / 250.0;
}

window.addEventListener("scroll", updateCamera);
body {
	overflow-x: hidden;
    overflow-y: scroll;
	padding: 0;
	margin: 0;
  
}

canvas {
	position: fixed;
  height: 100vh;
}

#threeD {
    position: fixed;
	margin: 0;
	padding: 0;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    
    
}
.page-wrapper {
	padding: 0px;
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	
  height: 4000vh;
}



#container {
	height: 500vh;
	position: fixed;
}
<html>
    <script src="https://raw.githubusercontent.com/mrdoob/three.js/master/src/loaders/LoadingManager.js"></script>
 <script src="https://unpkg.com/three@0.102.1/build/three.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="https://cdn.rawgit.com/mrdoob/three.js/r68/examples/js/loaders/SVGLoader.js"></script>
    <script src="https://raw.githubusercontent.com/mrdoob/three.js/master/examples/js/renderers/SVGRenderer.js"></script>
    <link rel="stylesheet" type="text/css" href="index1.css" />

    
    <body>
            <canvas id="viewport"></canvas>
         
                <div class="page-wrapper" >
                  <h1> scroll! </h1>

                
                  
                </div>

            
    </body>
   

	<script src="index1.js"></script>
    

</html>

1 Ответ

1 голос
/ 13 февраля 2020

Есть несколько вещей, которые вы должны иметь в виду.

  1. SVGRenderer не отображает те же вещи, что и WebGLRenderer .

    а. SVGRenderer принимает элементы внутри элемента <svg> и применяет преобразования к его внутренним элементам <path>, <circle>, <rect>, et c. Вы можете увидеть пример svg_sandbox . Все элементы SVG являются двумерными, но при вращении могут создавать впечатление трехмерности.

    b. WebGLRenderer dr aws на элемент <canvas> и может отображать все виды истинной трехмерной геометрии. Если вы хотите нарисовать SVG в WebGL, вам необходимо сначала преобразовать файл SVG в геометрию, понятную WebGL, используя THREE.SVGLoader. Вы можете увидеть, как это делается в примере webgl_loader_svg , (исходный код доступен при нажатии кнопки <> в правом нижнем углу).

  2. You элементы <svg> не могут сосуществовать в одном трехмерном пространстве с элементами WebGL в <canvas>. Если вы хотите добавить кубы и плоскости с изображениями кошек в одно и то же пространство, я рекомендую использовать подход WebGLRenderer.

  3. В вашем фрагменте кода я заметил, что вы используете файлы из многих различные источники и все виды трех. js редакций. Некоторые файлы r102.1, некоторые r68, а некоторые самые последние, то есть r113. Вы должны придерживаться одной ревизии, чтобы избежать конфликтов при попытке заставить старые файлы работать с более новыми. Например:

...