“我正在参加「初夏创意投稿大赛」详情请看:初夏创意投稿大赛”
在线链接
简介
在距离地球几光年外,有一颗行星,不仅外形酷似粽子,而且当地还盛产粽子,地表皆为绿色植物所覆盖,配合当地所植的大米,包出的粽子口感独特,广受星际公民的好评。该星因粽子而闻名由来以久,具体来源已不可考究。特产通过星际快递发放,需要请提取预定哦~
模型制作
粽子星整体外观呈现粽子形状,粽子星环上的小行星也呈粽子形状。。。
在Blender中,新建一个立方体,取名为 - zongziStar
进入编辑模式 - 选中四个点 - 按下M(合并顶点) - 选则collapse(顶点就会收缩到一个点)
粽子星的基本样子就出来了。。
按下shift + D,复制一份放到旁边,用于做粽子星环上的小行星
选则一个粽子,全选所有顶点 - 按下ctrl + B (倒角),增加分段,这样边缘就更光滑了!(粽子星)
新建一个圆环 - circle - 开始粽子星环了!
选中圆环,创建毛发粒子效果
粒子调整参数。
- 选择的是在点上创建图形
- 所以点越多,环上的图形越多(密度)
为什么要指定复制的那个物体呢?
- 因为复制出来的,没有做过倒角,面数较少!
- 之前是用倒角后的当粒子,三角面有几十万。。文件太大。。。
再新建一个圆环,同样的操作,这次缩小一下放大系数
新建了四个以后。。
选中圆环,进入编辑器窗口,点击convert,就能把粒子效果应用到模型中,可以删除那个圆环了!
不要的都删除了以后
因为由圆环制作的效果,比较平均,随机选中一些物体,调整一下位置(上下左右)
效果大概这样,,然后选中所有的小的,合并到一个图层(按下ctrl + J),命名为asteroids
整体效果, 调整了大小关系。
在材质面板中,设置一下颜色!
最后,选中这两个模型,导出为gltf格式!
在gltf-viewer中查看,可以的!
代码细节
引入资源
- 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;
}
截个图。。
总结
也许在某天,就可以预定了。。。
星空之所以美丽,是因为每颗星星都有自己的轨迹~