Three.js Restrict the mouse movement to Scene only - three.js

I am working on the cube example from three.js (webgl_interactive_cubes_gpu.html). I realized that events goes to the entire html page. I mean i can rotate, zoom in or zoom out, even if the mouse pointer is not inside the scene..
I google a little bit and found some answers (Allow mouse control of three.js scene only when mouse is over canvas) but they do not work for me..Below is my code...
var container, stats;
var camera, controls, scene, renderer;
var pickingData = [], pickingTexture, pickingScene;
var objects = [];
var highlightBox;
var mouse = new THREE.Vector2();
var offset = new THREE.Vector3( 10, 10, 10 );
init();
animate();
function init() {
container = document.getElementById( "container" );
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000;
//camera.translateZ( -500 );
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 4;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
scene = new THREE.Scene();
pickingScene = new THREE.Scene();
pickingTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight );
pickingTexture.minFilter = THREE.LinearFilter;
pickingTexture.generateMipmaps = false;
scene.add( new THREE.AmbientLight( 0x555555 ));
var light = new THREE.SpotLight( 0xffffff, 1.5 );
light.position.set( 0, 500, 2000 );
scene.add( light );
var geometry = new THREE.Geometry(),
pickingGeometry = new THREE.Geometry(),
pickingMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ),
defaultMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors} );
function applyVertexColors( g, c ) {
g.faces.forEach( function( f ) {
var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
for( var j = 0; j < n; j ++ ) {
f.vertexColors[ j ] = c;
}
} );
}
var geom = new THREE.BoxGeometry(0.005, 0.005, 0.005 );
var color = new THREE.Color();
var matrix = new THREE.Matrix4();
var quaternion = new THREE.Quaternion();
var coord="219_163_189;130_173_179;161_113_231;
var splitCoord=coord.split(";");
var coordColr="0_255_255;255_255_0;0_0_255;0_255_0;255_255_0;
var splitCoordColor=coordColr.split(";");
for ( var i = 0; i < splitCoord.length; i++ ) {
var position = new THREE.Vector3();
var xyz=splitCoord[i].split("_");
var col=splitCoordColor[i].split("_");
position.x = xyz[0];
position.y = xyz[1];
position.z = xyz[2];
var rotation = new THREE.Euler();
rotation.x = 0
rotation.y = 0;
rotation.z = 0;
var scale = new THREE.Vector3();
scale.x = 200 + 100;
scale.y = 200 + 100;
scale.z = 200 + 100;
quaternion.setFromEuler(rotation, false );
matrix.compose( position, quaternion, scale);
col[0]=col[0]/255;
col[1]=col[1]/255;
col[2]=col[2]/255;
applyVertexColors(geom, color.setRGB(col[0], col[1], col[2]));
geometry.merge(geom, matrix);
// give the geom's vertices a color corresponding to the "id"
applyVertexColors( geom, color.setHex( i ) );
pickingGeometry.merge( geom, matrix );
pickingData[ i ] = {
position: position,
rotation: rotation,
scale: scale
};
}
var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
scene.add(drawnObject);
pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );
highlightBox = new THREE.Mesh(
new THREE.BoxGeometry( 0.01, 0.01, 0.01 ),
new THREE.MeshLambertMaterial( { color: 0xffff00 }
) );
scene.add( highlightBox );
renderer = new THREE.WebGLRenderer( );
//renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(800, 800);
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
//renderer.domElement.addEventListener('mousemove', onMouseMove );
}
function onMouseMove( e ) {
mouse.x = e.clientX;
mouse.y = e.clientY;
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function pick() {
//render the picking scene off-screen
renderer.render( pickingScene, camera, pickingTexture );
//create buffer for reading single pixel
var pixelBuffer = new Uint8Array( 4 );
//read the pixel under the mouse from the texture
renderer.readRenderTargetPixels(pickingTexture, mouse.x, pickingTexture.height - mouse.y, 1, 1, pixelBuffer);
//interpret the pixel as an ID
var id = ( pixelBuffer[0] << 16 ) | ( pixelBuffer[1] << 8 ) | ( pixelBuffer[2] );
var data = pickingData[ id ];
if (data) {
//move our highlightBox so that it surrounds the picked object
if ( data.position && data.rotation && data.scale ){
highlightBox.position.copy( data.position );
highlightBox.rotation.copy( data.rotation );
highlightBox.scale.copy( data.scale ).add( offset );
highlightBox.visible = true;
}
} else {
highlightBox.visible = false;
}
}
function render() {
controls.update();
pick();
renderer.render( scene, camera );
}
any help is greatly appreciated..
Thanks

You can pass in the canvas as an argument to the TrackballsControls constructor.
var controls = new THREE.TrackballControls(camera, renderer.domElement);
That should solve the problem.
EDIT: included a working example,
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, 400 / 300, 1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(400, 300);
document.body.appendChild(renderer.domElement);
var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 4;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
var render = function() {
requestAnimationFrame(render);
controls.update();
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
could not get your code to run at all so..

Related

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

Three.js moving the camera left and right side of the scene

I am working on a three.js prototype in which a 3d model of the train is added to the scene. My requirement is to move the camera either left / right side of the scene to view the complete train.
I tried using below code -
function onKeyDown(){
var zdelta = 20;
switch( event.keyCode ) {
case 65: // look left
camera.position.z = camera.position.z + zdelta;
}
}
But the scene was rotating rather than panning in the left side.
So it will be great help, if anyone shares their idea on this :)
Thanks,
Satheesh K
Using a keydown event listener is definitely the right approach. Try it with this code:
var scene, camera, renderer, cubeObj;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400;
camera.position.y = - 10;
camera.position.x = 10;
var cubeGeo = new THREE.BoxGeometry( 200, 150, 100 );
var cubeGeoMaterial = new THREE.MeshPhongMaterial( { color: 0x808080 } );
cubeObj = new THREE.Mesh( cubeGeo, cubeGeoMaterial );
cubeObj.position.x = - 70;
cubeObj.position.y = - 50;
cubeObj.position.z = 0;
cubeObj.rotation.x = 0.5;
scene.add( cubeObj );
var cubeGeo2 = new THREE.BoxGeometry( 200, 150, 100 );
var cubeGeoMaterial2 = new THREE.MeshPhongMaterial( { color: 0x808080 } );
var cubeObj2 = new THREE.Mesh( cubeGeo2, cubeGeoMaterial2 );
cubeObj2.position.x = 160;
cubeObj2.position.y = - 50;
cubeObj2.position.z = - 5;
cubeObj2.rotation.x = 0.5;
scene.add( cubeObj2 );
var cubeGeo3 = new THREE.BoxGeometry( 200, 150, 100 );
var cubeGeoMaterial3 = new THREE.MeshPhongMaterial( { color: 0x808080 } );
var cubeObj3 = new THREE.Mesh( cubeGeo3, cubeGeoMaterial3 );
cubeObj3.position.x = 440;
cubeObj3.position.y = - 50;
cubeObj3.position.z = 0;
cubeObj3.rotation.x = 0.5;
scene.add( cubeObj3 );
renderer = new THREE.WebGLRenderer( {
antialias: true
} );
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 100, 1000, 100 );
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.camera.near = 500;
spotLight.shadow.camera.far = 4000;
spotLight.shadow.camera.fov = 30;
//scene.add( spotLight );
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
scene.add( directionalLight );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xcce0ff );
document.body.appendChild( renderer.domElement );
document.addEventListener( 'keydown', onKeyDown, false );
}
function onKeyDown( event ) {
const step = 5; // world units
switch ( event.keyCode ) {
case 37:
camera.position.x -= step;
break;
case 39:
camera.position.x += step;
break;
}
}
function animate() {
renderer.render( scene, camera );
requestAnimationFrame( animate );
}
body {
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.114/build/three.js"></script>

Three.js : remove texture on top/bottom of CylinderGeometry

I'm using Three.js to make basic 3D cylinder rendering. I'm using TextureLoader to load texture async (based on UI interactions).
All is ok, but I would like those textures not to be applied on the cylinder top / bottom.
How can I achieve that?
Here's what I've done so far:
function threeJsRenderer() {
var width = 325;
var height = 375;
var scene = new THREE.Scene();
var camera = new THREE.OrthographicCamera(width / - 2, width / 2, height / 2, height / - 2, -200, 1000);
var renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setClearColor( 0x000000, 0 );
renderer.setSize(width,height);
document.getElementById('projection').appendChild(renderer.domElement);
// CylinderGeometry(radiusTop : Float, radiusBottom : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float)
var geometry = new THREE.CylinderGeometry(135,128,110,64,1, false, 0, Math.PI-2);
var loader = new THREE.TextureLoader();
var material = new THREE.MeshPhongMaterial();
var cone = new THREE.Mesh();
var pointLight = new THREE.AmbientLight( 0xFFFFFF );
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
scene.add(pointLight);
camera.position.z = 40;
camera.position.y = 0;
cone.rotation.x = 0.01;
cone.rotation.y = -10;
jQuery(document).on('new3DConfigReady', function () {
scene.remove(cone);
var newGeometry = new THREE.CylinderGeometry(state.cylinderGeometry.radiusTop,state.cylinderGeometry.radiusBottom,state.cylinderGeometry.height,64,1, false, 0, Math.PI-2);;
cone = new THREE.Mesh(newGeometry, material);
cone.rotation.x = 0.01;
cone.rotation.y = -0.55;
cone.position.y = state.cylinderGeometry.positionY;
geometry.dispose();
if(state.textureUrl !== ''){
scene.add(cone);
}
});
jQuery(document).on('newTextureReady', function () {
loader.load( state.textureUrl, function (texture){
material.map = texture;
material.map.anisotropy = 256;
material.map.needsUpdate = true;
material.needsUpdate = true;
scene.add(cone);
});
});
var render = function () {
requestAnimationFrame(render);
renderer.render(scene, camera);
};
render();
}
Using a materials array you can have different materials on the sides and ends of your cylinder.
var geometry = new THREE.CylinderBufferGeometry( 5, 5, 10, 16, 1 );
var materials = [
new THREE.MeshPhongMaterial( { map: texture } ),
new THREE.MeshPhongMaterial( { color: 0x0000ff } ),
new THREE.MeshPhongMaterial( { color: 0xff0000 } )
];
var mesh = new THREE.Mesh( geometry, materials );
three.js r.100

Adding image in the script code "Bad TV Shader"?

I want to be able to add images in the script code "Bad TV Shader" (https://www.airtightinteractive.com/demos/js/badtvshader/). It was originally developed for video, but I want to implement an image that also is under these distortion and noise effects.
Who can help I would be very grateful! =)
<script>
//Bad TV Effect Demo
//Using Three.js r.66
//by Felix Turner / www.airtight.cc / #felixturner
var camera, scene, renderer;
var video, videoTexture,videoMaterial;
var composer;
var shaderTime = 0;
var badTVParams, badTVPass;
var staticParams, staticPass;
var rgbParams, rgbPass;
var filmParams, filmPass;
var renderPass, copyPass;
var gui;
var pnoise, globalParams;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(55, 1080/ 720, 20, 3000);
camera.position.z = 1000;
scene = new THREE.Scene();
//Load Video
video = document.createElement( 'video' );
video.loop = true;
video.src = "res/fits.mp4";
video.play();
//Use webcam
// video = document.createElement('video');
// video.width = 320;
// video.height = 240;
// video.autoplay = true;
// video.loop = true;
// //Webcam video
// window.URL = window.URL || window.webkitURL;
// navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
// //get webcam
// navigator.getUserMedia({
// video: true
// }, function(stream) {
// //on webcam enabled
// video.src = window.URL.createObjectURL(stream);
// }, function(error) {
// prompt.innerHTML = 'Unable to capture WebCam. Please reload the page.';
// });
//init video texture
videoTexture = new THREE.Texture( video );
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
videoMaterial = new THREE.MeshBasicMaterial( {
map: videoTexture
} );
//Add video plane
var planeGeometry = new THREE.PlaneGeometry( 1080, 720,1,1 );
var plane = new THREE.Mesh( planeGeometry, videoMaterial );
scene.add( plane );
plane.z = 0;
plane.scale.x = plane.scale.y = 1.45;
//add stats
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
//init renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( 800, 600 );
document.body.appendChild( renderer.domElement );
//POST PROCESSING
//Create Shader Passes
renderPass = new THREE.RenderPass( scene, camera );
badTVPass = new THREE.ShaderPass( THREE.BadTVShader );
rgbPass = new THREE.ShaderPass( THREE.RGBShiftShader );
filmPass = new THREE.ShaderPass( THREE.FilmShader );
staticPass = new THREE.ShaderPass( THREE.StaticShader );
copyPass = new THREE.ShaderPass( THREE.CopyShader );
//set shader uniforms
filmPass.uniforms[ "grayscale" ].value = 0;
//Init DAT GUI control panel
badTVParams = {
mute:true,
show: true,
distortion: 3.0,
distortion2: 1.0,
speed: 0.3,
rollSpeed: 0.1
}
staticParams = {
show: true,
amount:0.5,
size2:4.0
}
rgbParams = {
show: true,
amount: 0.005,
angle: 0.0,
}
filmParams = {
show: true,
count: 800,
sIntensity: 0.9,
nIntensity: 0.4
}
gui = new dat.GUI();
gui.add(badTVParams, 'mute').onChange(onToggleMute);
var f1 = gui.addFolder('Bad TV');
f1.add(badTVParams, 'show').onChange(onToggleShaders);
f1.add(badTVParams, 'distortion', 0.1, 20).step(0.1).listen().name("Thick Distort").onChange(onParamsChange);
f1.add(badTVParams, 'distortion2', 0.1, 20).step(0.1).listen().name("Fine Distort").onChange(onParamsChange);
f1.add(badTVParams, 'speed', 0.0,1.0).step(0.01).listen().name("Distort Speed").onChange(onParamsChange);
f1.add(badTVParams, 'rollSpeed', 0.0,1.0).step(0.01).listen().name("Roll Speed").onChange(onParamsChange);
f1.open();
var f2 = gui.addFolder('RGB Shift');
f2.add(rgbParams, 'show').onChange(onToggleShaders);
f2.add(rgbParams, 'amount', 0.0, 0.1).listen().onChange(onParamsChange);
f2.add(rgbParams, 'angle', 0.0, 2.0).listen().onChange(onParamsChange);
f2.open();
var f4 = gui.addFolder('Static');
f4.add(staticParams, 'show').onChange(onToggleShaders);
f4.add(staticParams, 'amount', 0.0,1.0).step(0.01).listen().onChange(onParamsChange);
f4.add(staticParams, 'size2', 1.0,100.0).step(1.0).onChange(onParamsChange);
f4.open();
var f3 = gui.addFolder('Scanlines');
f3.add(filmParams, 'show').onChange(onToggleShaders);
f3.add(filmParams, 'count', 50, 1000).onChange(onParamsChange);
f3.add(filmParams, 'sIntensity', 0.0, 2.0).step(0.1).onChange(onParamsChange);
f3.add(filmParams, 'nIntensity', 0.0, 2.0).step(0.1).onChange(onParamsChange);
f3.open();
gui.close();
onToggleShaders();
onToggleMute();
onParamsChange();
window.addEventListener('resize', onResize, false);
renderer.domElement.addEventListener('click', randomizeParams, false);
onResize();
randomizeParams();
}
function onParamsChange() {
//copy gui params into shader uniforms
badTVPass.uniforms[ "distortion" ].value = badTVParams.distortion;
badTVPass.uniforms[ "distortion2" ].value = badTVParams.distortion2;
badTVPass.uniforms[ "speed" ].value = badTVParams.speed;
badTVPass.uniforms[ "rollSpeed" ].value = badTVParams.rollSpeed;
staticPass.uniforms[ "amount" ].value = staticParams.amount;
staticPass.uniforms[ "size" ].value = staticParams.size2;
rgbPass.uniforms[ "angle" ].value = rgbParams.angle*Math.PI;
rgbPass.uniforms[ "amount" ].value = rgbParams.amount;
filmPass.uniforms[ "sCount" ].value = filmParams.count;
filmPass.uniforms[ "sIntensity" ].value = filmParams.sIntensity;
filmPass.uniforms[ "nIntensity" ].value = filmParams.nIntensity;
}
function randomizeParams() {
if (Math.random() <0.2){
//you fixed it!
badTVParams.distortion = 0.1;
badTVParams.distortion2 =0.1;
badTVParams.speed =0;
badTVParams.rollSpeed =0;
rgbParams.angle = 0;
rgbParams.amount = 0;
staticParams.amount = 0;
}else{
badTVParams.distortion = Math.random()*10+0.1;
badTVParams.distortion2 =Math.random()*10+0.1;
badTVParams.speed =Math.random()*.4;
badTVParams.rollSpeed =Math.random()*.2;
rgbParams.angle = Math.random()*2;
rgbParams.amount = Math.random()*0.03;
staticParams.amount = Math.random()*0.2;
}
onParamsChange();
}
function onToggleMute(){
video.volume = badTVParams.mute ? 0 : 1;
}
function onToggleShaders(){
//Add Shader Passes to Composer
//order is important
composer = new THREE.EffectComposer( renderer);
composer.addPass( renderPass );
if (filmParams.show){
composer.addPass( filmPass );
}
if (badTVParams.show){
composer.addPass( badTVPass );
}
if (rgbParams.show){
composer.addPass( rgbPass );
}
if (staticParams.show){
composer.addPass( staticPass );
}
composer.addPass( copyPass );
copyPass.renderToScreen = true;
}
function animate() {
shaderTime += 0.1;
badTVPass.uniforms[ 'time' ].value = shaderTime;
filmPass.uniforms[ 'time' ].value = shaderTime;
staticPass.uniforms[ 'time' ].value = shaderTime;
if ( video.readyState === video.HAVE_ENOUGH_DATA ) {
if ( videoTexture ) videoTexture.needsUpdate = true;
}
requestAnimationFrame( animate );
composer.render( 0.1);
stats.update();
}
function onResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
</script>
Using video or image is the same process, you can use Planegeometry and TextureLoader to place an image instead of a video like this :
YourGroup = new THREE.Group();
var YourImage = new THREE.TextureLoader();
YourImage.load( 'folder/to_image.png', function ( texture ) {
var geometry = new THREE.PlaneGeometry( width, height );
var material = new THREE.MeshBasicMaterial({
map: texture,
transparent: true,
});
var mesh = new THREE.Mesh( geometry, material );
YourGroup.add( mesh );
});
scene.add( YourGroup );
Note:
Here i created a group with everything to put inside (a planegeometry with BasicMaterial to apply my loaded image to Plane, and create a mesh from these two.
I put a Png instead of jpeg because of transparency for Mesh.
I add my group to scene.

raycast intersecting with all objects/objects are all the same?

As soon as you mouse over 1 box, all the boxes turn red.I added the go Boolean because otherwise the page would load with the boxes being red. Here is a jsfiddle link https://jsfiddle.net/mduffy/be8vm5vL/17/
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, document.getElementById("canvas").width / document.getElementById("canvas").height, 0.1, 1000 );
var x,y;
var image_spacing = 20;
var image_height = 90;
var image_width = 160;
var rows = 3;
var cols = 4;
var go = false;
var controls = new THREE.OrbitControls( camera );
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var renderer = new THREE.WebGLRenderer( { canvas: canvas } );
var geometry = new THREE.BoxGeometry( image_width, image_height, 0 );
var pictures = new THREE.Object3D();
pictures.position.x = -((cols / 2 * (image_width+image_spacing)) - 0.5*(image_spacing+image_width));
pictures.position.y = -((rows / 2 * (image_height+image_spacing)) - 0.5*(image_spacing+image_height));
var material = new THREE.MeshBasicMaterial();
for(var i = 0;i < rows;i++){
for(var e = 0;e < cols;e++){
var picture = new THREE.Mesh( geometry, material );
picture.position.set( (e*(image_spacing+image_width)), (i*(image_spacing+image_height)), 0 );
//picture.overdraw = true;
pictures.add( picture );
}
}
scene.add( pictures );
camera.position.z = 400;
function render() {
requestAnimationFrame( render );
if(go ){
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.children, true);
for ( var e = 0; e < intersects.length; e++ ) {
intersects[ e ].object.material.color.set( 0xff0000 );
}
}
controls.update();
renderer.render( scene, camera );
}
document.getElementById("canvas").addEventListener("mousemove", function(event){
var position = getMousePos(document.getElementById("canvas"),event);
x = position.x;
y = position.y;
mouse.x = ( x / 1000 ) * 2 - 1;
mouse.y = - ( y / 600 ) * 2 + 1;
});
document.getElementById("canvas").addEventListener("mouseenter", function(event){
go = true;
});
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
render();
Your objects are sharing the same material.
var picture = new THREE.Mesh( geometry, material );
Consequently, when you change the the material color for one object, you are changing the color of all the objects.
Instead, do this:
var picture = new THREE.Mesh( geometry, material.clone() );
three.js .r.71

Resources