我正在尝试使用此示例代码-https://github.com/mrdoob/three.js/blob/master/examples/webgl_postprocessing_outline.html概述具有某些更改的模型。
更改为:
问题是:
每当我在场景中移动鼠标时,我都会得到相同的相交对象。如图所示,假设场景中只有平面缓冲区几何图形并且移动了鼠标,则相交距离对我来说永远不会改变。现在,如果我在场景中添加多个模型并移动鼠标,则相交对象的大小会发生变化,但距离保持不变,与鼠标移动事件无关。
对于此处的注释代码,我感到抱歉:尝试了很多事情以使其正常工作。请耐心等待。
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - loaders - OBJ loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader test
</div>
<script src="../build/three.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/loaders/OBJLoader.js"></script>
<script src="js/WebGL.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/shaders/FXAAShader.js"></script>
<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>
<script src="js/postprocessing/OutlinePass.js"></script>
<script>
var container;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
var controls;
var mouse;
var objects = [];
var loader;
var manager;
var pickedObject, pickedObjectSavedColor;
const pickPosition = {x: 0, y: 0};
var outlinePass, composer, renderPass, effectFXAA;
var selectedObjects = [];
var textureLoader;
var texture;
var INTERSECTED;
var obj3d = new THREE.Object3D();
var group = new THREE.Group();
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 20000 );
// camera.position.z = 250;
camera.position.set( 300, 300, 300 );
camera.lookAt( 0, 0, 0 );
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x000000 );
var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
scene.add( ambientLight );
var pointLight = new THREE.PointLight( 0xffffff, 0.8 );
camera.add( pointLight );
scene.add( camera );
var gridHelper = new THREE.GridHelper( 4000, 20 );
scene.add( gridHelper );
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
// sets the boundary
var geometry = new THREE.PlaneBufferGeometry( 2000, 2000 );
geometry.rotateX( - Math.PI / 2 );
plane = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { visible: true } ) );
scene.add( group )
group.add( obj3d )
group.add( plane )
// scene.add( plane );
// objects.push( plane );
// manager
function loadModel() {
if ( object ) {
object.traverse( function ( child ) {
if ( child.isMesh ) child.material.map = texture;
} );
// object.position.y = 20;
object.scale.set(2.54, 2.54, 2.54);
scene.add( object );
}
}
manager = new THREE.LoadingManager( loadModel );
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
// texture
textureLoader = new THREE.TextureLoader( manager );
// var texture = textureLoader.load( 'models/obj/52329571/mid/diffuse_2048.png' );
// model
function onProgress( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( 'model ' + Math.round( percentComplete, 2 ) + '% downloaded' );
}
}
function onError() {}
loader = new THREE.OBJLoader( manager );
// loader.load( 'models/obj/52329571/mid/52329571_mid.obj', function ( obj ) {
// object = obj;
// }, onProgress, onError );
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', animate ); // call this only in static scenes (i.e., if there is no animation loop)
// controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
// controls.dampingFactor = 0.25;
controls.screenSpacePanning = false;
// controls.minDistance = 100;
// controls.maxDistance = 500;
// controls.maxPolarAngle = Math.PI / 2;
controls.update();
composer = new THREE.EffectComposer( renderer );
renderPass = new THREE.RenderPass( scene, camera );
composer.addPass( renderPass );
outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
composer.addPass( outlinePass );
effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);
effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);
effectFXAA.renderToScreen = true;
composer.addPass(effectFXAA);
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
var x, y;
if ( event.changedTouches ) {
x = event.changedTouches[ 0 ].pageX;
y = event.changedTouches[ 0 ].pageY;
} else {
x = event.clientX;
y = event.clientY;
}
pickPosition.x = ( x / window.innerWidth ) * 2 - 1;
pickPosition.y = - ( y / window.innerHeight ) * 2 + 1;
checkIntersection();
animate();
}
function checkIntersection() {
// // console.log("Checking intersection");
// var vector = new THREE.Vector3(pickPosition.x, pickPosition.y, 1);
// vector.unproject(camera);
// var ray = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
// console.log(objects)
// var intersects = ray.intersectObjects( objects, true );
// if ( intersects.length > 0 ) {
// // console.log("intersects: ", intersects);
// if (intersects[0].object != INTERSECTED) {
// // console.log(" NEW intersect: ", intersects);
// // restore previous intersection object (if it exists) to its original color
// if (INTERSECTED)
// // INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
// // store reference to closest object as current intersection object
// // console.log("previous object: ", INTERSECTED)
// INTERSECTED = intersects[0].object;
// // console.log("new object: ", INTERSECTED)
// // store color of closest object (for later restoration)
// // INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// // set a new color for closest object
// // INTERSECTED.material.color.setHex(0xffff00);
// }
// } else // there are no intersections
// {
// console.log("No intersection")
// // restore previous intersection object (if it exists) to its original color
// if (INTERSECTED)
// // INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
// // remove previous intersection object reference
// // by setting current intersection object to "nothing"
// INTERSECTED = null;
// }
// controls.update();
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( [ scene ], true );
console.log(intersects)
if ( intersects.length > 0 ) {
var selectedObject = intersects[ 0 ].object;
addSelectedObject( selectedObject );
outlinePass.selectedObjects = selectedObjects;
} else {
// outlinePass.selectedObjects = [];
}
}
function onDocumentMouseDown( event ) {
// console.log("mouse down event received")
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
event.preventDefault();
console.log("mouse down received")
mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 );
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.children, true );
if ( intersects.length > 0 ) {
var intersect = intersects[ 0 ];
// delete cube
// delete object feature call
if ( false ) {
if ( intersect.object !== plane ) {
scene.remove( intersect.object );
objects.splice( objects.indexOf( intersect.object ), 1 );
}
// create cube
} else {
console.log("onDocumentMouseDown call to obj loader first object")
// objLoaderFunction(loader, textureMap, intersect)
// var voxel = new THREE.Mesh( cubeGeo, cubeMaterial );
// console.log("objLoaderFunction call complete")
// objMesh.position.copy( intersect.point ).add( intersect.face.normal );
// // voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
// scene.add( objMesh );
// objects.push( objMesh );
// call for another image here
//textures/50219063/low
// console.log("onDocumentMouseDown call to obj loader second object")
// objLoaderFunction(loader, textureMap1)
texture = textureLoader.load( 'models/obj/52329571/mid/diffuse_2048.png' );
loader.load( 'models/obj/52329571/mid/52329571_mid.obj', function ( obj ) {
object = obj;
object.traverse( function ( child ) {
if ( child.isMesh ) {
child.material.map = texture;
}
} );
// object.position.y = 20;
object.scale.set(2.54, 2.54, 2.54);
object.position.copy( intersect.point ).add( intersect.face.normal );
// objects.push( object );
obj3d.add(object)
// scene.add(object)
animate();
}, manager.onProgress, manager.onError );
}
}
}
//
function animate() {
// requestAnimationFrame(animate)
// controls.update();
composer.render();
}
function render() {
// for looking at the center
// camera.position.x += ( mouseX - camera.position.x ) * .05;
// camera.position.y += ( - mouseY - camera.position.y ) * .05;
// camera.lookAt( scene.position );
// pick(pickPosition, scene, camera);
renderer.render( scene, camera );
}
function addSelectedObject( object ) {
selectedObjects = [];
selectedObjects.push( object );
}
function pick(normalizedPosition, scene, camera) {
// restore the color if there is a picked object
if (pickedObject) {
// pickedObject.material.emissive.setHex(pickedObjectSavedColor);
pickedObject = undefined;
}
// cast a ray through the frustum
raycaster.setFromCamera(normalizedPosition, camera);
// get the list of objects the ray intersected
const intersectedObjects = raycaster.intersectObjects(scene.children);
if (intersectedObjects.length) {
// pick the first object. It's the closest one
pickedObject = intersectedObjects[0].object;
addSelectedObject( pickedObject );
outlinePass.selectedObjects = selectedObjects;;
// save its color
// pickedObjectSavedColor = pickedObject.material.emissive.getHex();
// set its emissive color to flashing red/yellow
// pickedObject.material.emissive.setHex((time * 8) % 2 > 1 ? 0xFFFF00 : 0xFF0000);
}
}
</script>
</body>
</html>
预期结果: 每当我的鼠标放在某个对象上时,该对象应突出显示,否则保持不突出状态
实际结果: 一旦将对象加载到场景中,该模型的轮廓就会显示出来,但是当我移到场景中的其他对象时,什么也没发生