Intersecting Objects - Shadow Problem - Three.js - three.js

When I have intersecting objects there is a weird line of light in the shadow where the objects intersect. I’ve tried different types of lights, materials, browsers (MacOS), and render settings. It occurs with one or more lights.
I found that adjusting the shadow bias (spotLight.shadow.bias = 0.0005) and using a relatively large shadowmap helped reduce the lines but did not get rid of them entirely. I'm guessing that this is issue relates to how the shadowmap is rendered.
Does anyone have any ideas for what is causing this, and how to solve it?
Example image showing lines of light in shadow on intersecting objects - Demo code: https://codepen.io/henryegloff/pen/eYyRJpx
import * as THREE from 'three';
import { OrbitControls } from 'https://unpkg.com/three#0.139.0/examples/jsm/controls/OrbitControls.js';
let scene, camera, renderer, controls;
let cube_mesh;
init();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
camera = new THREE.PerspectiveCamera(25, window.innerWidth / window.innerHeight, 0.1,1000);
camera.position.set(0,1.5,-10);
renderer = new THREE.WebGLRenderer({ antialias:true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
//renderer.shadowMap.type = THREE.PCFShadowMap;
renderer.setAnimationLoop( animation );
renderer.toneMapping = THREE.LinearToneMapping;
renderer.physicallyCorrectLights = true;
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize);
controls = new OrbitControls(camera, renderer.domElement);
controls.target = new THREE.Vector3(0, 1, 0);
// Spotlight
const spotLight = new THREE.SpotLight( 0xffffff, 11 );
spotLight.position.set( 2, 4, -2 );
spotLight.castShadow = true;
// spotLight.shadow.bias = 0.0005;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.angle = 0.6;
spotLight.penumbra = 1;
// spotLight.decay = 1;
// const spotLightHelper = new THREE.SpotLightHelper( spotLight );
// scene.add( spotLightHelper );
scene.add( spotLight );
// Materials
const material_1 = new THREE.MeshPhongMaterial({color: 0xffffff,});
const material_2 = new THREE.MeshPhongMaterial({color: 0xbbbbbb,});
// Ground Plane
const ground_geometry = new THREE.PlaneGeometry(20, 20);
const ground_mesh = new THREE.Mesh(ground_geometry, material_2);
ground_mesh.receiveShadow = true;
ground_mesh.rotateX(-Math.PI / 2);
scene.add(ground_mesh);
// Cube
const cube_geometry = new THREE.BoxGeometry(1, 1, 1);
cube_mesh = new THREE.Mesh(cube_geometry, material_1);
cube_mesh.castShadow = true;
cube_mesh.position.y = 2;
scene.add(cube_mesh);
// Sphere
const sphere_geometry = new THREE.SphereGeometry( .75, 128,128 );
const sphere = new THREE.Mesh( sphere_geometry, material_1 );
sphere.castShadow = true;
sphere.receiveShadow = true;
sphere.position.set(0,.75,0);
scene.add( sphere );
const sphere_2_geometry = new THREE.SphereGeometry( 1, 128, 128 );
const sphere_2 = new THREE.Mesh( sphere_2_geometry, material_1 );
sphere_2.castShadow = true;
sphere_2.receiveShadow = true;
sphere_2.position.set(-1,1.5,1);
scene.add( sphere_2 );
}
function animation(time) {
cube_mesh.rotation.x += 0.01;
cube_mesh.rotation.y += 0.01;
controls.update();
renderer.render(scene, camera);
}
// Resize Window
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}

Related

The DOM element created by CSS3DObject cannot be obscured by the GL plane

I found that it seems to be solved by setting the blending attribute of material, but it still cannot be solved after trying.
Incorrect occlusion
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader.js"
import {
CSS3DRenderer,
CSS3DObject
} from "three/examples/jsm/renderers/CSS3DRenderer.js"
import dat from "dat.gui"
function initThree() {
const scene = new THREE.Scene();
const scene2 = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
50,
window.innerWidth / window.innerHeight,
0.1,
10000
);
camera.position.set(0, 0, 2500);
scene.add(camera);
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
});
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
document.querySelector('#webgl').appendChild(renderer.domElement);
const labelRenderer = new CSS3DRenderer()
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
document.body.appendChild(labelRenderer.domElement);
scene.add(new THREE.AxesHelper(1000))
const controls = new OrbitControls(camera, labelRenderer.domElement);
controls.enableDamping = true;
const clock = new THREE.Clock()
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
labelRenderer.setSize(window.innerWidth, window.innerHeight);
});
return {
scene,
scene2,
camera,
renderer,
labelRenderer,
controls,
clock,
}
}
const gltfLoader = new GLTFLoader()
const textureLoader = new THREE.TextureLoader()
const gui = new dat.GUI()
const {
scene,
scene2,
camera,
renderer,
labelRenderer,
controls,
clock
} = initThree();
const ambientLight = new THREE.AmbientLight("#ffffff", 1)
scene.add(ambientLight)
const position = new THREE.Vector3(0, 900, 300);
const rotation = new THREE.Euler(0, 0, 0);
const container = document.createElement('div');
container.style.width = '1000px';
container.style.height = '1000px';
container.style.opacity = '1';
container.style.background = '#1d2e2f';
const iframe = document.createElement('iframe');
iframe.src = "http://csyedu.top"
iframe.style.width = "1000px"
iframe.style.height = "1000px"
iframe.style.padding = 10 + 'px';
iframe.style.boxSizing = 'border-box';
iframe.style.opacity = '1';
container.appendChild(iframe);
const object = new CSS3DObject(container);
// copy monitor position and rotation
object.position.copy(position);
object.rotation.copy(rotation);
// Add to CSS scene
scene2.add(object);
// Create GL plane
const material = new THREE.MeshLambertMaterial();
material.side = THREE.DoubleSide;
material.opacity = 0;
material.transparent = true;
// NoBlending allows the GL plane to occlude the CSS plane
material.blending = THREE.NoBlending;
// Create plane geometry
const geometry = new THREE.PlaneGeometry(1000, 1000);
// Create the GL plane mesh
const mesh = new THREE.Mesh(geometry, material);
// Copy the position, rotation and scale of the CSS plane to the GL plane
mesh.position.copy(object.position);
mesh.rotation.copy(object.rotation);
mesh.scale.copy(object.scale);
// Add to gl scene
scene.add(mesh);
gltfLoader.load("./models/computer_setup.glb", model => {
const texture = textureLoader.load("./models/baked_computer.jpg");
texture.flipY = false;
texture.encoding = THREE.sRGBEncoding;
const material = new THREE.MeshBasicMaterial({
map: texture,
});
model.scene.traverse((child) => {
if (child instanceof THREE.Mesh) {
child.scale.set(900, 900, 900);
child.material.map = texture;
child.material = material;
}
});
scene.add(model.scene)
})
function render() {
const elapsedTime = clock.getElapsedTime();
controls.update();
renderer.render(scene, camera);
labelRenderer.render(scene2, camera)
requestAnimationFrame(render);
}
render();
The effect I want is that the 3D mesh can correctly occlude the CSS3DObject.
I runned over the same problem, I'm trying your code and works good on my project, I think you have a styling problem.
I have separated the WebGL and CSS3DRenderer on the html.
<body>
<div id="css"></div>
<div id="webgl"></div>
</body>
#css,
#webgl
{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
If I only put the #css on absolute this is the result
If I put both in absolute it works fine.
I wish that'll help

Three.JS VRAM memory leak when adding removing THREE.Geometry to scene

I have encountered a VRAM memory leak in my app.
The app adds and removes THREE.Geometry very often to create a volumetric animation.
If instead of a THREE.Geometry with it's own populated vertices, I used instead THREE.SphereBufferGeometry, the memory leak doesn't happen.
I have created a minimal app to prove this memory leak is real.
The memory leak increase VRAM memory very slowly, but it does fill up in the end.
I think that pools won't help, since it's VRAM and not managed memory.
I do use dispose.
If you can make this sample work and not have memory leak, that might solve my issue:
https://jsfiddle.net/4a7ksryd/16/
Edit: I am adding here the code of the app:
var camera, scene, renderer;
var geometry, material, mesh;
var lastSphere;
var lastGeo;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
var light = new THREE.DirectionalLight( 0xffffff, 1, 100 );
light.position.set( 0, 4, 0 ); //default; light shining from top
light.castShadow = true; // default false
//Set up shadow properties for the light
light.shadow.mapSize.width = 1024; // default
light.shadow.mapSize.height = 1024; // default
light.shadow.camera.near = 1; // default
light.shadow.camera.far = 20; // default
scene.add( light );
//Create a sphere that cast shadows (but does not receive them)
geometry = new THREE.SphereBufferGeometry( 0.1, 32, 32 );
material = new THREE.MeshStandardMaterial( { color: 0xff0000 } );
// geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
// material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
mesh.position.y = 0.1;
mesh.castShadows = true;
mesh.receiveShadow = false;
scene.add( mesh );
var planeGeometry = new THREE.PlaneBufferGeometry( 15, 15, 1, 1 );
var planeMaterial = new THREE.MeshStandardMaterial( { color: 0xffffff, emissive:0x111111 } )
var plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.position.y = -0.2;
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add( plane );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
var dim = 32;
var geo1 = new THREE.Geometry();
const numVertices = dim*dim;
var vertices = new Array(numVertices);
for (var i=0; i<vertices.length; i++)
{
const x = i%dim;
const y = (Math.floor(i/dim))%dim;
vertices[i] = new THREE.Vector3(x*0.1, y*0.1, 0);
}
const numFaces = (dim-1)*(dim-1)*2;
var faces = new Array(numFaces);
for (var i=0; i<(faces.length/2); i++)
{
const x = i%(dim-1);
const y = Math.floor(i/(dim-1))%(dim-1);
faces[2*i] = new THREE.Face3(x+y*dim, x+1+y*dim, x+(y+1)*dim);
faces[2*i+1] = new THREE.Face3(x+1+y*dim, x+1+(y+1)*dim, x+(y+1)*dim);
}
var uv = new Array(numFaces);
for (var i=0; i<uv.length; i++)
uv[i] = [new THREE.Vector2(0, 0), new THREE.Vector2(0, 0), new THREE.Vector2(0, 0)];
geo1.faces = faces;
geo1.vertices = vertices;
geo1.faceVertexUvs[0] = uv;
geo1.uvsNeedUpdate = true;
geo1.verticesNeedUpdate = true;
geo1.elementsNeedUpdate = true;
// var sphereGeometry = new THREE.SphereBufferGeometry( 0.1, 256, 256 );
var sphereGeometry = geo1;
var sphereMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
sphere.position.y = 0.1+Math.sin(mesh.rotation.x)*0.1;
sphere.position.x = 0.5;
sphere.castShadow = true; //default is false
sphere.receiveShadow = false; //default
if (lastGeo!=null)
lastGeo.dispose();
if (lastSphere!=null)
scene.remove(lastSphere);
scene.add( sphere );
lastSphere = sphere;
lastGeo = sphereGeometry;
// geo1.dispose();
renderer.render( scene, camera );
}
This is actually a bug in three.js. I've filed a PR to fix the issue:
https://github.com/mrdoob/three.js/pull/20479

overlapping semitransparent objects are not rendered as expected

I have two overlapping semitransparent boxes and I'd expect to see both of them independent of the viewing angle. The first image shows a rendering from aside and the small box is visible within the bigger box. The second image shows the same scene but form another viewing angle. As you can see, the smaller box is visible but the part which is with the bigger box is invisible. What am I missing?
var camera, scene, renderer;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50);
camera.position.set(2, 2, 2);
camera.lookAt(new THREE.Vector3(0.0, 0.0, 0.0));
// Create scene.
scene = new THREE.Scene();
// Create material
var material = new THREE.MeshStandardMaterial();
material.transparent = true;
material.opacity = 0.5;
// Create cube and add to scene.
var geometry1 = new THREE.BoxGeometry(1, 1, 1);
var mesh1 = new THREE.Mesh(geometry1, material);
mesh1.position.set(0, 0, 0);
//mesh1.castShadow = true;
scene.add(mesh1);
// Create cube and add to scene.
var geometry2 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var mesh2 = new THREE.Mesh(geometry2, material);
mesh2.position.set(0.0, 0, 0.5);
//mesh2.castShadow = true;
scene.add(mesh2);
var spotLight = new THREE.SpotLight(0xffffff, 0.32);
spotLight.position.set(0, 5, 0);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.near = 0.1;
spotLight.shadow.camera.far = 20;
scene.add(spotLight);
let hemiLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.8);
scene.add(hemiLight);
// Ground plane
var groundGeo = new THREE.PlaneBufferGeometry(50, 50);
var groundMat = new THREE.MeshStandardMaterial({color: 0xffffff});
var ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -0.5;
ground.receiveShadow = true;
scene.add(ground);
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
let controls = new THREE.OrbitControls(camera);
controls.enableZoom = true;
controls.enablePan = false;
controls.maxDistance = 20.0;
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 2;
controls.target.set(0, 0, 0);
controls.update();
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
body {
padding: 0;
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Transparent objects in WebGL are sometimes rather problematic. It's all about the rendering order: If the small cube is rendered after the large cube, how should the rendering behave? This question has some information you might find useful.
In your particular case (though not necessarily always), one solution could be to disable renderer object sorting:
renderer.sortObjects = false;
and(!) make sure you add your objects in the correct order, i.e. the small cube first and the large one second. Here is an updated version of your snippet:
var camera, scene, renderer;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.sortObjects = false;
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 50);
camera.position.set(2, 2, 2);
camera.lookAt(new THREE.Vector3(0.0, 0.0, 0.0));
// Create scene.
scene = new THREE.Scene();
// Create material
var material = new THREE.MeshStandardMaterial();
material.transparent = true;
material.opacity = 0.5;
// Create cube and add to scene.
var geometry2 = new THREE.BoxGeometry(0.5, 0.5, 0.5);
var mesh2 = new THREE.Mesh(geometry2, material);
mesh2.position.set(0.0, 0, 0.5);
//mesh2.castShadow = true;
scene.add(mesh2);
// Create cube and add to scene.
var geometry1 = new THREE.BoxGeometry(1, 1, 1);
var mesh1 = new THREE.Mesh(geometry1, material);
mesh1.position.set(0, 0, 0);
//mesh1.castShadow = true;
scene.add(mesh1);
var spotLight = new THREE.SpotLight(0xffffff, 0.32);
spotLight.position.set(0, 5, 0);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.near = 0.1;
spotLight.shadow.camera.far = 20;
scene.add(spotLight);
let hemiLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.8);
scene.add(hemiLight);
// Ground plane
var groundGeo = new THREE.PlaneBufferGeometry(50, 50);
var groundMat = new THREE.MeshStandardMaterial({color: 0xffffff});
var ground = new THREE.Mesh(groundGeo, groundMat);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -0.5;
ground.receiveShadow = true;
scene.add(ground);
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
let controls = new THREE.OrbitControls(camera);
controls.enableZoom = true;
controls.enablePan = false;
controls.maxDistance = 20.0;
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 2;
controls.target.set(0, 0, 0);
controls.update();
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
body {
padding: 0;
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

three.js outline does not work when scene set `scene.background=texture`

I caeate outline according to this example https://threejs.org/examples/?q=out#webgl_postprocessing_outline.And this is the result.It is works well.But when i set scene.background=texture,it is not work.IAnd i check the three.js document about scene.background. (If not null, sets the background used when rendering the scene, and is always rendered first. Can be set to a Color which sets the clear color, a Texture covering the canvas, or a CubeTexture. Default is null).I want to find out why outline disappear.Here is the code.
var scene, camera, renderer;
var light, floor;
var WIDTH,HEIGHT;
var controls;
var composer;
var composer, effectFXAA, outlinePass;
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight;
init();
animation()
function init () {
scene = new THREE.Scene();
var textureLoader = new THREE.TextureLoader();
textureLoader.load('img/bg.png', function(texture){
scene.background = texture;
});
camera = new THREE.PerspectiveCamera(45, WIDTH/HEIGHT, 0.1, 800);
camera.position.set(0,150,150);
scene.add(camera);
scene.add(new THREE.AmbientLight(0xffffff));
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(WIDTH, HEIGHT);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
controls = new OrbitControls(camera);
var shape = new THREE.Shape();
shape.moveTo(0,4);
shape.lineTo(0,96);
shape.lineTo(4,100);
shape.lineTo(96,100);
shape.lineTo(100,96);
shape.lineTo(100,4);
shape.lineTo(96, 0 );
shape.lineTo(84,0);
shape.lineTo(80,4);
shape.lineTo(20, 4);
shape.lineTo(16, 0);
shape.lineTo(4, 0 );
shape.lineTo(0, 4);
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
var material = new THREE.MeshLambertMaterial( { color: 0x0E2350 } );
mesh = new THREE.Mesh( geometry, material ) ;
mesh.rotation.x = -Math.PI/2;
mesh.translateX(-50);
mesh.translateY(-50);
scene.add(mesh);
composer = new THREE.EffectComposer( renderer );
var renderPass = new THREE.RenderPass( scene, camera );
composer.addPass( renderPass );
outlinePass = new THREE.OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), scene, camera );
outlinePass.edgeStrength = 3;
outlinePass.edgeGlow = 3.0;
outlinePass.edgeThickness = 0.1;
outlinePass.visibleEdgeColor.setHex(0x19C0EE);
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 );
outlinePass.selectedObjects = [mesh];
}
function animation() {
requestAnimationFrame(animation);
composer.render();
render();
controls.update();
};
function render () {
renderer.render(scene, camera)
};

Three.js ray object intersection

friends.
Here is my code. It should find intersection of ray and cube. But it does not work and makes me mad. This code is quite simple, but it is hard for me to find the error. Please, help.
jsFiddle
<script>
var container;
var camera, controls, scene, renderer;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000;
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render );
// world
scene = new THREE.Scene();
var testObject_G = new THREE.CubeGeometry(100, 100, 100);
var testObject_M = new THREE.MeshBasicMaterial({ color: 0xBBBBBB });
var testObject_Mesh = new THREE.Mesh(testObject_G, testObject_M);
testObject_Mesh.position.x = 300;
scene.add(testObject_Mesh);
scene2 = new THREE.Object3D();
// rays
var direction = new THREE.Vector3(1, 0, 0);
direction.normalize();
var startPoint = new THREE.Vector3(0, 0, 0);
var ray = new THREE.Raycaster(startPoint, direction);
var rayIntersects = ray.intersectObjects(scene.children, true);
if (rayIntersects[0]) {
console.log(rayIntersects[0]);
var geometry = new THREE.CubeGeometry(10, 10, 10);
var material = new THREE.MeshBasicMaterial({color: 0xff0000});
var cube = new THREE.Mesh(geometry, material);
cube.position = rayIntersects[0].point;
scene2.add(cube);
}
var ray_G = new THREE.Geometry();
ray_G.vertices.push(new THREE.Vector3(0, 0, 0));
ray_G.vertices.push(direction.multiplyScalar(1000));
var ray_M = new THREE.LineBasicMaterial({ color: 0x000000 });
var ray_Mesh = new THREE.Line(ray_G, ray_M);
scene2.add(ray_Mesh);
scene.add(scene2);
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor(0xffffff, 1);
container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
render();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
Thank you very much for replies.
During the render loop, three.js updates each object's transform matrix for you, based on your specified object.position, object.rotation/quaternion, and object.scale.
Since you are calling Raycaster.intersectObjects() before the first render call, you have to update the object matrices yourself prior to raycasting.
scene.updateMatrixWorld();
fiddle: http://jsfiddle.net/mzRtJ/5/
three.js r.64

Resources