目前,我正在开发一个web应用程序,当这些面孔被雷克斯特(鼠标)悬停时,应该给它们另一种颜色。
我目前有一个工作的.stl查看器和轨道控制到位。
使用已知的工作.stl文件看我的github下载并运行我的代码。您可以非常轻松地运行它,只需要一个活动服务器(这在例如VSCode中很容易实现,请参阅自述文件)。
目前,它可以很好地改变整个对象的颜色,但是当我尝试使用raycaster的intersects改变面部颜色时(就像更改对象的属性一样),它不起作用。我已经读过了,你必须把vertexColors: THREE.VertexColors添加到你的材料属性中。
我可以看到颜色值正在变化(在脸的颜色属性上使用console.log ),当我更改intersects[i].face.color.setHex(0x0f0f0f)时,它会改变为一个不同的腐蚀值。但视觉表情并没有改变。
我想我错过了什么或者忽略了什么,但我似乎无法弄清楚。
我现在的代码是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3d viewer tjalle</title>
<link rel="stylesheet" type="text/css" href="../style/render.css">
</head>
<body>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r117/build/three.min.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r117/examples/js/loaders/STLLoader.js"></script>
<script src="https://rawcdn.githack.com/mrdoob/three.js/r117/examples/js/controls/OrbitControls.js"></script>
<script>
function init() {
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
document.addEventListener('mousemove', onMouseMove, false);
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
// Setup some basic stuff
scene = new THREE.Scene();
scene.background = new THREE.Color(0xdddddd);
// Setup Camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 5000);
// Setup renerer and add to page
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// Setup Camera Position
camera.rotation.y = 45 / 180 * Math.PI;
camera.position.x = 800;
camera.position.y = 100;
camera.position.z = 1000;
// Add Camera Control through orbit.js
let controls = new THREE.OrbitControls(camera, renderer.domElement);
// Add some basic ambient lighting (Does light all parts equally and does not cast shadows)
hlight = new THREE.AmbientLight(0xffffff, 5.3);
scene.add(hlight);
//Add some point lights to simulate real lights
light = new THREE.PointLight(0xffffff, 1, 10000);
light.position.set(0, 300, 500);
scene.add(light);
controls.update();
// Animation Script
function animate() {
raycaster.setFromCamera(mouse, camera);
// scene.children[2].material.color.set(0x1313)
// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObjects(scene.children);
for (var i = 0; i < intersects.length; i++) {
// changes whole object to red
// intersects[i].object.material.color.set(0xff0000);
intersects[i].face.color.setHex(0x0f0f0f)
}
if (intersects.length > 1) {
console.log(intersects[1].face.color);
}
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
// Setup GLTF Loader and load in car
let loader = new THREE.STLLoader();
loader.load('example.stl', function (geometry) {
// console.log(gltf);
var material = new THREE.MeshLambertMaterial({
color: 0x1313,
wireframe: false,
transparent: false,
vertexColors: THREE.vertexColors
});
var mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
mesh.position.set(0, 0, 0);
mesh.name = 'Tjalle\'s Mesh'
scene.add(mesh);
renderer.render(scene, camera)
animate();
console.log("Scene: ",)
console.log(mesh)
});
}
// Call method for starting init
init();
</script>
</body>
</html>发布于 2020-07-15 16:38:17
交集对象的face属性是只读的.这意味着即使你修改了它,实际的几何数据也不会被更新。
请记住,您使用的是BufferGeometry,它通过顶点数据表示几何图形。没有像遗留Geometry类那样的面子抽象。因此,如果您想修改每个脸的颜色,您必须确保在您的几何图形中没有人脸定义共享顶点。换句话说,只有在非索引几何学中才能做到这一点。幸运的是,STLLoader只返回非索引的几何图形。
实际顶点颜色数据存储在颜色缓冲区属性中。您可以通过const colorAttribute = geometry.getAttribute( 'color' );访问它。您必须更新此缓冲区属性中的颜色值,以实现您的预期功能。这方面的模式是:
const face = intersects[ 0 ].face;
const color = new THREE.Color( Math.random() * 0xffffff ); // random color
const colorAttribute = geometry.getAttribute( 'color' );
colorAttribute.setXYZ( face.a, color.r, color.g, color.b );
colorAttribute.setXYZ( face.b, color.r, color.g, color.b );
colorAttribute.setXYZ( face.c, color.r, color.g, color.b );
colorAttribute.needsUpdate = true;STLLoader不一定会产生颜色缓冲区属性,因此如果缺少颜色缓冲区属性,您可能必须创建一个属性。
https://stackoverflow.com/questions/62914985
复制相似问题