当前位置:首页 > Web开发 > 正文

three.js 制作太阳系统

2024-03-31 Web开发

最近学了three.js,想拿来练练手,喜欢宇宙,于是亲手撸代码来完成这个,为了更真实,于是查了一些相关资料。
1. 距离太阳由近及远分别是【水星,金星,地球,火星,木星,,土星,天王星,海王星】
2. 他们分别到太阳的距离为5791, 10820, 14960, 22794, 77833, 142940, 287099, 450400(单位万千米)
3. 他们的半径分别为2440, 6052, 6371, 3397, 71492, 60268, 25559, 24766(千米)
4. 他们的公转周期分别为88, 225, 365, 687, 4329, 10767, 30769, 60152(天)
5. 他们的自转周期分别为58,243,1, 1, 0.41, 0.42, 0.64, 0.65,
好了除了八大行星都已经调查好了,接下来八大行星都将按照真实比例绘制,(由于周期相差过大,遂正比于1/2次方)

技术图片

1.绘制八大行星

绘制行星很容易,直接看代码

shuixing = renderMesh("shuixing", 0); jinxing = renderMesh("jinxing", 1); diqiu = renderMesh("diqiu", 2); huoxing = renderMesh("huoxing", 3); muxing = renderMesh("muxing", 4); tuxing = renderMesh("tuxing", 5); tianwangxing = renderMesh("tianwangxing", 6); haiwangxing = renderMesh("haiwangxing", 7); scene.add(shuixing); scene.add(jinxing); scene.add(diqiu); scene.add(huoxing); scene.add(muxing); scene.add(tuxing); scene.add(tianwangxing); scene.add(haiwangxing); function renderMesh(name, num) { let texture = new THREE.TextureLoader().load("http://www.bettersmile.cn:90/three_code/assets/textures/planets/"+name+".jpg"); let geometry = new THREE.SphereGeometry(radiuses[num] * RADIUS, 50, 50); let material = new THREE.MeshBasicMaterial({map: texture}); let mesh = new THREE.Mesh(geometry, material); mesh.position.x = distances[num] * DISTANCE + SUNRADIUS * RADIUS; return mesh; }

在绘制的同时,我们还固定了他们的位置哦,

2.绘制小行星带

八大行星都绘制好了,怎么能少了小行星带呢?由于小行星带都是不规则的石头,这里我们使用上一节的ConvexGeometry()渲染。

let asteroidTexture = new THREE.TextureLoader().load("http://www.bettersmile.cn:90/three_code/assets/textures/planets/asteroid.jpg"); asteriods = renderAsteriod(asteroidTexture); scene.add(asteriods); function renderAsteriod(texture) { let asteroid = new THREE.Geometry(); let asteroidMate = new THREE.MeshBasicMaterial(); for(var i=0; i<20000; i++) { let points = []; let rad = Math.pow(Math.random(), 3) * ASTERIODRADIUS; for(var j=0; j<30; j++) { points.push(new THREE.Vector3(Math.random() * RADIUS * rad, Math.random() * RADIUS * rad, Math.random() * RADIUS * rad)) } var asteroidGeom = new THREE.ConvexGeometry(points); var asterMesh = new THREE.Mesh(asteroidGeom, asteroidMate); //2.17-3.64 * 14960 = 32450 - 54450 let dis = (Math.random() * 22000 + 32450) * DISTANCE + SUNRADIUS * RADIUS; let angle = Math.random() * Math.PI * 2; asterMesh.position.x = dis * Math.sin(angle); asterMesh.position.y = Math.random() * ASTERIODRADIUS * RADIUS * 4 - ASTERIODRADIUS * RADIUS * 2; asterMesh.position.z = dis * Math.cos(angle); asterMesh.updateMatrix(); asteroid.merge(asterMesh.geometry, asterMesh.matrix); } let mesh = new THREE.Mesh(asteroid, new THREE.MeshLambertMaterial({map: texture, emissive: 0x484137})); return mesh; }

我们渲染了20000个小行星,这里小行星带距离太阳2.17~3.64个天文单位,一天文单位为14960万千米。

3.加下来我们绘制太阳,月球,土星环

绘制太阳,月球和土星环(土星环P了好久),相对容易,太阳设置在原点,月球围绕地球,土星环围绕土星,

let taiyangTexture = new THREE.TextureLoader().load("http://www.bettersmile.cn:90/three_code/assets/textures/planets/sun.jpg"); let yueqiuTexture = new THREE.TextureLoader().load("http://www.bettersmile.cn:90/three_code/assets/textures/planets/yueqiu.jpg"); let tuxinghuanTexture = new THREE.TextureLoader().load("http://www.bettersmile.cn:90/three_code/assets/textures/planets/tuxinghuan.png"); let taiyangGeom = new THREE.SphereGeometry(SUNRADIUS * RADIUS, 50, 50); let taiyangMate = new THREE.MeshBasicMaterial({map: taiyangTexture}); let yueqiuGeom = new THREE.SphereGeometry(MOONRADIUS * RADIUS, 50, 50); let yueqiuMate = new THREE.MeshBasicMaterial({map: yueqiuTexture}); tuxinghuan = renderTuxinghuan(tuxinghuanTexture); tuxinghuan.position.copy(tuxing.position); scene.add(tuxinghuan); taiyang = new THREE.Mesh(taiyangGeom, taiyangMate); yueqiu = new THREE.Mesh(yueqiuGeom, yueqiuMate); yueqiu.position.set((distances[2] * DISTANCE + SUNRADIUS * RADIUS) + MOONDISTANCE * DISTANCE, 0, 0); scene.add(taiyang); scene.add(yueqiu); function renderTuxinghuan(texture) { let geom = new THREE.RingGeometry(16, 24, 50, 10, 0, Math.PI * 2); let mate = new THREE.MeshLambertMaterial({emissive: 0xaa8766, transparent:false, opacity: 0.8, map: texture, side: THREE.DoubleSide}); let ring = new THREE.Mesh(geom, mate); ring.rotation.x = - Math.PI / 2; ring.rotation.y = - Math.PI / 12; return ring; } function initCanvas() { let canvas = document.createElement(‘canvas‘); canvas.width = 16; canvas.height = 16; let context = canvas.getContext(‘2d‘); let gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2); gradient.addColorStop(0, ‘rgba(244,164,33,1)‘); gradient.addColorStop(0.2, ‘rgba(244,164,33,1)‘); gradient.addColorStop(0.4, ‘rgba(244,164,33,.6)‘); gradient.addColorStop(1, ‘rgba(0,0,0,0)‘); context.fillStyle = gradient; context.fillRect(0, 0, canvas.width, canvas.height); return canvas; } function initSunshine() { let centerBallLite = new THREE.Sprite(new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(initCanvas()), blending: THREE.AdditiveBlending })); centerBallLite.scale.x = centerBallLite.scale.y = centerBallLite.scale.z = 250000 * RADIUS; scene.add(centerBallLite); }

这里我们的土星环使用了RingGeometry()几何体,太阳的光晕使用CanvasTexture()

4.让星球动起来

让所有星星动起来,使用自转和公转,这里需要一点三角函数的功底,

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/39745.html