在 Three.js 和 WebGL 中渲染 2D SVG 时遇到问题

Trouble rendering a 2D SVG in Three.js & WebGL

我有一个 ThreeJS 场景(下面,或者 here on CodePen) with some objects in it - one is a Mesh object of a cat, one is a cube, and now, I'm trying to render a 2D SVG illustration 我制作的。我想将 SVG 插图放在猫图像和立方体之间的场景中,以与猫图像相同的方式显示(直立和二维)。

我花了好几天时间才弄清楚如何渲染我自己的 SVG,我发现 ThreeJs.org 上的 SVGRenderer 和 SVGLoader 的文档和示例非常繁琐且难以选择适用于我自己的图像(我'我是新手)。我最接近渲染我的 SVG 的是使用来自 SO thread that uses a LegacySVG Loader 的代码。问题是,我完全不知道如何将这段代码渲染到 canvas 与 DOM 上,而且这个 LegacySVG Loader 似乎是一个错误的解决方案,这个错误使得很难找到资源。

所以,基本上,我已经使用上述资源在 an individual CodePen 中渲染了一个 SVG,现在我不知道如何将它渲染到与我的立方体和猫图像相同的场景中。是否可以使用 LegacySVG 渲染到 canvas?或者,是否有更简单的方法让我的 SVG 与其他对象位于相同的 canvas 上?

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. SVGRenderer does not render the same things as WebGLRenderer

    一个。 SVGRenderer 获取 <svg> 元素内的项目并将转换应用于其内部 <path><circle><rect> 等元素。你可以看到svg_sandbox example。所有 SVG 元素都是 2D 的,但在旋转时可以给人以 3D 的印象。

    b。 WebGLRenderer 绘制到 <canvas> 元素上,可以渲染各种真实的 3D 几何图形。如果要在 WebGL 中绘制 SVG,则需要先使用 THREE.SVGLoader. You can see how that's done in the webgl_loader_svg example 将 SVG 文件转换为 WebGL 可以理解的几何图形(源代码可通过单击 <>右下角的按钮)。

  2. 您不能让 <svg> 元素与 <canvas> 中的 WebGL 元素共存于同一 3D space 中。如果你想将带有猫图像的立方体和平面添加到相同的 space,我建议你使用 WebGLRenderer 方法。

  3. 我在您的代码片段中注意到您正在使用来自许多不同来源的文件,以及各种 Three.js 修订。有些文件是r102.1,有些是r68,还有一些是最新的,也就是r113。在尝试让旧文件与新文件一起工作时,您应该坚持一个修订以避免冲突。例如: