说shape是平面雕刻大师一点都不为过。shade可以雕刻出各种复杂的平面,包括房子的那种什么c4d设计图纸。然后通过曲线的拉伸,将建筑立体化。
下面这里演示一个简单的使用场景:
完整代码:
javascript
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
export default (domId) => {
/* ------------------------------初始化三件套--------------------------------- */
const dom = document.getElementById(domId);
const { innerHeight, innerWidth } = window
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 2000);
camera.position.set(100, 100, 100);
camera.lookAt(scene.position);
const renderer = new THREE.WebGLRenderer({
antialias: true,// 抗锯齿
alpha: false,// 透明度
powerPreference: 'high-performance',// 性能
// logarithmicDepthBuffer: true,// 深度缓冲
})
renderer.shadowMap.enabled = true;// 开启阴影
renderer.shadowMap.type = THREE.PCFSoftShadowMap;// 阴影类型
renderer.outputEncoding = THREE.sRGBEncoding;// 输出编码
renderer.toneMapping = THREE.ACESFilmicToneMapping;// 色调映射
renderer.toneMappingExposure = 1;// 色调映射曝光
renderer.physicallyCorrectLights = true;// 物理正确灯光
renderer.setPixelRatio(window.devicePixelRatio);// 设置像素比
renderer.setSize(innerWidth, innerHeight);// 设置渲染器大小
dom.appendChild(renderer.domElement);
// 重置大小
window.addEventListener('resize', () => {
const { innerHeight, innerWidth } = window
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
})
/* ------------------------------初始化工具--------------------------------- */
const controls = new OrbitControls(camera, renderer.domElement) // 相机轨道控制器
controls.enableDamping = true // 是否开启阻尼
controls.dampingFactor = 0.05// 阻尼系数
controls.panSpeed = -1// 平移速度
const axesHelper = new THREE.AxesHelper(10);
scene.add(axesHelper);
/* ------------------------------正题--------------------------------- */
// Shape表示一个平面多边形轮廓
const shape = new THREE.Shape();
shape.moveTo(10, 0);// 移动到指定点
shape.lineTo(100, 0);//.currentPoint变为(100, 0)
shape.lineTo(100, 100);//.currentPoint变为(100, 100)
shape.lineTo(10, 100);//.currentPoint变为(10, 100)
// 创建空
// Shape内孔轮廓
const path1 = new THREE.Path();// 圆孔1
path1.absarc(20, 20, 10);
const path2 = new THREE.Path();// 圆孔2
path2.absarc(80, 20, 10);
const path3 = new THREE.Path();// 方形孔
path3.moveTo(50, 50);
path3.lineTo(80, 50);
path3.lineTo(80, 80);
path3.lineTo(50, 80);
//三个内孔轮廓分别插入到holes属性中
shape.holes.push(path1, path2, path3);
const geometry = new THREE.ExtrudeGeometry(shape, {
depth: 20,//拉伸长度
bevelEnabled: false,//禁止倒角
curveSegments: 50,
});
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
console.log('currentPoint', shape.currentPoint);
/* ------------------------------动画函数--------------------------------- */
const animation = () => {
controls.update();// 如果不调用,就会很卡
renderer.render(scene, camera);
requestAnimationFrame(animation);
}
animation();
}