这是我空闲时期,收集素材,通过Three.js绘制的一根魔法魔力仗,花了点心思,算是铜鼓开发小Demo来另类记录学习进步。
创作灵感
- 使用Three.js创造出一颗神秘而神奇的魔力仗,它含嵌了一个魔核,散发出淡淡的光芒,暗示着这个物品蕴含着无穷的魔力和力量。
- 当你仔细观察这个魔力仗时,你会发现它的颜色似乎在不断变化,每一个角度都有着不同的颜色和光芒。
- 魔力仗似乎有着自己的灵魂,它蕴含着神秘的力量和无尽的可能性,静静等待来人靠近。
开发流程
设置场景
- 创建用于渲染Three.js场景的(容器元素):
const canvas = document.querySelector("canvas.webgl") as HTMLCanvasElement;
- 创建渲染器(Renderer)
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector("canvas.webgl")!,
antialias: true,
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor(0x000000, 0.0);
renderer.setSize(canvas.offsetWidth, canvas.offsetHeight);
- 创建场景(Scene)
const scene = new THREE.Scene();
- 创建相机(Camera)
const camera = new THREE.PerspectiveCamera(
40,
window.innerWidth / window.innerHeight,
1,
200
);
camera.position.set(0, 4, 20);
camera.lookAt(0, 0, 0);
- 添加轨道控制器(OrbitControls)
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;
controls.enableZoom = false;
设置环境
- 添加光照
let light = new THREE.DirectionalLight();
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 1.0));
- 添加全景图
let envMap = (await getCubeMapTexture(
renderer,
"./hdr/satara_night_4k.hdr"
)) as THREE.Texture;
设置模型
- 添加魔法杖
let { models, mixer }: any = await addModel(scene);
- 添加魔法阵
let { ring, ringMixer }: any = await addRing(scene);
- 添加光粒子
let particles = new Particles(scene);
设置EffectComposer(后期处理)
- 添加UnrealBloomPass后期处理
let selectiveBloom = new SelectiveBloom(scene, camera, renderer);
设置场景渲染
let time = new Time();
let clock = new THREE.Clock();
window.addEventListener("resize", onResize);
renderer.setAnimationLoop(() => {
let delta = clock.getDelta();
time.tick();
particles.update({
value: time.value(),
});
const shader = ring.material.userData.shader;
if (shader) {
shader.uniforms["uTime"].value = time.value() * 0.0005;
}
if (mixer) mixer.update(delta);
if (ringMixer) ringMixer.update(delta);
if (models) {
world.material.color.set(0x000000);
models.forEach((model: THREE.Mesh) => {
// @ts-ignore;
model.material.color.set(0x000000);
});
ring.material.color.set(0x000000);
scene.background = null;
scene.environment = null;
renderer.toneMappingExposure = 1.02;
}
renderer.setClearColor(0x000000);
selectiveBloom.bloomComposer.render();
if (models) {
world.material.color.copy(world.userData.color);
models.forEach((model: THREE.Mesh) => {
// @ts-ignore;
model.material.color.copy(model.userData.color);
});
ring.material.color.copy(ring.userData.color);
}
if (envMap) {
scene.background = envMap;
scene.environment = envMap;
renderer.toneMappingExposure = 1.0;
}
renderer.setClearColor(0x1d1d1d);
selectiveBloom.finalComposer.render();
// renderer.render(scene, camera);
controls.update();
});