Javascript 正交摄影机和使用光线投射选择对象
我在使用光线投射器使用正交摄影机选择对象时遇到了一些困难。不过,当我使用透视相机时,我对它没有问题。在两者之间切换时,我唯一要改变的是相机类型 我可以在正交视图上选择面,但它与我在屏幕上单击的位置关系不大。当我可以在远离对象的地方单击时,它仍然会返回,就好像它击中了靠近其中心的对象一样 你知道我在这里遗漏了什么吗 我的大部分代码都基于此,我希望从我的代码中获得一个非常相似的结果。我引用的这个示例使用透视摄影机 非常感谢您的帮助Javascript 正交摄影机和使用光线投射选择对象,javascript,three.js,raycasting,orthographic,Javascript,Three.js,Raycasting,Orthographic,我在使用光线投射器使用正交摄影机选择对象时遇到了一些困难。不过,当我使用透视相机时,我对它没有问题。在两者之间切换时,我唯一要改变的是相机类型 我可以在正交视图上选择面,但它与我在屏幕上单击的位置关系不大。当我可以在远离对象的地方单击时,它仍然会返回,就好像它击中了靠近其中心的对象一样 你知道我在这里遗漏了什么吗 我的大部分代码都基于此,我希望从我的代码中获得一个非常相似的结果。我引用的这个示例使用透视摄影机 非常感谢您的帮助 <html> <head> <st
<html>
<head>
<style>
canvas {
left: 0;
top: 0;
width: 100%;
height: 100%;
position: fixed;
background-color: #111115;
}
</style>
</head>
<body id='c'>
<script src="js/three.js"></script>
<script>
var obj = [];
var mouse ={};
var zoom = 2;
var scene = new THREE.Scene();
//switch between these two and see the difference:
//var camera = new THREE.OrthographicCamera(window.innerWidth / -zoom, window.innerWidth / zoom, window.innerHeight / zoom, window.innerHeight / -zoom, -1000, 1000);
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position = new THREE.Vector3(100,100,100);
camera.lookAt(new THREE.Vector3(0,0,0));
// this material causes a mesh to use colors assigned to faces
var material = new THREE.MeshBasicMaterial(
{ color: 0xffffff, vertexColors: THREE.FaceColors } );
var sphereGeometry = new THREE.SphereGeometry( 80, 32, 16 );
for ( var i = 0; i < sphereGeometry.faces.length; i++ )
{
face = sphereGeometry.faces[ i ];
face.color.setRGB( 0, 0, 0.8 * Math.random() + 0.2 );
}
obj['box'] = {};
obj['box'] = new THREE.Mesh( sphereGeometry, material );
obj['box'].castShadow = true;
obj['box'].receiveShadow = true;
scene.add(obj['box']);
var ambientLight = new THREE.AmbientLight(0xbbbbbb);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(-100, 40, 100);
directionalLight.castShadow = true;
directionalLight.shadowOnly = true;
directionalLight.shadowDarkness = .5;
scene.add(directionalLight);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
document.body.appendChild(renderer.domElement);
projector = new THREE.Projector();
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
function onDocumentMouseDown( event ) {
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
// event.preventDefault();
console.log("Click.");
// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// find intersections
// create a Ray with origin at the mouse position
// and direction into the scene (camera direction)
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( [obj['box']] );
// if there is one (or more) intersections
if ( intersects.length > 0 )
{
console.log("Hit @ " + toString( intersects[0].point ) );
console.log(intersects);
// change the color of the closest face.
intersects[ 0 ].face.color.setRGB( 0.8 * Math.random() + 0.2, 0, 0 );
intersects[ 0 ].object.geometry.colorsNeedUpdate = true;
}
}
function toString(v) { return "[ " + v.x + ", " + v.y + ", " + v.z + " ]"; }
var render = function() {
requestAnimationFrame(render);
renderer.render(scene, camera);
};
console.log(camera);
console.log(obj['box'])
render();
</script>
</body>
我希望这是一件我还不知道的简单事情
three.js r60以下是使用正交摄影机或透视摄影机进行光线投射时使用的模式:
var raycaster = new THREE.Raycaster(); // create once
var mouse = new THREE.Vector2(); // create once
...
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( objects, recursiveFlag );
three.js r.84还有一个注释可能会为您省去一些麻烦。如果您有这样的相机:
var camera = new THREE.OrthographicCamera(0, window.innerWidth, -window.innerHeight, 0, -100, 100);
然后,在光线投射过程中,确保将光线原点.z移动到camera.far,以使其击中整个可见范围内的任何物体:
this.ray.origin.set(0, 0, 0);
this.camera.localToWorld(this.ray.origin);
this.ray.setFromCamera(this.mouseCoord, this.camera);
this.ray.origin.z = this.camera.far;
提示:平面附近的正交摄影机为负片。在摄像机后面。它应该是积极的。另外,前四个参数是世界坐标,而不是像素坐标,因此不要混淆。thx。令人不舒服的是,拾取代码取决于相机类型……但比在WebGL中自行创建要好得多:请添加相机配置,因为您呈现的片段依赖于它。太好了:我还添加了this.ray=this.raycaster.ray