使用three.js怎么模拟一个太阳系行星体系?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
概况如下:
SphereGeometry 实现自转的太阳;
RingGeometry 实现太阳系星系的公转轨道;
ImageUtils 加载球体和各行星贴图;
canvas 中 createRadialGradient 实现太阳发光效果;
THREE.Sprite 精灵实现太阳系行星。
// 初始化场景var scene = new THREE.Scene();// 初始化相机,第一个参数为摄像机视锥体垂直视野角度,第二个参数为摄像机视锥体长宽比,// 第三个参数为摄像机视锥体近端面,第四个参数为摄像机视锥体远端面var camera = new THREE.PerspectiveCamera(20, dom.clientWidth / dom.clientHeight, 1, 100000);// 设置相机位置,对应参数分别表示x,y,z位置camera.position.set(0, 0, 500);var renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true});
设置场景窗口尺寸,并且初始化控制器,窗口尺寸默认与浏览器窗口尺寸保持一致,最后将渲染器加载到dom中。
// 设置窗口尺寸,第一个参数为宽度,第二个参数为高度renderer.setSize(dom.clientWidth, dom.clientHeight);// 初始化控制器var orbitcontrols = new THREE.OrbitControls(camera,renderer.domElement);// 将渲染器加载到dom中dom.appendChild(renderer.domElement);
定义太阳及其材质,太阳通过 SphereGeometry 来实现,通过 ImageUtils 来导入贴图。
// 定义太阳材质var sunTexture = THREE.ImageUtils.loadTexture('./image/sun_bg.jpg', {}, function () { renderer.render(scene, camera);});// 太阳以及太阳材质设定centerBall = new THREE.Mesh(new THREE.SphereGeometry(30, 30, 30), new THREE.MeshBasicMaterial({ map: sunTexture}));scene.add(centerBall);
太阳发光效果通过 Sprite 引入 canvas 渲染的 createRadialGradient 来实现。
var generateSprite = function (color) { var canvas = document.createElement('canvas'); canvas.width = 16; canvas.height = 16; var context = canvas.getContext('2d'); var gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2); gradient.addColorStop(0, 'rgba(' + color + ',1)'); gradient.addColorStop(0.2, 'rgba(' + color + ',1)'); gradient.addColorStop(0.4, 'rgba(' + color + ',.6)'); gradient.addColorStop(1, 'rgba(0,0,0,0)'); context.fillStyle = gradient; context.fillRect(0, 0, canvas.width, canvas.height); return canvas;};// 添加太阳发光效果var centerBallLite = new THREE.Sprite(new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(generateSprite(sunSpriteColor)), blending: THREE.AdditiveBlending}));centerBallLite.scale.x = centerBallLite.scale.y = centerBallLite.scale.z = sunScaleSize;scene.add(centerBallLite);
太阳系各行星公转轨道通过 RingGeometry 来实现,公转轨道偏移通过 position 来实现,行星体系通过 THREE.Sprite 来实现。
var initSatellite = function (starLiteSize, starLiteRadius, rotation, speed, imgUrl, scene) {var track = new THREE.Mesh(new THREE.RingGeometry(starLiteRadius, starLiteRadius + 0.05, 50, 1), new THREE.MeshBasicMaterial());var centerMesh = new THREE.Mesh(new THREE.SphereGeometry(1, 1, 1), new THREE.MeshLambertMaterial()); //材质设定var starLite = new THREE.Sprite(new THREE.SpriteMaterial({ map: THREE.ImageUtils.loadTexture(imgUrl)}));starLite.scale.x = starLite.scale.y = starLite.scale.z = starLiteSize;starLite.position.set(starLiteRadius, 0, 0);var pivotPoint = new THREE.Object3D();pivotPoint.add(starLite);pivotPoint.add(track);centerMesh.add(pivotPoint);centerMesh.rotation.set(rotation.x, rotation.y, rotation.z);scene.add(centerMesh); return {starLite: centerMesh, speed: speed};};
将创建好的太阳及行星自转公转体系渲染到场景中,自转和公转通过定时修改 position 值来实现,动画使用 requestAnimationFrame 来实现。
// 执行函数var render = function () { renderer.render(scene, camera); centerBall.rotation.y -= 0.01; for (var i = 0; i < starLites.length; i++) { starLites[i].starLite.rotation.z -= starLites[i].speed; } orbitcontrols.update(); requestAnimationFrame(render);}
看完上述内容,你们掌握使用three.js怎么模拟一个太阳系行星体系的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!