Javascript Three.js:Raycast有一个空的相交数组
我将此示例用于我的WebGL全景立方体: 我想知道cube用户点击了什么,我发现我可以使用Raycaster来实现这一点。根据文档,我添加了以下功能:Javascript Three.js:Raycast有一个空的相交数组,javascript,three.js,Javascript,Three.js,我将此示例用于我的WebGL全景立方体: 我想知道cube用户点击了什么,我发现我可以使用Raycaster来实现这一点。根据文档,我添加了以下功能: function onMouseDown( event ) { event.preventDefault(); var mouseVector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,
function onMouseDown( event ) {
event.preventDefault();
var mouseVector = new THREE.Vector3(
( event.clientX / window.innerWidth ) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1,
1 );
//projector.unprojectVector( mouseVector, camera );
mouseVector.unproject( camera );
var raycaster = new THREE.Raycaster( camera.position, mouseVector.sub( camera.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = raycaster.intersectObjects( scene.children );
console.log(intersects);
if (intersects.length>0){
console.log("Intersected object:", intersects.length);
intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
}
// ...
但是,相交
始终为空。我的场景定义为
scene = new THREE.Scene();
skyBox还添加了:
var skyBox = new THREE.Mesh( new THREE.CubeGeometry( 1, 1, 1 ), materials );
skyBox.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, - 1 ) );
scene.add( skyBox );
我看到过与此问题相关的类似帖子,但不知道如何应用于此示例。欢迎提供任何指导。尝试将此添加到材质定义中:
var materials = new THREE.SomeMaterial({
/* other settings */,
side: THREE.DoubleSide
});
Raycaster
不会与背面相交,除非side
属性设置为thire.BackSide
或thire.DoubleSide
。即使从技术上讲,缩放会反转面方向,但顶点顺序保持不变,这对于Raycaster
非常重要
一些进一步的解释
下面的代码片段显示了从天空盒中心的摄影机投影的光线(按a-Z比例反转)的外观
长方体本身看起来很奇怪,因为它已按-Z比例缩放,法线不再与材质匹配。但这是不存在的
绿色箭头表示原始光线。红色箭头表示在Mesh.raycast
函数中该光线将发生的情况,该函数将对象的世界矩阵的倒数应用于光线,但不应用于对象的几何体。这是一个完全不同的问题
我要强调的是,在Mesh.raycast
中,它不会影响顶点/索引顺序,因此当它检查网格的三角形时,它们仍然保持原始顺序。对于标准的BoxGeometry
/BoxBufferGeometry
,这意味着所有面都从几何原点向外
这意味着光线(无论变换矩阵如何影响它们)仍在尝试与这些三角形的背面相交,除非将材质设置为3。DoubleSide
。(它也可以设置为3.BackSide
,但-Z刻度将破坏这一点。)
如果-Z缩放框未设置为3,则单击任一光线投射按钮将产生0个相交。双面
(默认)。单击“Set THREE.DoubleSide”按钮并重试--它现在将相交
var渲染器、场景、摄影机、控件、统计信息;
变量宽度=window.innerWidth,
高度=窗内高度,
FOV=35,
近=1,
远=1000,
ray1,ray2,网格;
函数populateScene(){
var cubeGeo=新的3.BoxBufferGeometry(10,10,10),
cubeMat=新的三点网格材质({颜色:“红色”,透明:真,不透明度:0.5});
网格=新的三个网格(cubeGeo,cubeMat);
applyMatrix(新的三个.Matrix4().makeScale(1,1,-1));
更新矩阵世界(true);
场景。添加(网格);
var dir=新的三个向量3(0.5,0.5,1);
dir.normalize();
ray1=new THREE.Ray(new THREE.Vector3(),dir);
var arrow1=新的三个.ArrowHelper(ray1.direction,ray1.origin,200x00ff00);
场景。添加(箭头1);
var inverseMatrix=新的三个.Matrix4();
获取逆矩阵(mesh.matrixWorld);
ray2=ray1.clone();
ray2.ApplyMatrix X4(反向矩阵);
var arrow2=新的三个.ArrowHelper(ray2.direction,ray2.origin,20,0xff0000);
场景。添加(箭头2);
}
函数init(){
document.body.style.backgroundColor=“slateGray”;
renderer=new THREE.WebGLRenderer({antialas:true,alpha:true});
document.body.appendChild(renderer.doElement);
document.body.style.overflow=“隐藏”;
document.body.style.margin=“0”;
document.body.style.padding=“0”;
场景=新的三个。场景();
摄像机=新的三个透视摄像机(视野、宽度/高度、近距离、远距离);
摄像机位置z=50;
场景。添加(摄影机);
控件=新的三个.trackball控件(摄影机、渲染器.doElement);
controls.dynamicDampingFactor=0.5;
controls.rotateSpeed=3;
var灯光=新的三点灯光(0xffffff,1,无穷大);
相机。添加(灯光);
统计数据=新统计数据();
stats.domElement.style.position='绝对';
stats.domElement.style.top='0';
document.body.appendChild(stats.domeElement);
调整大小();
window.onresize=调整大小;
populateScene();
制作动画();
var rayCaster=new THREE.rayCaster();
document.getElementById(“greenCast”).addEventListener(“单击”,函数(){
rayCaster.ray.copy(ray1);
警报(光线投射器。相交对象(网格)。长度+“相交!”);
});
document.getElementById(“redCast”).addEventListener(“单击”,函数(){
rayCaster.ray.copy(ray2);
警报(光线投射器。相交对象(网格)。长度+“相交!”);
});
document.getElementById(“setSide”).addEventListener(“单击”,函数(){
mesh.material.side=3.DoubleSide;
mesh.material.needsUpdate=true;
});
}
函数resize(){
宽度=window.innerWidth;
高度=窗内高度;
if(渲染器和摄影机及控件){
设置大小(宽度、高度);
camera.aspect=宽度/高度;
camera.updateProjectMatrix();
controls.handleResize();
}
}
函数render(){
渲染器。渲染(场景、摄影机);
}
函数animate(){
请求动画帧(动画);
render();
控件更新();
stats.update();
}
函数threeReady(){
init();
}
(功能(){
函数addScript(url,回调){
callback=callback | |函数(){};
var script=document.createElement(“脚本”);
script.addEventListener(“加载”,回调);
setAttribute(“src”,url);
document.head.appendChild(脚本);
}
添加脚本(“https://threejs.org/build/three.js“,函数(){
添加脚本(“https://threejs.org/examples/js/controls/TrackballControls.js“,函数(){
添加脚本(“https://threejs.org/examples/js/libs/stats.min.js“,函数(){
三就绪();
})
})
})
})();代码>
正文{
文本对齐:居中;
}
实际上,您可能希望使用一个更简单的过程从相机确定光线:
THREE.Raycaster.prototype.setFromCamera( Vector2, Camera );
只需像在