「端午」- 发现一颗粽子星。。。

827 阅读3分钟

“我正在参加「初夏创意投稿大赛」详情请看:初夏创意投稿大赛

在线链接

简介

在距离地球几光年外,有一颗行星,不仅外形酷似粽子,而且当地还盛产粽子,地表皆为绿色植物所覆盖,配合当地所植的大米,包出的粽子口感独特,广受星际公民的好评。该星因粽子而闻名由来以久,具体来源已不可考究。特产通过星际快递发放,需要请提取预定哦~

模型制作

粽子星整体外观呈现粽子形状,粽子星环上的小行星也呈粽子形状。。。

在Blender中,新建一个立方体,取名为 - zongziStar

image.png

进入编辑模式 - 选中四个点 - 按下M(合并顶点) - 选则collapse(顶点就会收缩到一个点)

image.png

粽子星的基本样子就出来了。。

image.png

按下shift + D,复制一份放到旁边,用于做粽子星环上的小行星

image.png

选则一个粽子,全选所有顶点 - 按下ctrl + B (倒角),增加分段,这样边缘就更光滑了!(粽子星)

image.png

新建一个圆环 - circle - 开始粽子星环了!

image.png

选中圆环,创建毛发粒子效果

image.png

粒子调整参数。

  • 选择的是在点上创建图形
  • 所以点越多,环上的图形越多(密度)

image.png

image.png

为什么要指定复制的那个物体呢?

  • 因为复制出来的,没有做过倒角,面数较少!
  • 之前是用倒角后的当粒子,三角面有几十万。。文件太大。。。

再新建一个圆环,同样的操作,这次缩小一下放大系数

image.png

新建了四个以后。。

image.png

选中圆环,进入编辑器窗口,点击convert,就能把粒子效果应用到模型中,可以删除那个圆环了!

image.png

不要的都删除了以后

image.png

因为由圆环制作的效果,比较平均,随机选中一些物体,调整一下位置(上下左右)

image.png

效果大概这样,,然后选中所有的小的,合并到一个图层(按下ctrl + J),命名为asteroids

image.png

整体效果, 调整了大小关系。

image.png

在材质面板中,设置一下颜色!

image.png

最后,选中这两个模型,导出为gltf格式!

image.png

gltf-viewer中查看,可以的!

image.png

代码细节

引入资源

  • three.js
  • OrbitControls.js
  • GLTFLoader.js
https://cdnjs.cloudflare.com/ajax/libs/three.js/r125/three.min.js
https://unpkg.com/three@0.125.2/examples/js/controls/OrbitControls.js
https://unpkg.com/three@0.125.2/examples/js/loaders/GLTFLoader.js

基础搭建

  • canvas
  • camera、scene、renderer
  • controls
  • gltfLoader
  • directionalLight
// Canvas
const canvas = document.querySelector("canvas.webgl");

// Scene
const scene = new THREE.Scene();

// GLTF loader
const gltfLoader = new THREE.GLTFLoader();

// Light
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
scene.add(directionalLight);

// camera
const camera = new THREE.PerspectiveCamera(
	45,
	sizes.width / sizes.height,
	0.1,
	100
);
camera.position.x = -4;
camera.position.y = 2;
camera.position.z = -16;
scene.add(camera);

// controls
const controls = new THREE.OrbitControls(camera, canvas);
controls.enableDamping = true;
controls.maxPolarAngle = Math.PI / 2 - 0.1; // 最大旋转角度。

// renderer
const renderer = new THREE.WebGLRenderer({
	canvas: canvas,
	antialias: true
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.outputEncoding = THREE.sRGBEncoding;

加载模型

  • 定义star 和asteroids,获取模型实例
  • 在load中调用animate(),因为load是异步的
  • 这样就可以在加载结束后获取到模型实例,就可以旋转了!
let star, asteroids;
gltfLoader.load("./glb/zongziStar.glb", async (gltf) => {
    
    // 获取模型实例
    star = await gltf.scene.children.find((child) => child.name === 'zongziStar');
    asteroids = await gltf.scene.children.find((child) => child.name === 'asteroids');

    scene.add(gltf.scene);

    animate();
});

粒子效果

  • 用了好几次了 - 好看的。。
  • 粒子效果。。
// 散布于空中的点 - 尘埃效果!
for (let i = 0; i < 2000; i++) {
	const x = (Math.random() * size + Math.random() * size) / 2 - size / 2
	const y = (Math.random() * size + Math.random() * size) / 2 - size / 2
	const z = (Math.random() * size + Math.random() * size) / 2 - size / 2
	vertices.push(x, y, z)
}

geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)) // 几何
material = new THREE.PointsMaterial({ // 材质(点材质)
	size: 0.08,
	color: 0xffffff,
})
const particles = new THREE.Points(geometry, material) // 创建图形 (几何 + 材质)
scene.add(particles) // 添加进场景!

动画函数

  • 这样星星和粒子都能旋转了!
const animate = () => {
	// Update controls
	controls.update();
	rotate();
	// Render
	renderer.render(scene, camera);
	window.requestAnimationFrame(animate);
};

function rotate() {
	asteroids.rotation.z += 0.002;
	star.rotation.x += 0.002;
	star.rotation.y += 0.002;
	particles.rotation.y -= 0.002;
}

截个图。。

image.png

总结

也许在某天,就可以预定了。。。

星空之所以美丽,是因为每颗星星都有自己的轨迹~