如何使用 babylonjs 或 threejs 预览 3D 中的 2D 平面对象? [关闭]
Posted
技术标签:
【中文标题】如何使用 babylonjs 或 threejs 预览 3D 中的 2D 平面对象? [关闭]【英文标题】:How can i preview 2D flat objects in 3D using babylonjs or threejs? [closed] 【发布时间】:2020-11-09 00:35:24 【问题描述】:我正在使用fabricJS,并且在平面画布大小的矩形对象(基础)上几乎没有随机图形(例如圆形、正方形、多边形)。
我想以 3D 形式预览所有雕刻在主矩形对象上的图纸。
他们有任何图书馆可用于此吗?我用谷歌搜索了一下,发现了 three.js 和 Babylon.js,但其中没有与我的要求类似的示例,即使我不知道这些库是否可行。
现在想在浏览器中使用 JS 库将其转换为 3D 预览。
请指导我。
【问题讨论】:
请考虑更改您的问题?要求第三方库是题外话。 请指导我,我是新手,如果您有更好的建议,请改进我的问题上下文 我不想要关于图书馆的建议,但我想要任何关于我的要求的例子我不是fabricjs或3d等方面的专家 Three.js 是一个 3D 库,因此可以用它创建 3D 的东西。 是的,我已经知道了,但我的问题不同,让我通过预览更新我的问题 【参考方案1】:我认为您应该使用 Three.JS 而不是 BabylonJs,它更易于处理且体积更小。
这是一个示例代码,您可能看起来与此类似。
您所要做的就是从 FabricJS 中提取 SVG 并将其放入 ThreeJS。
// --- Init threejs scene
// ----------------------
const scene = new THREE.Scene();
const ratio = window.innerWidth / window.innerHeight;
const renderer = new THREE.WebGLRenderer( antialias: true );
renderer.setSize(window.innerWidth, window.innerHeight);
const camera = new THREE.PerspectiveCamera(100, ratio, 0.01, 1000);
camera.position.z = 300;
document.querySelector("body").appendChild(renderer.domElement);
// Resize and update camera
window.addEventListener('resize', function(e)
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
);
// Axes helper
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);
// --- Main part, load and parse SVG
// ---------------------------------
const svgMarkup = document.querySelector('svg').outerhtml;
// SVG Loader is not a part of the main three.js bundle
// We need to load it separately, it is included in this pen's Settings > javascript
// https://threejs.org/docs/#examples/en/loaders/SVGLoader
const loader = new THREE.SVGLoader();
const svgData = loader.parse(svgMarkup);
// Group we'll use for all SVG paths
const svgGroup = new THREE.Group();
// When importing SVGs paths are inverted on Y axis
// it happens in the process of mapping from 2d to 3d coordinate system
svgGroup.scale.y *= -1;
const material = new THREE.MeshNormalMaterial();
// Loop through all of the parsed paths
svgData.paths.forEach((path, i) =>
const shapes = path.toShapes(true);
// Each path has array of shapes
shapes.forEach((shape, j) =>
// Finally we can take each shape and extrude it
const geometry = new THREE.ExtrudeGeometry(shape,
depth: 20,
bevelEnabled: false
);
// Create a mesh and add it to the group
const mesh = new THREE.Mesh(geometry, material);
svgGroup.add(mesh);
);
);
// Meshes we got are all relative to themselves
// meaning they have position set to (0, 0, 0)
// which makes centering them in the group easy
// Get group's size
const box = new THREE.Box3().setFromObject(svgGroup);
const size = new THREE.Vector3();
box.getSize(size);
const yOffset = size.y / -2;
const xOffset = size.x / -2;
// Offset all of group's elements, to center them
svgGroup.children.forEach(item =>
item.position.x = xOffset;
item.position.y = yOffset;
);
// Finally we add svg group to the scene
scene.add(svgGroup);
// --- Animation loop
// ------------------
function animate()
renderer.render(scene, camera);
// Rotate out group
svgGroup.rotation.y += 0.005;
requestAnimationFrame(animate);
animate();
svg
display: none;
canvas
display: block;
a
font-family: Helvetica, Arial, sans-serif;
font-size: 15px;
padding: 10px 16px;
display: block;
position: fixed;
bottom: 0;
right: 0;
color: #ddd;
transition: all 0.25s;
a:hover
color: #3498db;
<script src="https://unpkg.com/three@0.111.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.111.0/examples/js/loaders/SVGLoader.js"></script>
<svg viewBox="0 0 202 202" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path fill="none" d="M201,1 L201,201 L1,201 L1,1 L201,1 Z M53.27053,71 L37.6666667,71 L37.6666667,134.333333 L53.27053,134.333333 L53.27053,86.6038647 C59.2367133,86.879227 66.1207733,91.1014493 66.1207733,99.9130433 L66.1207733,134.333333 L80.4396133,134.333333 L80.4396133,99.9130433 C80.4396133,91.1014493 87.32367,86.879227 93.2898567,86.6038647 L93.2898567,134.333333 L110.63768,134.333333 L110.63768,86.6038647 C116.603863,86.879227 123.487923,91.1014493 123.487923,99.9130433 L123.487923,134.333333 L137.806763,134.333333 L137.806763,99.9130433 C137.806763,91.1014493 144.69082,86.879227 150.657003,86.6038647 L150.657003,134.333333 L166.26087,134.333333 L166.26087,71 L150.657003,71 C142.120773,71 133.859903,75.589372 130.647343,80.178744 C127.434783,75.589372 119.173913,71 110.63768,71 L93.2898567,71 C84.7536233,71 76.4927533,75.589372 73.2801933,80.178744 C70.0676333,75.589372 61.8067633,71 53.27053,71 Z" stroke="#979797"></path></svg>
Example code
【讨论】:
非常感谢您至少用示例代码回复我,是的,您的示例更接近但由于我不是 ThreeJS 专家,我试图用我自己排除的 SVG 替换您的 SVG 代码,问题就在于此仅排除形状,而不是像您的示例中显示的那样进行插入或雕刻。也许我做错了什么 我认为您的主要矩形形状与您面临此问题的形状无关,让我们等待其他 ThreeJS 专家以更简单的解决方案回复您。 three.js 中没有这种开箱即用的功能。你必须自己实现它。以上是关于如何使用 babylonjs 或 threejs 预览 3D 中的 2D 平面对象? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何让相机聚焦在物体上并使用 Babylonjs 将其保持在中心焦点?