Pan is the only working thing for OrbitControls - three.js

I am trying to program a solar system that you can orbit around and pan so I added an OrbitControls to my project and pan is working fine but for some reason rotate and zoom aren't working. I have tried copying other people's examples and I cannot figure out what is wrong with mine. I don't know if it could just be my computer, but I have no reason to believe that it would be.
<!DOCTYPE html>
<html>
<head>
<title>Example 01.02 - First Scene</title>
<script type="text/javascript" src="../libs/three.js"></script>
<script type="text/javascript" src="../libs/jquery-1.9.0.js"></script>
<script type="text/javascript" src="../libs/stats.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<script type="text/javascript" src="../libs/OrbitControls.js"></script>
<script type="text/javascript" src="../libs/chroma.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<style>
body{
/* set margin to 0 and overflow to hidden, to go fullscreen */
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="Stats-output">
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>
<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
// once everything is loaded, we run our Three.js stuff.
$(function () {
var stats = initStats();
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var clock = new THREE.Clock();
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 5000);
// position and point the camera to the center of the scene
camera.position.x = -150;
camera.position.y = 200;
camera.position.z = 150;
camera.lookAt(scene.position);
// create a render and set the size
renderer = new THREE.WebGLRenderer( {antialias:true} );
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
ccontrols = new THREE.OrbitControls( camera, renderer.domElement );
ccontrols.damping = 0.2;
ccontrols.addEventListener( 'change', render );
var ambiLight = new THREE.AmbientLight(0x747474)
scene.add(ambiLight);
var pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(0, 0, 0);
pointLight.distance = 100;
scene.add(pointLight);
//create the light box
var lightboxgeom = new THREE.SphereGeometry(3000,50,50);
var lightboxmat = new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture("./TexturesAndModels/lightbox.png"), side: THREE.BackSide});
var lightbox = new THREE.Mesh(lightboxgeom, lightboxmat);
//sun and glow
var sun = createMesh(new THREE.SphereGeometry(20, 20, 20), "texture_sun.jpg", "texture_sun_DISP.jpg", "texture_sun_SPEC.jpg");
sun.shading = THREE.NoShading;
var spriteMaterial = new THREE.SpriteMaterial(
{
map: new THREE.ImageUtils.loadTexture( "TexturesAndModels/GLOW.png" ),
useScreenCoordinates: false, alignment: THREE.SpriteAlignment.center,
color: 0xffcc00, transparent: false, blending: THREE.AdditiveBlending
});
var sprite = new THREE.Sprite( spriteMaterial );
sprite.scale.set(100, 100, 1.0);
sun.add(sprite);
//mercury
var mercury = createMesh(new THREE.SphereGeometry(1.50, 20, 20), "texture_mercury.jpg", "texture_mercury_DISP.jpg", "texture_mercury_SPEC.jpg", "texture_mercury_NRM.jpg");
//venus
var venus = createMesh(new THREE.SphereGeometry(3.80, 20, 20), "texture_venus_surface.jpg", "texture_venus_surface_DISP.jpg", "texture_venus_surface_SPEC.jpg", "texture_venus_surface_NRM.jpg");
//earth and clouds
var earth = createMesh(new THREE.SphereGeometry(4.00, 20, 20), "ColorMap.jpg", "Bump2.jpg", "SpecMask2.png", "ColorMap_NRM.jpg");
//mars
var mars = createMesh(new THREE.SphereGeometry(2.10, 20, 20), "texture_mars.jpg", "texture_mars_DISP.jpg", "texture_mars_SPEC.jpg", "texture_mars_NRM.jpg");
//Jupiter
var jupiter = createMesh(new THREE.SphereGeometry(18.7, 20, 20), "texture_jupiter.jpg", "texture_jupiter_DISP.jpg", "texture_jupiter_SPEC.jpg", "texture_jupiter_NRM.jpg");
//saturn
var saturn = createMesh(new THREE.SphereGeometry(18, 20, 20), "texture_saturn.jpg", "texture_saturn_DISP.jpg", "texture_saturn_SPEC.jpg", "texture_saturn_NRM.jpg");
//uranus
var uranus = createMesh(new THREE.SphereGeometry(15, 20, 20), "texture_uranus.jpg", "texture_uranus_DISP.jpg", "texture_uranus_SPEC.jpg", "texture_uranus_NRM.jpg");
//neptune
var neptune = createMesh(new THREE.SphereGeometry(14, 20, 20), "texture_neptune.jpg", "texture_neptune_DISP.jpg", "texture_neptune_SPEC.jpg", "texture_neptune_NRM.jpg");
// position the planets
sun.position.x=0;
sun.position.y=0;
sun.position.z=0;
earth.position.y=0;
mars.position.y=0;
venus.position.y=0;
mercury.position.y=0;
saturn.position.y=0;
jupiter.position.y=0;
uranus.position.y=0;
neptune.position.y=0;
// add the planets to the scene
scene.add(lightbox);
scene.add(earth);
scene.add(sun);
scene.add(mercury);
scene.add(venus);
scene.add(mars);
scene.add(jupiter);
scene.add(saturn);
scene.add(uranus);
scene.add(saturn);
// add the output of the renderer to the html element
$("#WebGL-output").append(renderer.domElement);
var r = 0;
var step = 0;
var controls = new function() {
this.timeScale = 1;
}
var gui = new dat.GUI();
gui.add(controls, 'timeScale', 0, 10);
// render the scene
render();
function createMesh(geom, imageFile, bump, spec, normal) {
var texture = THREE.ImageUtils.loadTexture("./TexturesAndModels/" + imageFile)
var mat = new THREE.MeshPhongMaterial();
mat.map = texture;
if (bump) {
var bump = THREE.ImageUtils.loadTexture("./TexturesAndModels/" + bump)
mat.bumpMap = bump;
mat.bumpScale = 0.2;
}
if(spec) {
var spec = THREE.ImageUtils.loadTexture("./TexturesandModels/" + spec)
mat.specularMap = spec;
}
if(normal) {
var norm = THREE.ImageUtils.loadTexture("./TexturesAndModels/" + normal)
mat.normalMap = norm;
}
var mesh = new THREE.Mesh(geom, mat);
return mesh;
}
function render() {
stats.update();
earth.position.x = Math.sin(r*0.1)*150;
earth.position.z = Math.cos(r*0.1)*150;
earth.rotation.y = step += controls.timeScale * 0.02;
mercury.position.x = Math.sin(r*0.4)*58;
mercury.position.z = Math.cos(r*0.4)*58;
mercury.rotation.y = step/58.7;
venus.position.x = Math.sin(r*0.1625)*108;
venus.position.z = Math.cos(r*0.1625)*108;
venus.rotation.y = step/243;
mars.position.x = Math.sin(r*0.05)*228;
mars.position.z = Math.cos(r*0.05)*228;
mars.rotation.y = step*1.026;
jupiter.position.x = Math.sin(r*.008)*483;
jupiter.position.z = Math.cos(r*.008)*483;
jupiter.rotation.y = step*2.44;
saturn.position.x = Math.sin(r*.003)*886;
saturn.position.z = Math.cos(r*.003)*886;
saturn.rotation.y = step*2.35;
uranus.position.x = Math.sin(r*.001)*1784;
uranus.position.z = Math.cos(r*.001)*1784;
uranus.rotation.y = step*1.34;
neptune.position.x = Math.sin(r*.0006)*2794;
neptune.position.z = Math.cos(r*.0006)*2794;
neptune.rotation.y = step*1.26;
r+=controls.timeScale * (Math.PI/180*2);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function initStats() {
var stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
$("#Stats-output").append(stats.domElement);
return stats;
}
});
</script>
</body>
</html>

Related

How to make particles in threejs take the shape of a model/object -onscroll

I am relatively new to ThreeJS.
I want to make a website very similar to this one:
Web de CraftedBYGC
In which I make a system of particles that as the user scrolls they disperse and rejoin in a form.
The truth is that I am very lost about where to start.
I would greatly appreciate some help.
I tried to create a geometry with particle mesh and move the camera on scroll to simulate a little bit the effect, but the truth was very poor. I need to find another method and I don't know well what to do...
Below is a snippet of the working example:
var webGLRenderer = initRenderer();
var scene = new THREE.Scene();
var camera = initCamera(new THREE.Vector3(-30, 40, 50));
// call the render function
var step = 0;
var knot;
// setup the control gui
var controls = new function () {
// we need the first child, since it's a multimaterial
this.radius = 13;
this.tube = 1.7;
this.radialSegments = 156;
this.tubularSegments = 12;
this.redraw = function () {
// remove the old plane
if (knot) scene.remove(knot);
// create a new one
var geom = new THREE.TorusKnotGeometry(controls.radius, controls.tube, Math.round(controls.radialSegments), Math.round(controls.tubularSegments), Math.round(controls.p), Math.round(controls.q));
knot = createPoints(geom);
// add it to the scene.
scene.add(knot);
};
};
var gui = new dat.GUI();
gui.add(controls, 'radius', 0, 40).onChange(controls.redraw);
gui.add(controls, 'tube', 0, 40).onChange(controls.redraw);
gui.add(controls, 'radialSegments', 0, 400).step(1).onChange(controls.redraw);
gui.add(controls, 'tubularSegments', 1, 20).step(1).onChange(controls.redraw);
controls.redraw();
render();
// from THREE.js examples
function generateSprite() {
var canvas = document.createElement('canvas');
canvas.width = 16;
canvas.height = 16;
var context = canvas.getContext('2d');
var gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
gradient.addColorStop(0, 'rgba(255,255,255,1)');
gradient.addColorStop(0.2, 'rgba(0,255,255,1)');
gradient.addColorStop(0.4, 'rgba(0,0,64,1)');
gradient.addColorStop(1, 'rgba(0,0,0,1)');
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
return texture;
}
function createPoints(geom) {
var material = new THREE.PointsMaterial({
color: 0xffffff,
size: 3,
transparent: true,
blending: THREE.AdditiveBlending,
map: generateSprite(),
depthWrite: false // instead of sortParticles
});
var cloud = new THREE.Points(geom, material);
return cloud;
}
function render() {
knot.rotation.y = step += 0.01;
// render using requestAnimationFrame
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}
body {
margin: 0;
overflow: none
}
<!DOCTYPE html>
<html>
<head>
<title>Example 07.11 - 3D Torusknot</title>
<script type="text/javascript" charset="UTF-8" src="https://www.smartjava.org/ltjs3/libs/three/three.js"></script>
<script src="https://www.smartjava.org/ltjs3/libs/three/controls/TrackballControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.9/dat.gui.min.js"></script>
<script src="https://www.smartjava.org/ltjs3/src/js/util.js"></script>
</head>
<body>
<div id="webgl-output">
</body>
</html>
This is working on a TorusKnot, but you can apply the particles to a model, too. All you have to do is change the source.

three.js post processing maskpass with multiple renderpass never works

I am working towards this:
Here is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../build/three.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/postprocessing/ClearPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>
<script src="js/postprocessing/MaskPass.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/Detector.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var composer, renderer;
var box_mask, box_1, box_2;
init();
animate();
function init() {
var camera_mask = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera_mask.position.z = 6;
var camera_1 = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera_1.position.z = 6;
var camera_2 = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera_2.position.z = 6;
var scene_mask = new THREE.Scene();
var scene_1 = new THREE.Scene();
var scene_2 = new THREE.Scene();
scene_mask.background = new THREE.Color( 0x000000 );
scene_1.background = new THREE.Color( 0xffffff );
scene_2.background = new THREE.Color( 0x000000 );
var box_mask_1 = new THREE.CircleGeometry( 2, 4 );
var box_mask_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_mask = new THREE.Geometry();
var boxMesh_mask_1 = new THREE.Mesh(box_mask_1);
boxMesh_mask_1.position.z = 1;
var boxMesh_mask_2 = new THREE.Mesh(box_mask_2);
boxMesh_mask_2.rotation.y = Math.PI;
boxMesh_mask_2.position.z = -1;
boxMesh_mask_1.updateMatrix(); // as needed
singleGeometry_mask.merge(boxMesh_mask_1.geometry, boxMesh_mask_1.matrix);
boxMesh_mask_2.updateMatrix(); // as needed
singleGeometry_mask.merge(boxMesh_mask_2.geometry, boxMesh_mask_2.matrix);
var material_mask = new THREE.MeshBasicMaterial({color: 0xffffff});
box_mask = new THREE.Mesh(singleGeometry_mask, material_mask);
scene_mask.add( box_mask );
var box_1_1 = new THREE.CircleGeometry( 2, 4 );
var box_1_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_1 = new THREE.Geometry();
var boxMesh_1_1 = new THREE.Mesh(box_1_1);
boxMesh_1_1.position.z = -1;
var boxMesh_1_2 = new THREE.Mesh(box_1_2);
boxMesh_1_2.rotation.y = Math.PI;
boxMesh_1_2.position.z = 1;
boxMesh_1_1.updateMatrix();
singleGeometry_1.merge(boxMesh_1_1.geometry, boxMesh_1_1.matrix);
boxMesh_1_2.updateMatrix();
singleGeometry_1.merge(boxMesh_1_2.geometry, boxMesh_1_2.matrix);
var material_1 = new THREE.MeshBasicMaterial({color: 0x000000});
box_1 = new THREE.Mesh(singleGeometry_1, material_1);
scene_1.add( box_1 );
var box_2_1 = new THREE.CircleGeometry( 2, 4 );
var box_2_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_2 = new THREE.Geometry();
var boxMesh_2_1 = new THREE.Mesh(box_2_1);
boxMesh_2_1.position.z = -1;
var boxMesh_2_2 = new THREE.Mesh(box_2_2);
boxMesh_2_2.rotation.y = Math.PI;
boxMesh_2_2.position.z = 1;
boxMesh_2_1.updateMatrix();
singleGeometry_2.merge(boxMesh_2_1.geometry, boxMesh_2_1.matrix);
boxMesh_2_2.updateMatrix();
singleGeometry_2.merge(boxMesh_2_2.geometry, boxMesh_2_2.matrix);
var material_2 = new THREE.MeshBasicMaterial({color: 0xffffff});
box_2 = new THREE.Mesh(singleGeometry_2, material_2);
scene_2.add( box_2 );
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.autoClear = false;
document.body.appendChild( renderer.domElement );
var clearPass = new THREE.ClearPass();
var clearMaskPass = new THREE.ClearMaskPass();
var maskPass = new THREE.MaskPass( scene_mask, camera_mask );
var renderPass_1 = new THREE.RenderPass( scene_1, camera_1 );
var renderPass_2 = new THREE.RenderPass( scene_2, camera_2 );
var outputPass = new THREE.ShaderPass( THREE.CopyShader );
outputPass.renderToScreen = true;
var parameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat,
stencilBuffer: true
};
var renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, parameters );
composer = new THREE.EffectComposer( renderer , renderTarget );
composer.addPass( clearPass );
composer.addPass( renderPass_1 );
composer.addPass( maskPass );
composer.addPass( renderPass_2 );
composer.addPass( clearMaskPass );
composer.addPass( outputPass );
}
function animate() {
requestAnimationFrame( animate );
var time = performance.now() * 0.001 * 2;
box_mask.rotation.y = time;
box_1.rotation.y = time;
box_2.rotation.y = time;
renderer.clear();
composer.render( time );
}
</script>
</body>
</html>
this never works:
composer.addPass( clearPass );
composer.addPass( renderPass_1 );
composer.addPass( maskPass );
composer.addPass( renderPass_2 );
composer.addPass( clearMaskPass );
composer.addPass( outputPass );
if i switch out "renderPass_2" with a THREE.TexturePass it works, but it's not what I want.
Here is the codepen:
https://codepen.io/oxbits/pen/yEQLGK?editors=0010
Anyone able to combine two renderPasses with a mask?
Should I be using a different approach?
I finally got it to work! Though I'm not sure how...
Take a look:
https://codepen.io/anon/pen/PyJObz
One trick was not using a scene background in the 2nd render. Instead I had to create a background mesh.
Code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
html, body, canvas {
margin: 0px;
overflow: hidden;
}
#fps {
position: absolute;
top: 0px;
left: 0px;
color: #fff;
z-index: 50;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../build/three.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/postprocessing/ClearPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>
<script src="js/postprocessing/MaskPass.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/Detector.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
// if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
let scene = null;
let normal = null;
let outline = null;
let outScene = null;
let maskScene = null;
let light = null;
let renderer = null;
let composer = null;
let camera1 = null;
let camera2 = null;
let camera3 = null;
let mesh1 = null;
let mesh2 = null;
let mesh3 = null;
let bg_mesh = null;
let renderTarget = null;
let screenWidth = window.innerWidth;
let screenHeight = window.innerHeight;
const clock = new THREE.Clock;
let elapsedTime = 0;
let frameCount = 0;
const init = function() {
// SCENE
scene = new THREE.Scene;
maskScene = new THREE.Scene;
outScene = new THREE.Scene;
setModel();
// SCENE CAMERA
camera1 = new THREE.PerspectiveCamera(40, screenWidth/screenHeight, 1, 1000);
camera1.position.set(0, 0, 10);
scene.add(camera1);
camera2 = new THREE.PerspectiveCamera(40, screenWidth/screenHeight, 1, 1000);
camera2.position.set(0, 0, 10);
outScene.add(camera2);
camera3 = new THREE.PerspectiveCamera(40, screenWidth/screenHeight, 1, 1000);
camera3.position.set(0, 0, 10);
maskScene.add(camera3);
scene.background = new THREE.Color( 0xffffff );
// RENDERER
renderer = new THREE.WebGLRenderer({
width: screenWidth,
height: screenHeight,
antialias: true
});
renderer.setSize(screenWidth, screenHeight);
renderer.setClearColor(0x000000);
renderer.autoClear = false;
renderer.gammaInput = true;
renderer.gammaOutput = true;
document.body.appendChild(renderer.domElement);
// POSTPROCESSING
const renderTargetParameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBAFormat,
stencilBuffer: true
};
renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters);
composer = new THREE.EffectComposer(renderer);
composer.renderTarget1.stencilBuffer = true;
composer.renderTarget2.stencilBuffer = true;
normal = new THREE.RenderPass(scene, camera1);
outline = new THREE.RenderPass(outScene, camera2);
outline.clear = false;
const mask = new THREE.MaskPass(maskScene, camera3);
mask.inverse = false;
const clearMask = new THREE.ClearMaskPass;
const copyPass = new THREE.ShaderPass(THREE.CopyShader);
copyPass.renderToScreen = true;
composer.addPass(normal);
composer.addPass(mask);
composer.addPass(outline);
composer.addPass(clearMask);
composer.addPass(copyPass);
// EVENTS
return window.addEventListener('resize', onWindowResize, false);
};
var setModel = function() {
var box_mask_1 = new THREE.CircleGeometry( 2, 4 );
var box_mask_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_mask = new THREE.Geometry();
var boxMesh_mask_1 = new THREE.Mesh(box_mask_1);
boxMesh_mask_1.position.z = 1;
var boxMesh_mask_2 = new THREE.Mesh(box_mask_2);
boxMesh_mask_2.rotation.y = Math.PI;
boxMesh_mask_2.position.z = -1;
boxMesh_mask_1.updateMatrix(); // as needed
singleGeometry_mask.merge(boxMesh_mask_1.geometry, boxMesh_mask_1.matrix);
boxMesh_mask_2.updateMatrix(); // as needed
singleGeometry_mask.merge(boxMesh_mask_2.geometry, boxMesh_mask_2.matrix);
var box_1_1 = new THREE.CircleGeometry( 2, 4 );
var box_1_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_1 = new THREE.Geometry();
var boxMesh_1_1 = new THREE.Mesh(box_1_1);
boxMesh_1_1.position.z = -1;
var boxMesh_1_2 = new THREE.Mesh(box_1_2);
boxMesh_1_2.rotation.y = Math.PI;
boxMesh_1_2.position.z = 1;
boxMesh_1_1.updateMatrix();
singleGeometry_1.merge(boxMesh_1_1.geometry, boxMesh_1_1.matrix);
boxMesh_1_2.updateMatrix();
singleGeometry_1.merge(boxMesh_1_2.geometry, boxMesh_1_2.matrix);
var box_2_1 = new THREE.CircleGeometry( 2, 4 );
var box_2_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_2 = new THREE.Geometry();
var boxMesh_2_1 = new THREE.Mesh(box_2_1);
boxMesh_2_1.position.z = -1;
var boxMesh_2_2 = new THREE.Mesh(box_2_2);
boxMesh_2_2.rotation.y = Math.PI;
boxMesh_2_2.position.z = 1;
boxMesh_2_1.updateMatrix();
singleGeometry_2.merge(boxMesh_2_1.geometry, boxMesh_2_1.matrix);
boxMesh_2_2.updateMatrix();
singleGeometry_2.merge(boxMesh_2_2.geometry, boxMesh_2_2.matrix);
const matColor = new THREE.MeshBasicMaterial({
color: 0x000000});
mesh1 = new THREE.Mesh(singleGeometry_1, matColor); // geometry, matColor);
scene.add(mesh1);
// flat mask
const matFlat = new THREE.MeshBasicMaterial({
color: 0x000000});
mesh2 = new THREE.Mesh(singleGeometry_mask, matFlat);
maskScene.add(mesh2);
const matColor2 = new THREE.MeshBasicMaterial({
color: 0xffffff});
mesh3 = new THREE.Mesh(singleGeometry_2, matColor2);
outScene.add(mesh3);
const matColor3 = new THREE.MeshBasicMaterial({
color: 0x000000});
bg_mesh = new THREE.Mesh(new THREE.CircleGeometry( 100, 4 ), matColor3);
outScene.add(bg_mesh);
bg_mesh.position.set(0, 0, -10);
};
var onWindowResize = function() {
screenWidth = window.innerWidth;
screenHeight = window.innerHeight;
camera1.aspect = screenWidth / screenHeight;
camera2.aspect = camera1.aspect;
camera3.aspect = camera1.aspect;
camera1.updateProjectionMatrix();
camera2.updateProjectionMatrix();
camera3.updateProjectionMatrix();
return renderer.setSize(screenWidth, screenHeight);
};
var animate = function() {
updateFps();
requestAnimationFrame(animate);
return render();
};
var render = function() {
const now = Date.now();
const delta = clock.getDelta();
if (mesh1) {
mesh1.rotation.y += 0.015;
mesh2.rotation.y = mesh1.rotation.y;
mesh3.rotation.y = mesh1.rotation.y;
}
return composer.render();
};
var updateFps = function() {
elapsedTime += clock.getDelta();
frameCount++;
if (elapsedTime >= 1) {
$('#fps').html(frameCount);
frameCount = 0;
return elapsedTime = 0;
}
};
init();
animate();
</script>
</body>
</html>
Just chiming in because I don't know the specifics of your situation but I have used the composer before...
What if you just add the texturePass after the maskPass and leave the renderPass1 as the next one after that?
The composer works by applying operations through a succession of buffers, so in between operations you sometimes have to do a texturePass to copy the current output back to the input for the next pass...
But this is just a guess, in case nobody else answers....

three.js r88 meshdepthmaterial there is no effect

I'm a new three.js men, and below is my code snippet...
In three.js docs said that the MeshDepthMaterial is drawing geometry by depth. Depth is based off of the camera near and far plane. White is nearest, black is farthest. But in my case, there is no effect for three.js r88, but three.js r 67. Can anybody please tell me why? Thanks very much...
<!DOCTYPE html>
<html>
<head>
<title>示例 04.02 - MeshDepthMaterial</title>
<script src="../build/three.js"></script>
<script src="../build/js/controls/OrbitControls.js"></script>
<script src="../build/js/libs/stats.min.js"></script>
<script src="../build/js/libs/dat.gui.min.js"></script>
<script src="../build/js/renderers/CanvasRenderer.js"></script>
<script src="../build/js/renderers/Projector.js"></script>
<script src="../jquery/jquery-3.2.1.min.js"></script>
<style>
body {
/* 设置 margin 为 0,并且 overflow 为 hidden,来完成页面样式 */
margin: 0;
overflow: hidden;
}
/* 统计对象的样式 */
#Stats-output {
position: absolute;
left: 0px;
top: 0px;
}
</style>
</head>
<body>
<!-- 用于 WebGL 输出的 Div -->
<div id="webgl-output"></div>
<!-- 用于统计 FPS 输出的 Div -->
<div id="stats-output"></div>
<!-- 运行 Three.js 示例的 Javascript 代码 -->
<script type="text/javascript">
var scene;
var camera;
var render;
var webglRender;
var canvasRender;
var controls;
var stats;
var guiParams;
var ground;
var cube;
var plane;
var sphere;
var meshMaterial;
var ambientLight;
var spotLight;
$(function() {
stats = initStats();
scene = new THREE.Scene();
scene.overrideMaterial = new THREE.MeshDepthMaterial({
morphTargets: true
});
webglRender = new THREE.WebGLRenderer( {antialias: true, alpha: true, logarithmicDepthBuffer: true} ); // antialias 抗锯齿
webglRender.setSize(window.innerWidth, window.innerHeight);
webglRender.setClearColor(0x000000, 1.0);
webglRender.shadowMap.enabled = true; // 允许阴影投射
render = webglRender;
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // 2147483647
camera.position.set(-50, 40, 50);
var target = new THREE.Vector3(0, 0 , 0);
controls = new THREE.OrbitControls(camera, render.domElement);
controls.target = target;
camera.lookAt(target);
$('#webgl-output')[0].appendChild(render.domElement);
window.addEventListener('resize', onWindowResize, false);
ambientLight = new THREE.AmbientLight(0x000000);
scene.add(ambientLight);
/** 用来保存那些需要修改的变量 */
guiParams = new function() {
this.rotationSpeed = 0.02;
this.near = 2;
this.far = 50;
this.addCube = function() {
for (var i=0; i<100; i++) {
// 定义 cube 几何
var cubeGeometry = new THREE.BoxGeometry(5, 5, 5);
// 定义网格材质
meshMaterial = new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff});
// 定义 cube 网格
cube = new THREE.Mesh(cubeGeometry, meshMaterial);
cube.castShadow = true;
cube.position.x = -60 + Math.round((Math.random() * 100));
cube.position.y = Math.round((Math.random() * 10));
cube.position.z = -100 + Math.round((Math.random() * 150));
// 默认加入 cube
scene.add(cube);
}
};
}
/** 定义 dat.GUI 对象,并绑定 guiParams 的几个属性 */
var gui = new dat.GUI();
gui.add(guiParams, 'addCube');
gui.add(guiParams, 'near', 0, 50).onChange(function(e) {
camera.near = e;
});
gui.add(guiParams, 'far', 5, 200).onChange(function(e) {
camera.far = e;
});
guiParams.addCube();
renderScene();
});
/** 渲染场景 */
function renderScene() {
stats.update();
rotateMesh(); // 旋转物体
requestAnimationFrame(renderScene);
render.render(scene, camera);
}
/** 初始化 stats 统计对象 */
function initStats() {
stats = new Stats();
stats.setMode(0); // 0 为监测 FPS;1 为监测渲染时间
$('#stats-output').append(stats.domElement);
return stats;
}
/** 当浏览器窗口大小变化时触发 */
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
render.setSize(window.innerWidth, window.innerHeight);
}
/** 旋转物体 */
function rotateMesh() {
scene.traverse(function(mesh) {
if (mesh instanceof THREE.Mesh) {
mesh.rotation.x += guiParams.rotationSpeed;
mesh.rotation.y += guiParams.rotationSpeed;
mesh.rotation.z += guiParams.rotationSpeed;
}
});
}
</script>
</body>
</html>
When you change camera.near or camera.far you need to call:
camera.updateProjectionMatrix();
three.js r.88

webGL readPixels and FireFox 35

I have updated to FireFox35 and the following code is not working anymore:
var ctx = renderer2.getContext("experimental-webgl",{preserveDrawingBuffer: true}) || renderer2.getContext("webgl",{preserveDrawingBuffer: true});
renderer2.render(scene2, camera2, renderTarget);
var arr = new Uint8Array( 4 * 1024 * 1024);
ctx.readPixels(0, 0, 1024, 1024, ctx.RGBA, ctx.UNSIGNED_BYTE, arr);
Thre returned array is completely black. It work until FireFox 34 to return the webGL canvas snapshot and it is still working in IE and Chrome.
Is there a workaround, or another way to get the pixel data from a webGL canvas?
A bug has been opened #Bugzilla. It seems to be a regression.
Example:
http://codepen.io/anon/pen/XJMQwV
<!DOCTYPE html>
<html lang="en">
<head>
<title> </title>
<style>
body {
background-color: #000;
color: #000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/threejs/r69/three.min.js"></script>
<script>
var renderer, camera, renderTarget;
var scene, element;
var ambient;
function createPIP(){
}
function init(){
pip = document.createElement('div');
pip.id = "divPIP";
pip.style.width = 512;
pip.style.height = 512;
pip.style.position = 'absolute';
pip.style.backgroundColor = 'black';
pip.style.borderRadius = "5px";
pip.style.border = '2px solid white';
pip.style.padding = "0px 20px";
pip.style.left = "50px";
pip.style.top = "25px";
document.body.appendChild(pip);
pip2 = document.createElement('div');
pip2.id = "divpip2";
pip2.style.width = 512;
pip2.style.height = 512;
pip2.style.position = 'absolute';
pip2.style.backgroundColor = 'black';
pip2.style.borderRadius = "5px";
pip2.style.border = '2px solid white';
pip2.style.padding = "0px 20px";
pip2.style.left = "650px";
pip2.style.top = "25px";
document.body.appendChild(pip2);
canvaspip2 = document.createElement('canvas');
canvaspip2.width = 512;
canvaspip2.height = 512;
canvaspip2.id = "canvaspip2";
pip2.appendChild(canvaspip2);
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setSize(512, 512);
pip.appendChild(renderer.domElement);
renderTarget = new THREE.WebGLRenderTarget( 512, 512 );
var ambient = new THREE.AmbientLight( 0xffffff );
scene.add( ambient );
camera = new THREE.OrthographicCamera( -256, 256, 256, -256, 1, 1e6 );
scene.add(camera);
camera.position.set(0, 0, 500);
cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200 ), new THREE.MeshNormalMaterial() );
scene.add(cube);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
var ctx = renderer.getContext("experimental-webgl",{preserveDrawingBuffer: true}) || renderer.getContext("webgl",{preserveDrawingBuffer: true});
renderer.render(scene, camera, renderTarget);
var arr = new Uint8Array( 4 * 512 * 512);
ctx.readPixels(0, 0, 512, 512, ctx.RGBA, ctx.UNSIGNED_BYTE, arr);
var c=document.getElementById("canvaspip2");
var ctx=c.getContext("2d");
var ImgData = ctx.createImageData(512, 512);
ImgData.data.set( arr, 0, arr.length );
var c=document.getElementById("canvaspip2");
var ctx=c.getContext("2d");
ctx.putImageData(ImgData,0,0);
renderer.autoClear = false;
renderer.clear();
renderer.render(scene, camera);
}
window.onload = function() {
init();
animate();
}
</script>
</body>
</html>

Can't get first person controls works

I'm starting with Three.js, and I'm trying to set up a simple first person controls in my scene, which is containing a single sphere. I just see a black screen. There are no errors.
Without FirstPersonControls, I can see the sphere.
What am I doing wrong ?
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
#container {
width: 400px;
height: 300px;
}
</style>
<script type="text/javascript" src="js/Three.js"></script>
<script type="text/javascript">
var controls;
window.onload = function() {
var RENDER_WIDTH = 400, RENDER_HEIGHT = 300;
// Creating scene
var scene = new THREE.Scene();
// Camera
var camera = new THREE.PerspectiveCamera(45, RENDER_WIDTH / RENDER_HEIGHT, 0.1, 10000);
camera.position.z = 300;
scene.add(camera);
controls = new THREE.FirstPersonControls(camera);
controls.movementSpeed = 1000;
controls.lookSpeed = 0.125;
controls.lookVertical = true;
// Sphere
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x00ff00
});
var radius = 50, segments = 16, rings = 16;
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(radius, segments, rings),
sphereMaterial
);
scene.add(sphere);
// Light
scene.add(new THREE.AmbientLight(0x333333));
var light = new THREE.PointLight(0xffffff, 0.9);
light.position.set(50, 200, 50);
scene.add(light);
// Render
var container = document.getElementById('container');
var renderer = new THREE.WebGLRenderer();
renderer.setSize(RENDER_WIDTH, RENDER_HEIGHT);
renderer.setClearColorHex(0x000000, 1);
container.appendChild(renderer.domElement);
var clock = new THREE.Clock();
setInterval(function() {
var delta = clock.getDelta();
controls.update(delta);
renderer.render(scene, camera);
}, 100);
};
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
FirstPersonControls is designed to work with full-width canvases, so you need to set
var RENDER_WIDTH = window.innerWidth, RENDER_HEIGHT = window.innerHeight;
Also remove you style settings.
Finally, to make it easier to "find" your sphere, set controls.lookVertical = false -- just for now.
From that point, you'll just have to experiment.

Resources