Three.js进行模型剖切,剖切面颜色可控。
用three.js自带的.clippingPlanes可以对模型进行剖切,通过GUI可以控制剖切面的移动。为了看到剖切面,一般使用THREE.Plane制作一个可视化平面。这里由于我们需要对剖切面进行贴纹理之类的操作,于是放弃了使用Plane,选择自己画一个BufferGeometry,使其跟随剖切面移动,并且将顶点颜色通过剖切面所在高度来确定,最后通过插值获得渐变的颜色。为了方便,中间被剖切的模型只画了一个平面。

代码可能有些乱,没整理也没注释,凑合看,准备放到项目中再优化。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>cloudchart</title>
<script src="../build/three.js"></script>
<script src="../examples/js/controls/OrbitControls.js"></script>
<script src="../examples/js/libs/dat.gui.min.js"></script>
</head>
<body>
<script type="module">
// import * as THREE from "/build/Three"
// import { OrbitControls } from "/examples/js/controls/Orbitcontrols"
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(100, 100, 100);
camera.lookAt(scene.position);
let pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(100, 100, 100);
scene.add(pointLight);
let ambientLight = new THREE.AmbientLight(0x444444);
scene.add(ambientLight);
let geometry0 = new THREE.BufferGeometry();
let geometry1 = new THREE.BufferGeometry();
let vertices0 = new Float32Array([
25, 25, 0,
25, -25, 0,
-25, -25, 0,
25, 25, 0,
-25, -25, 0,
-25, 25, 0,
]);
let vertices1 = new Float32Array([
50, 0, 50,
-50, 0, 50,
-50, 0, -50,
50, 0, 50,
-50, 0, -50,
50, 0, -50,
]);
geometry0.setAttribute("position", new THREE.BufferAttribute(vertices0, 3));
geometry1.setAttribute("position", new THREE.BufferAttribute(vertices1, 3));
let colors0 = new Float32Array([
0.3, 0.3, 0.3,
Math.random(), Math.random(), Math.random(),
0.7, 0.7, 0.7,
0.3, 0.3, 0.3,
0.7, 0.7, 0.7,
Math.random(), Math.random(), Math.random(),
]);
const colors1 = (parms) => {
return (new Float32Array([
0.3, 0.3, 0.3,
Math.random() * parms / 50, Math.random() * parms / 50, Math.random() * parms / 50,
0.7, 0.7, 0.7,
0.3, 0.3, 0.3,
0.7, 0.7, 0.7,
Math.random() * parms / 50, Math.random() * parms / 50, Math.random() * parms / 50,
]))
}
geometry0.attributes.color = new THREE.BufferAttribute(colors0, 3);
geometry1.attributes.color = new THREE.BufferAttribute(colors1(0), 3);
let params = {
planeY: {
constant: 0
}
};
let planes = [new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)];
console.log(params);
let material0 = new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors,
side: THREE.DoubleSide,
clippingPlanes: planes,
clipIntersection: true
});
let material1 = new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors,
side: THREE.DoubleSide,
})
let mesh0 = new THREE.Mesh(geometry0, material0);
let mesh1 = new THREE.Mesh(geometry1, material1);
// console.log('diatance', planes[0].constant);
// mesh1.position.y = data1;
// console.log('data1', data1);
// console.log('y', mesh1.position.y);
scene.add(mesh0);
scene.add(mesh1);
let axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000);
document.body.appendChild(renderer.domElement);
let gui = new dat.GUI();
gui.add(params.planeY, 'constant').min(-50).max(50).onChange(
(parms) => {
planes[0].constant = -parms;
mesh1.position.y = parms;
geometry1.attributes.color = new THREE.BufferAttribute(colors1(parms), 3);
}
);
// let helper = new THREE.PlaneHelper(planes[0], 100, 0x323fff);
// scene.add(helper);
// renderer.clippingPlanes = planes;
renderer.localClippingEnabled = true;
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
animate();
function createControls() {
}
let controls = new THREE.OrbitControls(camera, renderer.domElement);
// controls.addEventListener("change", render);
</script>
</body>
</html>

浙公网安备 33010602011771号