-
【合集 8.21 已更新 93 话】Blender 2.9-3.4 黑铁骑士 Ⅱ 系统零基础入门教程(持续更新+中文字幕+普通话+不敷衍+义务教育+案例+学习)
-
three.js 辉光的两种实现方法,及解决添加辉光后背景变成黑色的问题
创建一个场景(Creating a scene)
如何绘制透明的物体
可按照卦限给方块编号 1~8,以配置文件的方式设置方块的颜色及附加信息,便于调整方块的颜色,构造不同关卡。
可附着一个 Box3 对象来标记选中时线框高亮。
const ECubeType = Object.freeze({
solid: {
color: new THREE.Color().setHSL(0 / 8, 1, 0.5),
value: 1,
hyaline: {
color: new THREE.Color().setHSL(3 / 8, 1, 0.8),
value: 0,
});
const CubeCfg = {
d: 0.8,
size: 1.2,
options: [
name: "octant-1",
x: 1,
y: 1,
z: 1,
type: "hyaline",
},...
this.cubeGroup = this._createCubes(CubeCfg);
this.scene.add(this.cubeGroup);
- Box3Helper:设置六个 Box3Helper 并编号,每个 Box3Helper 都能包含四个位置;使用其 Box 对象的 distanceToPoint 方法来判断方块是否在选中的 Box3Helper 范围内,即方块是否选中。
- Raycaster:设置八条射线,可组合出六个面,通过射线相交来找选中的方块;且射线也可监测出投射面板,检查结果也更方便。
* 创建射线组
_createRaycasters(d, size) {
const raycasterOptions = [
* 投射面: XY平面
* 方向:Z负半轴
name: "raycaster-1",
origin: new THREE.Vector3(d, d, d + size),
direction: new THREE.Vector3(0, 0, -1),
type: "solid",
},...
return raycasterOptions
this.raycasterOptions = this._createRaycasters(CubeCfg.d, CubeCfg.size);
this.boardGroup = this._addProjectionBoard(this.raycasterOptions, CubeCfg.d, CubeCfg.size);
this.scene.add(this.boardGroup);
this.planeOptions = [
name: "plane-1",
raycasterIndexs: [0, 1],
rotateAxis: new THREE.Vector3(0, 1, 0),
leftRad: Math.PI / 2,
rightRad: -Math.PI / 2,
},...
知乎 · ThreeJS 四步制作一个简易魔方评论区方法,秒了。
注意:这里的旋转仅仅是方块位置(看成中心点)的旋转,实际上方块旋转过程中还应该考虑自身的旋转,否则动画效果会比较怪异。
* @descption 旋转动画
* @param {*} cubes 旋转的方块
* @param {*} rotateAxis 旋转轴
* @param {*} rad 旋转角度
_rotate(cubes, rotateAxis, rad) {
cubes.forEach((cube) => {
cube.recoardStart = {
position: cube.position.clone(),
rotation: new THREE.Vector3(0, 0, 0),
cube.rotation.x = 0;
cube.rotation.y = 0;
cube.rotation.z = 0;
});
const LOCAL_AXIS = rotateAxis.x ? "x" : rotateAxis.y ? "y" : "z";
const TWEEN_DURATION = 1000;
const tween = new TWEEN.Tween({ percentage: 0 });
tween.easing(TWEEN.Easing.Quartic.InOut);
tween.onUpdate(({ percentage }) => {
cubes.forEach((cube) => {
cube.rotation[LOCAL_AXIS] =
cube.recoardStart.rotation[LOCAL_AXIS] + percentage * rad;
const newPosition = cube.recoardStart.position.clone();
newPosition.applyAxisAngle(rotateAxis, percentage * rad);
cube.position.set(newPosition.x, newPosition.y, newPosition.z);
});
});
tween.onComplete(() => {
this._check();
});
tween.to({ percentage: 1 }, TWEEN_DURATION);
tween.start();