(Three.js) bloom over not bloom issue - three.js

Can someone please a bit change the given example for solve the main issue?
It will help everyone to understand how to properly use scene.traverse and obj.material.dispose in a real simple example (because original example has a bit complex code for dive freely).
How bloom over not bloom should looks: bloomYes.png
But in example it is incorrect: bloomNot.png
Example to see and change
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth/ window.innerHeight, 1, 1000);
camera.position.set(20, 0, -20);
camera.layers.enable(1);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor( 0x000000 );
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.75);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));
// not bloomy
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshLambertMaterial({color: 0xf0f0f0, wireframe: false}));
obj.layers.set(0);
obj.position.z = 0;
scene.add(obj);
var obj = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 1), new THREE.MeshLambertMaterial({color: 0x0000ff, wireframe: false}));
obj.position.z = 2.5;
obj.layers.set(0);
scene.add(obj);
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshLambertMaterial({color: 0xf0f0f0, wireframe: false}));
obj.layers.set(0);
obj.position.z = 5;
scene.add(obj);
// bloomystuff
var objBloomRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objBloomRed.position.z = -2.25;
objBloomRed.layers.set(1);
scene.add(objBloomRed);
var objBloomGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objBloomGreen.position.z = 7.5;
objBloomGreen.layers.set(1);
scene.add(objBloomGreen);
// "fake" objects
var objRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objRed.position.z = -2.5;
objRed.layers.set(0);
scene.add(objRed);
var objGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objGreen.position.z = 7.5;
objGreen.layers.set(0);
scene.add(objGreen);
/** COMPOSER */
renderScene = new THREE.RenderPass( scene, camera )
effectFXAA = new THREE.ShaderPass( THREE.FXAAShader )
effectFXAA.uniforms.resolution.value.set( 1 / window.innerWidth, 1 / window.innerHeight )
bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 )
bloomPass.threshold = 0.21
bloomPass.strength = 1.2
bloomPass.radius = 0.55
bloomPass.renderToScreen = true
composer = new THREE.EffectComposer( renderer )
composer.setSize( window.innerWidth, window.innerHeight )
composer.addPass( renderScene )
composer.addPass( effectFXAA )
composer.addPass( bloomPass )
var delta = 0;
render();
function render(){
requestAnimationFrame(render);
delta += 0.05;
objBloomRed.material.color.g = Math.sin(delta);
objBloomRed.material.color.b = Math.cos(delta);
objRed.material.color.g = Math.sin(delta);
objRed.material.color.b = Math.cos(delta);
renderer.clear();
camera.layers.set(1);
composer.render();
renderer.clearDepth();
camera.layers.set(0);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src='https://threejs.org/examples/js/postprocessing/EffectComposer.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/RenderPass.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/ShaderPass.js'></script>
<script src='https://threejs.org/examples/js/shaders/CopyShader.js'></script>
<script src="https://threejs.org/examples/js/shaders/FXAAShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/UnrealBloomPass.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Thank you.

Ok, I am did it as soon as possible. Let all who want, know how to do it! Just look into code how it is possible to solve the "bloom over not-bloom" issue:
var ENTIRE_SCENE = 0, BLOOM_SCENE = 1;
var bloomLayer = new THREE.Layers();
bloomLayer.set( BLOOM_SCENE );
var darkMaterial = new THREE.MeshBasicMaterial( { color: "yellow" } );
var materials = {};
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth/ window.innerHeight, 1, 1000);
camera.position.set(20, 0, -20);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));
// setup scene
scene.traverse(disposeMaterial);
scene.children.length = 0;
// not bloomy
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshBasicMaterial({color: 0x444444, wireframe: false}));
obj.position.z = 0;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);
var obj = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 1), new THREE.MeshBasicMaterial({color: 0x0000ff, wireframe: false}));
obj.position.z = 2.5;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshBasicMaterial({color: 0x444444, wireframe: false}));
obj.position.z = 5;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);
// bloomystuff
var objBloomRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objBloomRed.position.z = -2.5;
objBloomRed.layers.enable(BLOOM_SCENE)
scene.add(objBloomRed);
var objBloomGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objBloomGreen.position.z = 7.5;
objBloomGreen.layers.enable(BLOOM_SCENE)
scene.add(objBloomGreen);
window.onresize = function () {
var width = window.innerWidth;
var height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
bloomComposer.setSize(width, height);
finalComposer.setSize(width, height);
render();
};
/** COMPOSER */
renderScene = new THREE.RenderPass( scene, camera )
bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 )
bloomPass.threshold = 0.21
bloomPass.strength = 1.2
bloomPass.radius = 0.55
bloomComposer = new THREE.EffectComposer( renderer )
bloomComposer.setSize( window.innerWidth, window.innerHeight )
bloomComposer.renderToScreen = false;
bloomComposer.addPass( renderScene );
bloomComposer.addPass( bloomPass );
var finalPass = new THREE.ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: {value: null},
bloomTexture: {value: bloomComposer.renderTarget2.texture}
},
vertexShader: vertexshader.textContent,
fragmentShader: fragmentshader.textContent,
defines: {}
}), "baseTexture"
);
finalPass.needsSwap = true;
var finalComposer = new THREE.EffectComposer(renderer);
finalComposer.addPass(renderScene);
finalComposer.addPass(finalPass);
function disposeMaterial(obj) {
if (obj.material) {
obj.material.dispose();
}
}
function renderBloom(mask) {
if (mask === true) {
bloomComposer.render();
} else {
camera.layers.set(BLOOM_SCENE);
bloomComposer.render();
camera.layers.set(ENTIRE_SCENE);
}
}
var delta = 0;
render();
function render(){
requestAnimationFrame(render);
delta += 0.05;
objBloomRed.material.color.g = Math.sin(delta);
objBloomRed.material.color.b = Math.cos(delta);
renderBloom(true);
finalComposer.render();
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src='https://threejs.org/examples/js/postprocessing/EffectComposer.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/RenderPass.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/ShaderPass.js'></script>
<script src='https://threejs.org/examples/js/shaders/CopyShader.js'></script>
<script src="https://threejs.org/examples/js/shaders/FXAAShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/UnrealBloomPass.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script type="x-shader/x-vertex" id="vertexshader">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
uniform sampler2D baseTexture;
uniform sampler2D bloomTexture;
varying vec2 vUv;
vec4 getTexture( sampler2D texelToLinearTexture ) {
return mapTexelToLinear( texture2D( texelToLinearTexture , vUv ) );
}
void main() {
gl_FragColor = ( getTexture( baseTexture ) + vec4( 1.0 ) * getTexture( bloomTexture ) );
}
</script>

Related

Creating Hole in object using ThreeJS and Stencil method

I am trying to make a hole in a solid object(box) using stencil method in ThreeJS. I found few web pages and similar questions on the net in this regard but couldn't work them out. Specifically This link is what I want to achieve(even one hole is enough). However the code in the link is using Babylon and I need it to be in ThreeJS. Any idea how I can use ThreeJS to achieve this(or to translate it to ThreeJS)?
Update 1:
There is a sample in ThreeJS examples "misc_exporter_ply.html"(it's got nothing to do with stencil buffer though) and so I tried to use it as it has a simple scene with only one box. I added another cylinder inside the box to represent the hole.
I could get it to work so that there is a visible hole. Yet it's not perfect as the stencil buffer is not working as expected:
Image 1
Image 2
And here is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - exporter - ply</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<div id="info">
three.js webgl - exporter - ply<br/><br/>
<button id="exportASCII">export ASCII</button> <button id="exportBinaryBigEndian">export binary (Big Endian)</button> <button id="exportBinaryLittleEndian">export binary (Little Endian)</button>
</div>
<script type="module">
import * as THREE from '../build/three.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { PLYExporter } from './jsm/exporters/PLYExporter.js';
let scene, camera, renderer, exporter, mesh, meshHole, mesh0, mesh1;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 200, 100, 200 );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xa1caf1 );
//scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
//exporter = new PLYExporter();
//
const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
hemiLight.position.set( 0, 200, 0 );
scene.add( hemiLight );
const directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.set( 0, 200, 100 );
directionalLight.castShadow = true;
directionalLight.shadow.camera.top = 180;
directionalLight.shadow.camera.bottom = - 100;
directionalLight.shadow.camera.left = - 120;
directionalLight.shadow.camera.right = 120;
scene.add( directionalLight );
// ground
const ground = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0xaaaaaa, depthWrite: false } ) );
ground.rotation.x = - Math.PI / 2;
ground.receiveShadow = true;
scene.add( ground );
const grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
// mesh
const boxHole = new THREE.CylinderGeometry( 15, 15, 65, 32, 32 );//BoxGeometry( 20, 20, 51 );
let matHole = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
matHole.colorWrite = false;
meshHole = new THREE.Mesh( boxHole, matHole );
meshHole.castShadow = true;
meshHole.position.y = 50;
meshHole.rotation.x = Math.PI / 2;
scene.add( meshHole );
const geometry = new THREE.BoxGeometry( 50, 50, 50 );
mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial({ color: 0xaaaaaa }) );
mesh.castShadow = true;
mesh.position.y = 50;
scene.add( mesh );
// back faces
const mat0 = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
mat0.side = THREE.FrontSide;
mat0.depthWrite = false;
mat0.depthTest = false;
mat0.colorWrite = false;
//mat0.stencilWrite = true;
mat0.stencilFunc = THREE.AlwaysStencilFunc;
mat0.stencilFail = THREE.KeepStencilOp;
//mat0.stencilZFail = THREE.IncrementWrapStencilOp;
//mat0.stencilZPass = THREE.ReplaceStencilOp;
mat0.stencilRef = 1;
const boxHole0 = new THREE.CylinderGeometry( 15, 15, 65, 32, 32 );
mesh0 = new THREE.Mesh( boxHole0, mat0 );
mesh0.rotation.x = Math.PI / 2;
mesh0.castShadow = true;
mesh0.position.y = 50;
scene.add( mesh0 );
// front faces
const mat1 = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
mat1.side = THREE.DoubleSide;
//mat1.depthWrite = false;
//mat1.depthTest = true;
//mat1.colorWrite = false;
//mat1.stencilWrite = true;
mat1.depthFunc=THREE.AlwaysDepth;
mat1.stencilFunc = THREE.EqualStencilFunc;
mat1.stencilFail = THREE.IncrementStencilOp;
//mat1.stencilZFail = THREE.DecrementWrapStencilOp;
//mat1.stencilZPass = THREE.DecrementWrapStencilOp;
mat1.stencilRef = 1;
const boxHole1 = new THREE.CylinderGeometry( 15, 15, 65, 32, 32, true );
mesh1 = new THREE.Mesh( boxHole1, mat1 );
mesh1.rotation.x = Math.PI / 2;
mesh1.castShadow = true;
mesh1.position.z = 0;
mesh1.position.y = 50;
scene.add( mesh1 );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.localClippingEnabled = true;
document.body.appendChild( renderer.domElement );
//
const controls = new OrbitControls( camera, renderer.domElement );
controls.target.set( 0, 25, 0 );
controls.update();
//
window.addEventListener( 'resize', onWindowResize );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
const link = document.createElement( 'a' );
link.style.display = 'none';
document.body.appendChild( link );
</script>
</body>
</html>
Got it working at the end:
Box with cylinder hole
import * as THREE from '../build/three.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { PLYExporter } from './jsm/exporters/PLYExporter.js';
let scene, camera, renderer, exporter, mesh, meshHole, mesh0, mesh1;
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 200, 100, 200 );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xa1caf1 );
//scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
//exporter = new PLYExporter();
//
const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
hemiLight.position.set( 0, 200, 0 );
scene.add( hemiLight );
const directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.set( 0, 200, 100 );
directionalLight.castShadow = true;
directionalLight.shadow.camera.top = 180;
directionalLight.shadow.camera.bottom = - 100;
directionalLight.shadow.camera.left = - 120;
directionalLight.shadow.camera.right = 120;
scene.add( directionalLight );
// ground
const ground = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0xaaaaaa, depthWrite: false } ) );
ground.rotation.x = - Math.PI / 2;
ground.receiveShadow = true;
scene.add( ground );
const grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
// mesh
const boxHole = new THREE.CylinderGeometry( 15, 15, 51, 32, 32 );//BoxGeometry( 20, 20, 51 );
let matHole = new THREE.MeshPhongMaterial({ color: 0xaaaaaa });
matHole.colorWrite = false;
meshHole = new THREE.Mesh( boxHole, matHole );
meshHole.castShadow = true;
meshHole.position.y = 50;
meshHole.rotation.x = Math.PI / 2;
scene.add( meshHole );
const geometry = new THREE.BoxGeometry( 50, 50, 50 );
mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial({ color: 0xaaaaaa }) );
mesh.castShadow = true;
mesh.position.y = 50;
scene.add( mesh );
// front faces
const mat0 = new THREE.MeshPhongMaterial({ color: 0xaaaaaa });
mat0.side = THREE.FrontSide;
//mat0.depthWrite = false;
//mat0.depthTest = false;
mat0.colorWrite = false;
const boxHole0 = new THREE.CylinderGeometry( 15, 15, 51, 32, 32 );
mesh0 = new THREE.Mesh( boxHole0, mat0 );
mesh0.rotation.x = Math.PI / 2;
mesh0.castShadow = true;
mesh0.position.y = 50;
scene.add( mesh0 );
mat0.stencilWrite = true;
mat0.stencilFunc = THREE.AlwaysStencilFunc;
mat0.stencilFail = THREE.KeepStencilOp;
mat0.stencilZFail = THREE.KeepStencilOp;
mat0.stencilZPass = THREE.ReplaceStencilOp;
mat0.stencilRef = 1;
// back faces
const mat1 = new THREE.MeshPhongMaterial({ color: 0xaaaaaa });
mat1.side = THREE.BackSide;
mat1.depthWrite = false;
mat1.depthTest = true;
//mat1.colorWrite = false;
const boxHole1 = new THREE.CylinderGeometry( 15, 15, 51, 32, 32, true );
mesh1 = new THREE.Mesh( boxHole1, mat1 );
mesh1.rotation.x = Math.PI / 2;
mesh1.castShadow = true;
mesh1.position.z = 0;
mesh1.position.y = 50;
scene.add( mesh1 );
mat1.depthFunc=THREE.AlwaysDepth;
mat1.stencilWrite = true;
mat1.stencilFunc = THREE.EqualStencilFunc;
mat1.stencilFail = THREE.DecrementWrapStencilOp;
mat1.stencilZFail = THREE.DecrementWrapStencilOp;
mat1.stencilZPass = THREE.DecrementWrapStencilOp;
mat1.stencilRef = 1;
mesh1.onAfterRender = function ( renderer ) {
renderer.clearStencil();
};
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.localClippingEnabled = true;
document.body.appendChild( renderer.domElement );
//
const controls = new OrbitControls( camera, renderer.domElement );
controls.target.set( 0, 25, 0 );
controls.update();
//
window.addEventListener( 'resize', onWindowResize );
}

Moving an object using three.js

I am very much new to this three.js. I want to create two cubes. I am least interested in its animation. So, i want cube 1 to move towards cube 2 without any keyboard inputs. I am also providing image for better understanding.
Thanks in advance
On possibility to animate objects, is to use THREE.Tween
Create the 2 cubes:
var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
cube1 = new THREE.Mesh(geometry1, material1);
cube1.position.set(0.0, 0.0, 2.0);
var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
cube2 = new THREE.Mesh(geometry2, material2);
cube2.position.set(2.0, 0.0, 0.0);
Create a Tween, which rotates the cube and continuously restarts:
tweenStart = { value: 0 };
var finish = { value: Math.PI/2 };
cubeTween = new TWEEN.Tween(tweenStart);
cubeTween.to(finish, 3000)
cubeTween.onUpdate(function() {
cube1.position.set(0.0, 0.0, 0.0);
cube1.rotation.y = tweenStart.value;
cube1.translateZ( 2.0 );
});
cubeTween.onComplete( function() {
tweenStart.value = 0;
requestAnimationFrame(function() {
cubeTween.start();
});
});
cubeTween.start();
(function onLoad() {
var container, loader, camera, scene, renderer, controls, cube1, cube2, cubeTween, tweenStart;
init();
animate();
animateCube();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(0, 6, 0);
camera.lookAt( 0, 0, 0 );
loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;
var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(1,2,1.5);
scene.add( directionalLight );
controls = new THREE.OrbitControls(camera);
addGridHelper();
createModel();
}
function createModel() {
var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
cube1 = new THREE.Mesh(geometry1, material1);
cube1.position.set(0.0, 0.0, 2.0);
var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
cube2 = new THREE.Mesh(geometry2, material2);
cube2.position.set(2.0, 0.0, 0.0);
scene.add(cube1);
scene.add(cube2);
tweenStart = { value: 0 };
var finish = { value: Math.PI/2 };
cubeTween = new TWEEN.Tween(tweenStart);
cubeTween.to(finish, 3000)
cubeTween.onUpdate(function() {
cube1.position.set(0.0, 0.0, 0.0);
cube1.rotation.y = tweenStart.value;
cube1.translateZ( 2.0 );
});
cubeTween.onComplete( function() {
tweenStart.value = 0;
requestAnimationFrame(function() {
cubeTween.start();
});
});
cubeTween.start();
}
function addGridHelper() {
var helper = new THREE.GridHelper(100, 100);
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper(1000);
scene.add(axis);
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
TWEEN.update();
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.js"></script>
<div id="container"></div>
Alternatively you can slightly change the position of the cube by changing the position property of the cube in the animate function:
function animate() {
requestAnimationFrame(animate);
if ( cube1.position.z > 0.0 ) {
cube1.position.set(0.0, 0.0, cube1.position.z-0.01);
} else if ( cube1.position.x < 2.0 ) {
cube1.position.set(cube1.position.x+0.01, 0.0, 0.0);
} else {
cube1.position.set(0.0, 0.0, 2.0);
}
render();
}
(function onLoad() {
var container, loader, camera, scene, renderer, controls, cube1, cube2, cubeTween, tweenStart;
init();
animate();
animateCube();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(0, 6, 0);
camera.lookAt( 0, 0, 0 );
loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;
var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(1,2,1.5);
scene.add( directionalLight );
controls = new THREE.OrbitControls(camera);
addGridHelper();
createModel();
}
function createModel() {
var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
cube1 = new THREE.Mesh(geometry1, material1);
cube1.position.set(0.0, 0.0, 2.0);
var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
cube2 = new THREE.Mesh(geometry2, material2);
cube2.position.set(2.0, 0.0, 0.0);
scene.add(cube1);
scene.add(cube2);
}
function addGridHelper() {
var helper = new THREE.GridHelper(100, 100);
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper(1000);
scene.add(axis);
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
if ( cube1.position.z > 0.0 ) {
cube1.position.set(0.0, 0.0, cube1.position.z-0.01);
} else if ( cube1.position.x < 2.0 ) {
cube1.position.set(cube1.position.x+0.01, 0.0, 0.0);
} else {
cube1.position.set(0.0, 0.0, 2.0);
}
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="container"></div>
There are a few different ways you could do this.
It will also be easier to answer this by assuming axes and both cube's starting position.
Let's say cube1 position is:
x: 0
y: 0
z: 0
Cube2 position is:
x: 10
y: 20
z: 0
In the render loop, move cube1 along the y-axis until it reaches the same value as cube2 (20), then move cube1 along the x-axis until it reaches cube2 x position. So cube1 would then be sitting on top of cube2. You would need the code to move cube1 to be present, but only run when certain conditions are met.
E.g, only move in the y-axis if cube1.position.y is less than or equal to cube2.position.y
Movement speed can be increased or decreased by changing the increment value. So an update on the y-axis could look like this:
cube1.position.y += 0.1;
This way could be harder to manage though, as you will need to constantly check the cube1 position in relation to cube2, and because the cube needs to move in two directions this could get messy in the long-run.
You can see an example of this update in the loop concept here - https://jsfiddle.net/f2Lommf5/
I would look at using an animation library such as Tween.js or Greensock which in my opinion would be much better suited. You can specify an axis to move along, the start and end position, animation duration and easing. When the animation on the y-axis is complete, you can start the animation on the x-axis.
Some useful links:
Tween.js - http://learningthreejs.com/blog/2011/08/17/tweenjs-for-smooth-animation/
Greensock - http://www.kadrmasconcepts.com/blog/2012/05/29/greensock-three-js/

Three.js load Image as texture not render

The g.png success loaded,but it not render.
Is it not loaded but render first?
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
material = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("g.png") });
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
Full code
https://gist.github.com/EasonWang01/410046ababc1af4f7f2db4b294b591ca
I write a sample based on your code, hope that will help you.
<html>
<head>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"> </script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.lookAt(new THREE.Vector3(0, 0, 0));
var renderer = new THREE.WebGLRenderer({ alpha: false });
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry1 = new THREE.BoxGeometry( 12, 1, 1 );
var material1 = new THREE.MeshBasicMaterial( { color: 0x00FFCC } );
var cube1 = new THREE.Mesh( geometry1, material1 );
scene.add( cube1 );
var geometry2 = new THREE.BoxGeometry( 10, 1, 1 );
var material2 = new THREE.MeshBasicMaterial( { color: 0xCCFF33 } );
var cube2 = new THREE.Mesh( geometry2, material2 );
scene.add( cube2 );
var geometry3 = new THREE.CircleBufferGeometry( 3, 32 );
var material3 = new THREE.MeshBasicMaterial( { color: 0xCCFFCC } );
var circle3 = new THREE.Mesh( geometry3, material3 );
scene.add( circle3 );
var geometry4 = new THREE.BoxBufferGeometry( 10, 1, 1 );
material4 = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("img/g.png") });
var cube4 = new THREE.Mesh( geometry4, material4 );
scene.add( cube4 );
var geometry = new THREE.CubeGeometry(150, 200, 150, 2, 2, 2);
var materials = [];
cube = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
cube.position.y = 150;
scene.add(cube);
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
camera.position.z = 5;
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
material = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("img/g.png") });
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
cube1.rotation.x += 0.02;
cube1.rotation.y += 0.02;
cube2.rotation.x += 0.03;
cube2.rotation.y += 0.03;
renderer.render(scene, camera);
};
setTimeout(() => {render();},500)
</script>
</body>
</html>

Threejs, using ShaderMaterial to fake a hole in geometries

In Release 53 of Three.js I could fake a hole in a geometry with another geometry using a shader material with
vertex:void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
and
fragment:void main() {
gl_FragColor = vec4(1.0, 0.0, 1.0, 0.0); //alpha is zero
}
I could peep through the 'hole' and saw objects behind. Since release 54 I just see the inner object white, I can't peep through anymore.
How can I get it work again?
my complete sample:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometry - cube</title>
<meta charset="utf-8">
<style>
body {
margin: 0px;
background-color: #DDFFDD;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/old/three_53.js"></script>
<script src="../build/old/controls/TrackballControls_53.js"></script>
<script>
var camera, scene, renderer, controls, pointLight;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
//renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
document.body.appendChild( renderer.domElement );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400;
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;
scene = new THREE.Scene();
scene.add( new THREE.AmbientLight( 0x505050 ) );
pointLight = new THREE.PointLight(0xFFFFFF, 0.9);
scene.add(pointLight);
var mainGroup = new THREE.Object3D();
var geometry = new THREE.CubeGeometry( 100, 100, 10 );
var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: 0xaaaaaa } ) );
//mesh.renderOrder = 2;
var geometry2 = new THREE.CubeGeometry( 50, 50, 11 );
var material2 = new THREE.ShaderMaterial({vertexShader:'void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);}', fragmentShader:'void main() { gl_FragColor = vec4(1.0, 0.0, 1.0, 0.0);}'});
var innerGroup = new THREE.Object3D();
var mesh2 = new THREE.Mesh( geometry2, material2 );
//mesh2.renderOrder = 1;
mainGroup.add( mesh );
innerGroup.add(mesh2);
mainGroup.add( innerGroup );
//
var geometry3 = new THREE.SphereGeometry( 50);
var mesh3 = new THREE.Mesh( geometry3, new THREE.MeshLambertMaterial( { color: 0x00ff00 } ) );
mesh3.position.z = -200;
//mesh2.renderOrder = 3;
mainGroup.add( mesh3 );
scene.add(mainGroup);
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
pointLight.position.set(camera.position.x, camera.position.y, camera.position.z);
renderer.render( scene, camera );
}
</script>
</body>
It only works, if the 'hole-object' with the shader material is in a group.
If this worked before it's merely by accident. But you can, in 71, get this to work if you use renderOrder:
holeObj.renderOrder = 1;
bgObj.renderOrder = 2;
Now, if holeObj is in front of bgObj then in normal cases you will see through the bgObj. This is because holeObj will still write to the Z-buffer, when it draws its transparent pixels. The bgObj will be masked from that location. But this will only work for a particular view direction without some careful management of the sorting.

How to add a bokehShader in three.js

I am the shader in this example https://threejsdoc.appspot.com/doc/three.js/examples/webgl_postprocessing_dof.html to add the bokeh effect to my scene. But I am unable to get it work. However there seems to be no errors when I checked in the console. Here is my code (main.js). I have included the ShaderExtras.js from the example and added it in the index.html
$(document).ready(function(){
pposx = window.innerWidth/2;
pposy = window.innerHeight/2;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 10000 );
camera.lookAt(scene.position);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 5;
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xffffff );
$("body").append(renderer.domElement);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.7 );
directionalLight.position.set( 0, 0, -4 );
directionalLight.rotation.x = (Math.PI/180)*180;
directionalLight.rotation.y = (Math.PI/180)*180;
var directionalLight1 = new THREE.DirectionalLight( 0xffffff, 0.7 );
directionalLight1.position.set( 0, 0, 4 );
var directionalLight2 = new THREE.DirectionalLight( 0xffffff, 0.7 );
directionalLight2.position.set( -3, 0, 0 );
var directionalLight3 = new THREE.DirectionalLight( 0xffffff, 0.7 );
directionalLight3.position.set( 3, 0, 0 );
scene.add( directionalLight, directionalLight1, directionalLight2, directionalLight3 );
material1 = new THREE.MeshPhongMaterial( { color: 0xff00ff, specular: 0xff00ff, shininess: -3, shading: THREE.FlatShading, side: THREE.FrontSide } );
ge = [];
for(j=0;j<100;j++){
ge[j] = new THREE.BoxGeometry( 1, 1, 1 );
ge[j] = new THREE.Mesh( ge[j], material1 );
ge[j].position.z = -50 + j*2;
scene.add( ge[j] );
}
$(document).mousemove(function(e){
pposx = e.clientX;
pposy = e.clientY;
});
function initPostprocessing() {
postprocessing.scene = new THREE.Scene();
postprocessing.camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -100, 100 );
postprocessing.camera.position.z = 5;
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
postprocessing.rtTextureDepth = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, pars );
postprocessing.rtTextureColor = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, pars );
var bokeh_shader = THREE.ShaderExtras[ "bokeh" ];
postprocessing.bokeh_uniforms = THREE.UniformsUtils.clone( bokeh_shader.uniforms );
postprocessing.bokeh_uniforms[ "focus" ].value = 1;
postprocessing.bokeh_uniforms[ "aperture" ].value = 0.2;
postprocessing.bokeh_uniforms[ "maxblur" ].value = 3;
postprocessing.bokeh_uniforms[ "tColor" ].texture = postprocessing.rtTextureColor;
postprocessing.bokeh_uniforms[ "tDepth" ].texture = postprocessing.rtTextureDepth;
postprocessing.bokeh_uniforms[ "focus" ].value = 0.1;
postprocessing.bokeh_uniforms[ "aspect" ].value = window.innerWidth / window.innerHeight;
postprocessing.materialBokeh = new THREE.ShaderMaterial( {
uniforms: postprocessing.bokeh_uniforms,
vertexShader: bokeh_shader.vertexShader,
fragmentShader: bokeh_shader.fragmentShader
} );
postprocessing.quad = new THREE.Mesh( new THREE.PlaneGeometry( window.innerWidth, window.innerHeight ), postprocessing.materialBokeh );
postprocessing.quad.position.z = -1;
postprocessing.scene.add( postprocessing.quad );
}
function render() {
requestAnimationFrame( render );
camera.rotation.y = (Math.PI/180)*((pposx - (window.innerWidth/2))/1000*180);
camera.position.x = (5*Math.sin((Math.PI/180)*((pposx - (window.innerWidth/2))/1000*180)));
camera.position.y = (pposy - (window.innerHeight/2))/100;
camera.position.z = (5*Math.cos((Math.PI/180)*((pposx - (window.innerWidth/2))/1000*180)));
renderer.render(scene, camera);
};
var postprocessing = { enabled : true };
initPostprocessing();
render();
});
Please, Any help to make the cubes appear blured will be helpful.

Resources