three.js r88 meshdepthmaterial there is no effect - three.js

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

Related

I need to zoom on an object upon hover

I want something like this:
https://drive.google.com/file/d/1v_4M59Ny93QwT52unfM9N_tfzo3xRAq1/view?usp=share_link
This is my code
<!DOCTYPE html>
<html>
<head>
<title>Three.js JPG Background with Custom Position</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"></script>
<script src="./js/tween.js/dist/tween.umd.js"></script>
<!-- Css -->
<style>
body {
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
}
</style>
</head>
<body>
<script>
// Initialize Three.js scene
var scene = new THREE.Scene();
var camera = new THREE.OrthographicCamera(window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 0.1,);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Load the Main BG texture
var mainBg = new THREE.TextureLoader().load("http://127.0.0.1:5500/img/main-bg.jpg");
// Create a full-screen plane to display the texture
var geometry1 = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight);
var material1 = new THREE.MeshBasicMaterial({ map: mainBg });
var plane1 = new THREE.Mesh(geometry1, material1);
plane1.position.set(0, 0, 0)
scene.add(plane1);
// Create a full-screen plane to display the texture
var frame1 = new THREE.TextureLoader().load("http://127.0.0.1:5500/img/frame1.png");
var geometry2 = new THREE.PlaneGeometry(90, 110);
var material2 = new THREE.MeshBasicMaterial({ map: frame1 });
var plane2 = new THREE.Mesh(geometry2, material2);
plane2.position.set(-190, 130, .1);
scene.add(plane2);
// Check if mouse is over the child asset
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var zoomed = false;
// Mouse move function
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects([plane2]);
if (intersects.length > 0 && !zoomed) {
zoomed = true;
camera.position.set(plane2.position.x, plane2.position.y, plane2.position.z);
camera.lookAt(plane2.position.x, plane2.position.y, plane2.position.z);
} else if (intersects.length === 0 && zoomed) {
zoomed = false;
camera.position.set(0, 0, 5);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
}
// Mouse move function calling on moving mouse
document.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mousedown', function () {
gsap.to(camera.position, {
z: 15,
duration: 15
});
})
// Render loop
function render() {
camera.position.z = 5;
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>
assets:
frame1
and
main-bg
i made frame 1 on the center of the screen by hovering it but cannot make camera to zoom in on it. I tried tween but I think there is something wrong in the basics of my code
Sorry i am new to this and this is my first threejs project
You can apply a mousemove event on the canvas and use event.clientX or event.clientY to read live mouse pointer values. These values can then be used within the the listener to update values of camera.position.z to change zoom.

Display loaded OBJ model in wireframe mode in three.js

I wanted to display my loaded .obj file in wireframe mode..
I got to know about the WireFrameGeometry But for somereason the .mtl texture only gets display .
Below is the code ..
/* Model */
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl('assets/');
mtlLoader.setPath('assets/');
mtlLoader.load('materialfile.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('Objectfile.obj', function(object) {
object.traverse(function(child) {
if (child.isMesh) {
var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
var wireframeMaterial = new THREE.LineBasicMaterial({
color: 0xffffff
});
var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
child.add(wireframe);
}
});
scene.add(object);
});
});
I only want the wireframe of the model without any fill..
Thanks in advance.
The entire code is below...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="three.js"></script>
<script src="TrackballControls.js"></script>
<script src="cannon.js"></script>
<script src="Detector.js"></script>
<script src="OrbitControls.js"></script>
<script src="OBJLoader.js"></script>
<script src="MTLLoader.js"></script>
</head>
<body>
<script>
if (!Detector.webgl) {
Detector.addGetWebGLMessage();
}
var container;
var camera, controls, scene, renderer;
var lighting, ambient, keyLight, fillLight, backLight;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
/* Camera */
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 50;
/* Scene */
scene = new THREE.Scene();
lighting = false;
ambient = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambient);
// keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
// keyLight.position.set(-100, 0, 100);
// fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
// fillLight.position.set(100, 0, 100);
// backLight = new THREE.DirectionalLight(0xffffff, 1.0);
// backLight.position.set(100, 0, -100).normalize();
/* Model */
// var mtlLoader = new THREE.MTLLoader();
// mtlLoader.setBaseUrl('assets/');
// mtlLoader.setPath('assets/');
// mtlLoader.load('mtlfile.mtl', function(materials) {
// materials.preload();
// materials.materials.default.map.magFilter = THREE.NearestFilter;
// materials.materials.default.map.minFilter = THREE.LinearFilter;
var objLoader = new THREE.OBJLoader();
// objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('objectfile.obj', function(object) {
object.traverse(function(child) {
if (child.isMesh) {
var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
var wireframeMaterial = new THREE.LineBasicMaterial({
color: 0xeeeeee
});
var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
// add to child so we get same orientation
child.add(wireframe);
// to parent of child. Using attach keeps our orietation
child.parent.attach(wireframe);
// remove child (we don't want child)
child.parent.remove(child);
}
});
scene.add(object);
});
// });
/* Renderer */
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color("hsl(0, 0%, 10%)"));
container.appendChild(renderer.domElement);
/* Controls */
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
controls.autoRotate = true;
/* Events */
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();
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
</body>
</html>
So this is the entire code..
Its just the basic obj loader ..
I don't know whether the problem is in the code or model .
It shows as a fully filled white model
object.traverse(function(child) {
if (child.isMesh) {
child.material.wireframe = true;
}
}
This worked for me
objLoader.load('Objectfile.obj', function(object) {
object.traverse(function(child) {
if (child.isMesh) {
var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
var wireframeMaterial = new THREE.LineBasicMaterial({
color: 0xffffff
});
var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
// add to child so we get same orientation
child.add(wireframe);
// to parent of child. Using attach keeps our orietation
child.parent.attach(wireframe);
// remove child (we don't want child)
child.parent.remove(child);
}
});
scene.add(object);
});
Example:
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
<canvas id="c"></canvas>
<script type="module">
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
import {OrbitControls} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/controls/OrbitControls.js';
import {OBJLoader2} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader2.js';
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 10, 20);
const controls = new OrbitControls(camera, canvas);
controls.target.set(0, 5, 0);
controls.update();
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
{
const objLoader = new OBJLoader2();
objLoader.load('https://threejsfundamentals.org/threejs/resources/models/windmill/windmill.obj', (root) => {
root.traverse(child => {
if (child.isMesh) {
var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
var wireframeMaterial = new THREE.LineBasicMaterial({
color: 0xffffff
});
var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
child.add(wireframe);
child.parent.attach(wireframe);
child.parent.remove(child);
}
});
scene.add(root);
});
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
</script>
You can also do it the way manthrax suggested except you need to check if child.material is an array or not, then for each material remove the map (so the texture is not used) and set emissive to some color (you might also want to set color to black)`.
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
<canvas id="c"></canvas>
<script type="module">
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
import {OrbitControls} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/controls/OrbitControls.js';
import {OBJLoader2} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader2.js';
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 10, 20);
const controls = new OrbitControls(camera, canvas);
controls.target.set(0, 5, 0);
controls.update();
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
function makeWireframe(material) {
material.wireframe = true;
material.emissive.set('#0FF');
material.map = undefined;
}
{
const objLoader = new OBJLoader2();
objLoader.load('https://threejsfundamentals.org/threejs/resources/models/windmill/windmill.obj', (root) => {
root.traverse(child => {
if (child.isMesh) {
if (Array.isArray(child.material)) {
child.material.forEach(makeWireframe);
} else {
makeWireframe(child.material)
}
}
});
scene.add(root);
});
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
</script>

Guidance required for this handle shape in ThreeJS

I have to create this handle shape in ThreeJS:
I've imagined it as being a combination of a plane geometry and a twisted/squashed cone at each end with a smaller z position than the rest of the object.
I think it'd be simpler to create just one Shape for this rather than attempting to merge meshes together. Here's what I have so far:
(function onLoad() {
var container, camera, scene, renderer;
init();
animate();
function init() {
container = document.getElementById('container');
initScene();
addGridHelper();
addCamera();
addRenderer();
addOrbitControls();
var knottedRibbonHandleTwo = createKnottedRibbonHandleTwo();
knottedRibbonHandleTwo.position.x -= 250;
scene.add(knottedRibbonHandleTwo);
var sceneLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
scene.add(sceneLight);
}
function createKnottedRibbonHandleTwo() {
var belt = new THREE.Shape();
belt.moveTo(0, 0);
belt.lineTo(25, 0);
belt.lineTo(25, 2.5);
belt.lineTo(0, 2.5);
var extrudeSettings = {
steps: 1,
amount: 1,
bevelEnabled: false,
bevelThickness: 1,
bevelSize: 1,
bevelSegments: 1
};
var geometry = new THREE.ExtrudeGeometry(belt, extrudeSettings);
var material = new THREE.MeshPhongMaterial({
color: 0xffd700,
wireframe: false
});
var mesh = new THREE.Mesh(geometry, material);
mesh.scale.multiplyScalar(20);
return mesh;
}
/**** Basic Scene Setup ****/
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
}
function addCamera() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(349.11334070460066, 405.44010726325604, 359.3111192889029);
scene.add(camera);
}
function addGridHelper() {
var planeGeometry = new THREE.PlaneGeometry(2000, 2000);
planeGeometry.rotateX(-Math.PI / 2);
var planeMaterial = new THREE.ShadowMaterial({
opacity: 0.2
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.y = -200;
plane.receiveShadow = true;
scene.add(plane);
var helper = new THREE.GridHelper(2000, 100);
// helper.position.y = -199;
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper();
scene.add(axis);
}
function addRenderer() {
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
}
function addOrbitControls() {
var controls = new THREE.OrbitControls(camera, renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
})();
body {
background: transparent;
padding: 0;
margin: 0;
font-family: sans-serif;
}
#canvas {
margin: 10px auto;
width: 800px;
height: 350px;
margin-top: -44px;
}
<body>
<div id="container"></div>
<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
</body>
But I'm confused as to how I'd achieve the end parts.
Thanks.
Creativity is up to you. You can create any shape you want. I just modified your snippet a bit:
(function onLoad() {
var container, camera, scene, renderer;
init();
animate();
function init() {
container = document.getElementById('container');
initScene();
addGridHelper();
addCamera();
addRenderer();
addOrbitControls();
var knottedRibbonHandleTwo = createKnottedRibbonHandleTwo();
knottedRibbonHandleTwo.position.x -= 250;
scene.add(knottedRibbonHandleTwo);
var sceneLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
scene.add(sceneLight);
}
function createKnottedRibbonHandleTwo() {
var belt = new THREE.Shape();
belt.moveTo(0, 1.25);
belt.lineTo(1.25, 0.5);
belt.lineTo(2.5, 0);
belt.lineTo(22.5, 0);
belt.lineTo(23.75, 0.5);
belt.lineTo(25, 1.25);
belt.lineTo(23.75, 2);
belt.lineTo(22.5, 2.5);
belt.lineTo(2.5, 2.5);
belt.lineTo(1.25, 2);
var extrudeSettings = {
steps: 1,
amount: .25,
bevelEnabled: false,
bevelThickness: 1,
bevelSize: 1,
bevelSegments: 1
};
var geometry = new THREE.ExtrudeGeometry(belt, extrudeSettings);
var material = new THREE.MeshPhongMaterial({
color: 0xffd700,
wireframe: false
});
var mesh = new THREE.Mesh(geometry, material);
mesh.scale.setScalar(20);
return mesh;
}
/**** Basic Scene Setup ****/
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
}
function addCamera() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(349.11334070460066, 405.44010726325604, 359.3111192889029);
scene.add(camera);
}
function addGridHelper() {
var planeGeometry = new THREE.PlaneGeometry(2000, 2000);
planeGeometry.rotateX(-Math.PI / 2);
var planeMaterial = new THREE.ShadowMaterial({
opacity: 0.2
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.y = -200;
plane.receiveShadow = true;
scene.add(plane);
var helper = new THREE.GridHelper(2000, 100);
// helper.position.y = -199;
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper();
scene.add(axis);
}
function addRenderer() {
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
}
function addOrbitControls() {
var controls = new THREE.OrbitControls(camera, renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
})();
body {
background: transparent;
padding: 0;
margin: 0;
font-family: sans-serif;
}
#canvas {
margin: 10px auto;
width: 800px;
height: 350px;
margin-top: -44px;
}
<body>
<div id="container"></div>
<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
</body>

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>

Pan is the only working thing for OrbitControls

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>

Resources