javascript - 如何焊接物体并添加鳍状物体 THREE.js
问题描述
我正在制作一个围绕环绕某些行星等的火箭飞船旋转的场景。
我首先从创建自己的火箭飞船对象开始。我正在尝试重新创建一个看起来与此类似的模型https://kyleagnew.files.wordpress.com/2018/02/lowpolyrocket5.jpg
这是我创建的当前模型https://jsfiddle.net/pfya1sjm/4/
从我的模型可以看出,它由许多使用 y 轴创建并相互对齐的对象组成。这也意味着对象看起来并不完全平滑,因为您可以看到它们之间的所有线条。有没有办法可以避免这种情况或将所有物体焊接在一起,使它们成为一个光滑的物体?
另外,对于问题的第二部分,我怎样才能创建伸出火箭底部的鳍状物体?如我试图重制的示例所示。
<------------------------编辑------------- ->
// once everything is loaded, we run our Three.js stuff.
$(function() {
var stats = initStats();
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xEEEEEE, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
window.addEventListener('resize', function()
{
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
} );
controls = new THREE.OrbitControls(camera, renderer.domElement);
// create the object group that contains all the sub-shapes
var rocketGroup = new THREE.Object3D();
scene.add(rocketGroup);
var rocketMaterial = new THREE.MeshLambertMaterial({color: 0xEEEEEE});
var hingeMaterial = new THREE.MeshLambertMaterial({color: 0xFD1414});
/////////////////////////////////////////////////////////////////////////////////////////
var rocketAntennaOne = new THREE.CylinderGeometry( 0, 2, 2, 11 );
var rocketAntennaOneMesh = new THREE.Mesh(rocketAntennaOne, hingeMaterial, new THREE.MeshPhongMaterial());
var rocketAntennaTwo = new THREE.CylinderGeometry( 2, 3, 1, 11 );
var rocketAntennaTwoMesh = new THREE.Mesh(rocketAntennaTwo, hingeMaterial, new THREE.MeshPhongMaterial());
var rocketAntennaThree = new THREE.CylinderGeometry( 3, 4, 1, 11 );
var rocketAntennaThreeMesh = new THREE.Mesh( rocketAntennaThree,hingeMaterial, new THREE.MeshPhongMaterial());
/////////////////////////////////////////////////////////////////////////////////////////
var rocketBodyOne = new THREE.CylinderGeometry( 4, 8, 6, 11 );
var rocketBodyOneMesh = new THREE.Mesh(rocketBodyOne,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyTwo = new THREE.CylinderGeometry( 8, 11, 6, 11 );
var rocketBodyTwoMesh = new THREE.Mesh(rocketBodyTwo,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyThree = new THREE.CylinderGeometry( 11, 14, 6, 11 );
var rocketBodyThreeMesh = new THREE.Mesh(rocketBodyThree,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyFour = new THREE.CylinderGeometry( 14, 15, 6, 11 );
var rocketBodyFourMesh = new THREE.Mesh(rocketBodyFour,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyFive = new THREE.CylinderGeometry( 15, 16, 6, 11 );
var rocketBodyFiveMesh = new THREE.Mesh(rocketBodyFive,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodySix = new THREE.CylinderGeometry( 16, 16, 7, 11 );
var rocketBodySixMesh = new THREE.Mesh(rocketBodySix,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodySeven = new THREE.CylinderGeometry( 16, 15, 6, 11 );
var rocketBodySevenMesh = new THREE.Mesh(rocketBodySeven,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyEight = new THREE.CylinderGeometry( 15, 14, 6, 11 );
var rocketBodyEightMesh = new THREE.Mesh(rocketBodyEight,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyNine = new THREE.CylinderGeometry( 14, 13, 6, 11 );
var rocketBodyNineMesh = new THREE.Mesh(rocketBodyNine,rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyTen = new THREE.CylinderGeometry( 13, 12, 6, 11 );
var rocketBodyTenMesh = new THREE.Mesh(rocketBodyTen,rocketMaterial, new THREE.MeshPhongMaterial());
/////////////////////////////////////////////////////////////////////////////////////////
var rocketBodyUpper = new THREE.CylinderGeometry( 7, 8, 7, 10 );
var rocketBodyUpperMesh = new THREE.Mesh(rocketBodyUpper,rocketMaterial, new THREE.MeshPhongMaterial());
/////////////////////////////////////////////////////////////////////////////////////////
var rocketBodyLower = new THREE.CylinderGeometry( 5.5, 6, 5, 10 );
var rocketBodyLowerMesh = new THREE.Mesh(rocketBodyLower,rocketMaterial, new THREE.MeshPhongMaterial());
//////////////////////////////////////
scene.add(rocketAntennaOneMesh);
scene.add(rocketAntennaTwoMesh);
scene.add(rocketAntennaThreeMesh);
/////////////////////////////////////
scene.add(rocketBodyOneMesh);
scene.add(rocketBodyTwoMesh);
scene.add(rocketBodyThreeMesh);
scene.add(rocketBodyFourMesh);
scene.add(rocketBodyFiveMesh);
scene.add(rocketBodySixMesh);
scene.add(rocketBodySevenMesh);
scene.add(rocketBodyEightMesh);
scene.add(rocketBodyNineMesh);
scene.add(rocketBodyTenMesh);
///////////////////////////////////////
scene.add(rocketBodyUpperMesh);
scene.add(rocketBodyUpperMesh);
//Specify the position of the rocket cone
rocketAntennaOneMesh.position.y = 74;
rocketAntennaTwoMesh.position.y = 72.5;
rocketAntennaThreeMesh.position.y = 71.5;
rocketBodyOneMesh.position.y = 68;
rocketBodyTwoMesh.position.y = 62;
rocketBodyThreeMesh.position.y = 56;
rocketBodyFourMesh.position.y = 50;
rocketBodyFiveMesh.position.y = 44;
rocketBodySixMesh.position.y = 37.5;
rocketBodySevenMesh.position.y = 31;
rocketBodyEightMesh.position.y = 25;
rocketBodyNineMesh.position.y = 19;
rocketBodyTenMesh.position.y = 13;
rocketBodyUpperMesh.position.y = 10;
rocketBodyLowerMesh.position.y = 7;
//Add the rocketCone to the lowpolyRocket group
rocketGroup.add(rocketAntennaOneMesh);
rocketGroup.add(rocketAntennaTwoMesh);
rocketGroup.add(rocketAntennaTwoMesh);
/////////////////////////////////////////
rocketGroup.add(rocketBodyOneMesh);
rocketGroup.add(rocketBodyTwoMesh);
rocketGroup.add(rocketBodyThreeMesh);
rocketGroup.add(rocketBodyFourMesh);
rocketGroup.add(rocketBodyFiveMesh);
rocketGroup.add(rocketBodySixMesh);
rocketGroup.add(rocketBodySevenMesh);
rocketGroup.add(rocketBodyEightMesh);
rocketGroup.add(rocketBodyNineMesh);
rocketGroup.add(rocketBodyTenMesh);
//////////////////////////////////////////
rocketGroup.add(rocketBodyUpperMesh);
rocketGroup.add(rocketBodyLowerMesh);
// create the ground plane
var planeGeometry = new THREE.PlaneGeometry(60, 20);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
// rotate and position the plane
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 15;
// add the plane to the scene
scene.add(plane);
// position and point the camera to the center of the scene
camera.position.x = -150;
camera.position.y = 110;
camera.position.z = 20;
camera.lookAt(scene.position);
// add subtle ambient lighting
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
// add spotlight for the shadows
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-70, 60, -10);
spotLight.castShadow = true;
scene.add(spotLight);
// add the output of the renderer to the html element
$("#WebGL-output").append(renderer.domElement);
var controls = new function() {
};
// call the render function
var angle = 0;
render();
function render() {
}
function initStats() {
var stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
$("#Stats-output").append(stats.domElement);
return stats;
}
});
JSFiddle 代码:
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', function() {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
controls = new THREE.OrbitControls(camera, renderer.domElement);
// create the object group that contains all the sub-shapes
var rocketGroup = new THREE.Object3D();
scene.add(rocketGroup);
var rocketMaterial = new THREE.MeshLambertMaterial({
color: 0xEEEEEE
});
var hingeMaterial = new THREE.MeshLambertMaterial({
color: 0xFD1414
});
/////////////////////////////////////////////////////////////////////////////////////////
var rocketAntennaOne = new THREE.CylinderGeometry(0, 2, 2, 11);
var rocketAntennaOneMesh = new THREE.Mesh(rocketAntennaOne, hingeMaterial, new THREE.MeshPhongMaterial());
var rocketAntennaTwo = new THREE.CylinderGeometry(2, 3, 1, 11);
var rocketAntennaTwoMesh = new THREE.Mesh(rocketAntennaTwo, hingeMaterial, new THREE.MeshPhongMaterial());
var rocketAntennaThree = new THREE.CylinderGeometry(3, 4, 1, 11);
var rocketAntennaThreeMesh = new THREE.Mesh(rocketAntennaThree, hingeMaterial, new THREE.MeshPhongMaterial());
/////////////////////////////////////////////////////////////////////////////////////////
var rocketBodyOne = new THREE.CylinderGeometry(4, 8, 6, 11);
var rocketBodyOneMesh = new THREE.Mesh(rocketBodyOne, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyTwo = new THREE.CylinderGeometry(8, 11, 6, 11);
var rocketBodyTwoMesh = new THREE.Mesh(rocketBodyTwo, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyThree = new THREE.CylinderGeometry(11, 14, 6, 11);
var rocketBodyThreeMesh = new THREE.Mesh(rocketBodyThree, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyFour = new THREE.CylinderGeometry(14, 15, 6, 11);
var rocketBodyFourMesh = new THREE.Mesh(rocketBodyFour, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyFive = new THREE.CylinderGeometry(15, 16, 6, 11);
var rocketBodyFiveMesh = new THREE.Mesh(rocketBodyFive, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodySix = new THREE.CylinderGeometry(16, 16, 7, 11);
var rocketBodySixMesh = new THREE.Mesh(rocketBodySix, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodySeven = new THREE.CylinderGeometry(16, 15, 6, 11);
var rocketBodySevenMesh = new THREE.Mesh(rocketBodySeven, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyEight = new THREE.CylinderGeometry(15, 14, 6, 11);
var rocketBodyEightMesh = new THREE.Mesh(rocketBodyEight, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyNine = new THREE.CylinderGeometry(14, 13, 6, 11);
var rocketBodyNineMesh = new THREE.Mesh(rocketBodyNine, rocketMaterial, new THREE.MeshPhongMaterial());
var rocketBodyTen = new THREE.CylinderGeometry(13, 12, 6, 11);
var rocketBodyTenMesh = new THREE.Mesh(rocketBodyTen, rocketMaterial, new THREE.MeshPhongMaterial());
/////////////////////////////////////////////////////////////////////////////////////////
var rocketBodyUpper = new THREE.CylinderGeometry(7, 8, 7, 10);
var rocketBodyUpperMesh = new THREE.Mesh(rocketBodyUpper, rocketMaterial, new THREE.MeshPhongMaterial());
/////////////////////////////////////////////////////////////////////////////////////////
var rocketBodyLower = new THREE.CylinderGeometry(5.5, 6, 5, 10);
var rocketBodyLowerMesh = new THREE.Mesh(rocketBodyLower, rocketMaterial, new THREE.MeshPhongMaterial());
//////////////////////////////////////
scene.add(rocketAntennaOneMesh);
scene.add(rocketAntennaTwoMesh);
scene.add(rocketAntennaThreeMesh);
/////////////////////////////////////
scene.add(rocketBodyOneMesh);
scene.add(rocketBodyTwoMesh);
scene.add(rocketBodyThreeMesh);
scene.add(rocketBodyFourMesh);
scene.add(rocketBodyFiveMesh);
scene.add(rocketBodySixMesh);
scene.add(rocketBodySevenMesh);
scene.add(rocketBodyEightMesh);
scene.add(rocketBodyNineMesh);
scene.add(rocketBodyTenMesh);
///////////////////////////////////////
scene.add(rocketBodyUpperMesh);
scene.add(rocketBodyUpperMesh);
//Specify the position of the rocket cone
rocketAntennaOneMesh.position.y = 74;
rocketAntennaTwoMesh.position.y = 72.5;
rocketAntennaThreeMesh.position.y = 71.5;
rocketBodyOneMesh.position.y = 68;
rocketBodyTwoMesh.position.y = 62;
rocketBodyThreeMesh.position.y = 56;
rocketBodyFourMesh.position.y = 50;
rocketBodyFiveMesh.position.y = 44;
rocketBodySixMesh.position.y = 37.5;
rocketBodySevenMesh.position.y = 31;
rocketBodyEightMesh.position.y = 25;
rocketBodyNineMesh.position.y = 19;
rocketBodyTenMesh.position.y = 13;
rocketBodyUpperMesh.position.y = 10;
rocketBodyLowerMesh.position.y = 7;
//Add the rocketCone to the lowpolyRocket group
rocketGroup.add(rocketAntennaOneMesh);
rocketGroup.add(rocketAntennaTwoMesh);
rocketGroup.add(rocketAntennaTwoMesh);
/////////////////////////////////////////
rocketGroup.add(rocketBodyOneMesh);
rocketGroup.add(rocketBodyTwoMesh);
rocketGroup.add(rocketBodyThreeMesh);
rocketGroup.add(rocketBodyFourMesh);
rocketGroup.add(rocketBodyFiveMesh);
rocketGroup.add(rocketBodySixMesh);
rocketGroup.add(rocketBodySevenMesh);
rocketGroup.add(rocketBodyEightMesh);
rocketGroup.add(rocketBodyNineMesh);
rocketGroup.add(rocketBodyTenMesh);
//////////////////////////////////////////
rocketGroup.add(rocketBodyUpperMesh);
rocketGroup.add(rocketBodyLowerMesh);
var ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 0.8);
camera.add(pointLight);
scene.add(camera);
// position and point the camera to the center of the scene
camera.position.x = -140;
camera.position.y = 20;
camera.position.z = 30;
camera.lookAt(scene.position);
// game logic
var update = function() {
//cone.rotation.x += 0.01;
//cone.rotation.y += 0.005;
};
// draw scene
var render = function() {
renderer.render(scene, camera);
};
// run game loop (update, render, repeat)
var GameLoop = function() {
requestAnimationFrame(GameLoop);
update();
render();
};
GameLoop();
body {
margin: 0;
}
<script type="text/javascript" src="https://threejs.org/build/three.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/libs/dat.gui.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
解决方案
身体部分之间的边缘看起来很硬,因为匹配顶点的法线不同,并且以这种方式混合。
THREE.MeshPhongMaterial
使用顶点法线进行边缘融合。如果一条边的两条法线相同,则两条边看起来会混合在一起。如果法线指向不同的方向,边缘会显得很硬。
你有几个选择:
编辑几何图形,使相交的边对它们的每个配对顶点共享相同的法向量值。
手动将几何图形合并到一个几何对象中,然后找出不同的法线,并将它们配置为使用相同的法线。
THREE.Geometry
使用或构建自定义几何定义THREE.BufferGeometry
。
我真的建议尝试选项 3,因为您可能需要使用它来定义您的“鳍”。您可能会变得棘手并弄清楚如何定位/缩放/倾斜原始网格以满足您的要求,但构建自定义几何体(在我看来)会容易得多。
推荐阅读
- android-studio - Android Studio 中新 Flutter 项目中未解决的引用
- c# - C# 字体不会改变,但字体大小会改变
- r - 用其他数据框替换值作为参考
- haskell - 卡在“可配置”的haskell类中
- django - (DJANGO) NoReverseMatch 在后/
- macos - 如何更改 NSButton 复选框的颜色?
- c++ - 对于接口类,C++ 核心准则 C35“基类析构函数应该是公共的和虚拟的,或者受保护的和非虚拟的”是否错误?
- php - PHP 不应该等待第一个命令;在 sleep() 之前,这是如何完成的?
- python - 将包含元组的 pandas 列转换为字符串
- javascript - 在 iframe 中运行 Javascript 命令