How to render geojson with three.js and d3.js - d3.js

I use three.js r49, d3.v2.js and d3-threeD.js i want to render my city(Mashhad) with three.js
but i got a problem i can render europian countries with these codes but i cant render with existing json file.
d3.js Ref
d3-threeD.js Ref
these are my codes:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>GEO Bar</title>
<link rel="stylesheet" href="">
<script type="text/javascript" src="./scripts/jquery-1.7.2.js"></script>
<script type="text/javascript" src="./scripts/d3.v2.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/three.js/r49/Three.min.js"></script>
<script type="text/javascript" src="./scripts/d3-threeD.js"></script>
<script type="text/javascript" src="./scripts/constants.js"></script>
<script type="text/javascript" src="./scripts/util-geo.js"></script>
<script type="text/javascript" src="./scripts/script.js"></script>
<style type="text/css">
.btns{
position: fixed;
right: 100px;
top: 100px;
}
.btn{
width: 40px;
height: 60px;
background-color: #999;
margin-top: 5px;
text-align: center;
color: #111;
}
.btn > div{
margin-bottom: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="chart"></div>
<div class="btns">
<div class="btn x">
<div class="plus">+</div>X
<div class="minus">-</div>
</div>
<div class="btn y">
<div class="plus">+</div>Y
<div class="minus">-</div>
</div>
<div class="btn z">
<div class="plus">+</div>Z
<div class="minus">-</div>
</div>
</div>
</body>
</html>
constants.js codes:
var appConstants = {
TRANSLATE_0 : -360,
TRANSLATE_1 : 10040,
SCALE : 60000
}
util-geo.js codes:
var geons = {};
geons.geoConfig = function() {
this.TRANSLATE_0 = appConstants.TRANSLATE_0;
this.TRANSLATE_1 = appConstants.TRANSLATE_1;
this.SCALE = appConstants.SCALE;
this.mercator = d3.geo.mercator();
this.path = d3.geo.path().projection(this.mercator);
this.setupGeo = function() {
var translate = this.mercator.translate();
translate[0] = this.TRANSLATE_0;
translate[1] = this.TRANSLATE_1;
this.mercator.translate(translate);
this.mercator.scale(this.SCALE);
}
console.log(2,this.path);
}
// geoConfig contains the configuration for the geo functions
geo = new geons.geoConfig();
script.js codes:
(function($) {
$(function(){
// get the correct geo for d3s
geo.setupGeo();
var
dataURL = "area.json",
scene,
renderer,
camera;
btnXPlus = $(".btns .x .plus"),
btnXMinus = $(".btns .x .minus"),
btnYPlus = $(".btns .y .plus"),
btnYMinus = $(".btns .y .minus"),
btnZPlus = $(".btns .z .plus"),
btnZMinus = $(".btns .z .minus"),
translate = geo.mercator.translate();
// get the data
$.getJSON( dataURL, function(data, textStatus, jqXHR) {
initScene();
addGeoObject();
renderer.render( scene, camera );
// Set up the three.js scene. This is the most basic setup without
// any special stuff
function initScene() {
// set the scene size
var
WIDTH = 600,
HEIGHT = 600;
// set some camera attributes
var
VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 1, FAR = 10000;
// create a WebGL renderer, camera, and a scene
renderer = new THREE.WebGLRenderer({antialias:true});
camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
scene = new THREE.Scene();
// add and position the camera at a fixed position
scene.add(camera);
camera.position.z = 550;
camera.position.x = 0;
camera.position.y = 550;
console.log("scene.position: ",scene.position);
camera.lookAt( scene.position );
// start the renderer, and black background
renderer.setSize(WIDTH, HEIGHT);
renderer.setClearColor(0x321);
// add the render target to the page
$("#chart").append(renderer.domElement);
// add a light at a specific position
var pointLight = new THREE.PointLight(0xFFFFFF);
scene.add(pointLight);
pointLight.position.x = 800;
pointLight.position.y = 800;
pointLight.position.z = 800;
// add a base plane on which we'll render our map
var planeGeo = new THREE.PlaneGeometry(10000, 10000, 10, 10);
var planeMat = new THREE.MeshLambertMaterial({color: 0x666699});
var plane = new THREE.Mesh(planeGeo, planeMat);
// rotate it to correct position
plane.rotation.x = -Math.PI/2;
scene.add(plane);
console.log(1);
}
// add the loaded gis object (in geojson format) to the map
function addGeoObject() {
// keep track of rendered objects
var meshes = [];
var colors = [];
var averageValues = [];
var totalValues = [];
// keep track of min and max, used to color the objects
var maxValueAverage = 0;
var minValueAverage = -1;
// keep track of max and min of total value
var maxValueTotal = 0;
var minValueTotal = -1;
// convert to mesh and calculate values
for (var i = 0 ; i < data.features.length ; i++) {
console.log(data.features[i]);
var geoFeature = data.features[i];
var feature = geo.path(geoFeature);
console.log("feature:",feature);
// we only need to convert it to a three.js path
var mesh = transformSVGPathExposed(feature);
console.log(mesh);
// add to array
meshes.push(mesh);
// we get a property from the json object and use it
// to determine the color later on
var value = parseInt(geoFeature.properties.bev_dichth);
if (value > maxValueAverage) maxValueAverage = value;
if (value < minValueAverage || minValueAverage == -1) minValueAverage = value;
averageValues.push(value);
// var style = JSON.parse(geoFeature.properties.style);
// colors.push(hexToRgb(style.strokeColor));
// colors.push(style.strokeColor);
// and we get the max values to determine height later on.
value = parseInt(geoFeature.properties.aant_inw);
if (value > maxValueTotal) maxValueTotal = value;
if (value < minValueTotal || minValueTotal == -1) minValueTotal = value;
totalValues.push(value);
}
console.log(averageValues,totalValues,colors);
// we've got our paths now extrude them to a height and add a color
for (var i = 0 ; i < averageValues.length ; i++) {
// create material color based on average
var scale = ((averageValues[i] - minValueAverage) / (maxValueAverage - minValueAverage)) * 255;
var mathColor = gradient(Math.round(scale),255);
console.log(scale,mathColor);
var material = new THREE.MeshLambertMaterial({
color: mathColor
});
// var material = new THREE.MeshLambertMaterial({
// // color: hexToRgb(colors[i])
// });
// material.color.setHex(colors[i]);
console.log("material:", material);
// create extrude based on total
var extrude = ((totalValues[i] - minValueTotal) / (maxValueTotal - minValueTotal)) * 100;
var shape3d = meshes[i].extrude({amount: Math.round(extrude), bevelEnabled: false});
console.log("extrude: ",extrude, "shape3d:", shape3d);
// create a mesh based on material and extruded shape
var toAdd = new THREE.Mesh(shape3d, material);
// rotate and position the elements nicely in the center
toAdd.rotation.x = Math.PI/2;
toAdd.translateX(-490);
toAdd.translateZ(50);
toAdd.translateY(extrude/2);
console.log("toAdd: ",toAdd);
// add to scene
scene.add(toAdd);
}
}
// simple gradient function
// function gradient(length, maxLength) {
// var i = (length * 255 / maxLength);
// var r = i;
// var g = 255-(i);
// var b = 0;
// var rgb = b | (g << 8) | (r << 16);
// console.log(rgb);
// return rgb;
// }
function gradient(color, maxLength) {
var i = (length * 255 / maxLength);
var r = i;
var g = 255-(i);
var b = 0;
var rgb = b | (g << 8) | (r << 16);
console.log("rgb: ",rgb);
return rgb;
}
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
// return result ? {
// r: parseInt(result[1], 16),
// g: parseInt(result[2], 16),
// b: parseInt(result[3], 16)
// } : null;
return result ? parseInt(result[1], 16) | (parseInt(result[2], 16) << 8) | (parseInt(result[3], 16) << 16) : null;
}
});
btnXPlus.click(function(){
camera.position.x +=10;
console.log(camera.position.x);
renderer.render( scene, camera );
});
btnXMinus.click(function(){
camera.position.x -=10;
console.log(camera.position.x);
renderer.render( scene, camera );
});
btnYPlus.click(function(){
camera.position.y +=10;
console.log(camera.position.y);
renderer.render( scene, camera );
});
btnYMinus.click(function(){
camera.position.x -=10;
console.log(camera.position.y);
renderer.render( scene, camera );
});
btnZPlus.click(function(){
camera.position.z +=10;
console.log(camera.position.z);
renderer.render( scene, camera );
});
btnZMinus.click(function(){
camera.position.z -=10;
console.log(camera.position.z);
renderer.render( scene, camera );
});
});
})(jQuery);
my geo json file: omidgharib.ir/area.json

Related

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

Three JS - Uncaught TypeError: Cannot read property 'length' of undefined at THREE.JSONLoader.parse

I'm trying to just render a blender exported json(exported to use in three js). I'm doing that as follows.
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Three.js JSON Loader Demo</title>
<script type="text/javascript" src="three.min.js"></script>
<script type="text/javascript">
var renderer; // A three.js WebGL or Canvas renderer.
var scene; // The 3D scene that will be rendered, containing the model.
var camera; // The camera that takes the picture of the scene.
var light; // A light shining from the direction of the camera.
var model; // The three.js object that represents the model.
var rotateX = 0; // rotation of model about the x-axis
var rotateY = 0; // rotation of model about the y-axis
function modelLoadedCallback(geometry, materials) {
var object = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
/* Determine the ranges of x, y, and z in the vertices of the geometry. */
var xmin = Infinity;
var xmax = -Infinity;
var ymin = Infinity;
var ymax = -Infinity;
var zmin = Infinity;
var zmax = -Infinity;
for (var i = 0; i < geometry.vertices.length; i++) {
var v = geometry.vertices[i];
if (v.x < xmin)
xmin = v.x;
else if (v.x > xmax)
xmax = v.x;
if (v.y < ymin)
ymin = v.y;
else if (v.y > ymax)
ymax = v.y;
if (v.z < zmin)
zmin = v.z;
else if (v.z > zmax)
zmax = v.z;
}
/* translate the center of the object to the origin */
var centerX = (xmin+xmax)/2;
var centerY = (ymin+ymax)/2;
var centerZ = (zmin+zmax)/2;
var max = Math.max(centerX - xmin, xmax - centerX);
max = Math.max(max, Math.max(centerY - ymin, ymax - centerY) );
max = Math.max(max, Math.max(centerZ - zmin, zmax - centerZ) );
var scale = 10/max;
object.position.set( -centerX, -centerY, -centerZ );
console.log("Loading finished, scaling object by " + scale);
console.log("Center at ( " + centerX + ", " + centerY + ", " + centerZ + " )");
/* Create the wrapper, model, to scale and rotate the object. */
model = new THREE.Object3D();
model.add(object);
model.scale.set(scale,scale,scale);
rotateX = rotateY = 0;
scene.add(model);
render();
}
function render() {
renderer.render(scene, camera);
}
function init() {
try {
var theCanvas = document.getElementById("cnvs");
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, theCanvas.width/theCanvas.height, 0.1, 100);
camera.position.z = 30;
light = new THREE.DirectionalLight();
light.position.set(0,0,1);
renderer = new THREE.WebGLRenderer( {
canvas: theCanvas,
antialias: true
} );
scene.add(light);
render();
var loader = new THREE.JSONLoader();
loader.load("DummyBox.js", modelLoadedCallback);
}
catch (e) {
document.getElementById("message").innerHTML = "Sorry, an error occurred: " + e;
}
}
</script>
</head>
<body onload="init()" bgcolor="#CCC">
<noscript>
<p style="color: #A00; font-weight: bold">Sorry, but this page requires JavaScript!</p>
</noscript>
<div style="float:left">
<canvas width=350 height=400 id="cnvs" style="background-color:black"></canvas>
</div>
</body>
</html>
The Contents of DummyBox.js is
{
"metadata":{
"generator":"io_three",
"type":"BufferGeometry",
"normal":36,
"version":3,
"position":36
},
"data":{
"index":{
"type":"Uint16Array",
"itemSize":1,
"array":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35]
},
"attributes":{
"position":{
"type":"Float32Array",
"itemSize":3,
"array":[1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,0.999999,1,1,1,1,-1,1,1,-1,1,-1,1,1,-1,-1,0.999999,1,1,-1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,0.999999,1,1,1,1,-1,0.999999,1,1,1,-1,1,0.999999,1,1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1]
},
"normal":{
"type":"Float32Array",
"itemSize":3,
"array":[-7.10543e-15,-1,2.98023e-08,-7.10543e-15,-1,2.98023e-08,-7.10543e-15,-1,2.98023e-08,7.10543e-15,1,-2.98023e-08,7.10543e-15,1,-2.98023e-08,7.10543e-15,1,-2.98023e-08,1,-2.38419e-07,7.10543e-15,1,-2.38419e-07,7.10543e-15,1,-2.38419e-07,7.10543e-15,-5.96046e-08,-2.98023e-07,1,-5.96046e-08,-2.98023e-07,1,-5.96046e-08,-2.98023e-07,1,-1,-1.49012e-07,-2.38419e-07,-1,-1.49012e-07,-2.38419e-07,-1,-1.49012e-07,-2.38419e-07,2.38419e-07,1.78814e-07,-1,2.38419e-07,1.78814e-07,-1,2.38419e-07,1.78814e-07,-1,-1.77636e-15,-1,2.98023e-08,-1.77636e-15,-1,2.98023e-08,-1.77636e-15,-1,2.98023e-08,1.5099e-14,1,-2.98023e-08,1.5099e-14,1,-2.98023e-08,1.5099e-14,1,-2.98023e-08,1,3.27825e-07,5.66244e-07,1,3.27825e-07,5.66244e-07,1,3.27825e-07,5.66244e-07,-5.0664e-07,1.49012e-07,1,-5.0664e-07,1.49012e-07,1,-5.0664e-07,1.49012e-07,1,-1,-1.19209e-07,-2.08616e-07,-1,-1.19209e-07,-2.08616e-07,-1,-1.19209e-07,-2.08616e-07,2.38419e-07,1.78814e-07,-1,2.38419e-07,1.78814e-07,-1,2.38419e-07,1.78814e-07,-1]
}
}
}
}
I'm new to Three js and not able to figure out what is the problem. Is there any website i can go through.. Is there any problem in Exported JSON file.
The json script looks ok.
If you replace the loader class ( as already mentioned by #TheJim01 )
var loader = new THREE.BufferGeometryLoader(); //new THREE.JSONLoader();
and handle the geometry like this in the modelLoadedCallback function (more here):
var geometry = new THREE.Geometry().fromBufferGeometry(geometry);
you will go through without errors.
PS. The materials parameter in modelLoadedCallback function is undefined.
You can define it like this:
var materials = new THREE.MeshLambertMaterial({color:0xff0000});

Three.js Updating DataTextures with a renderTarget's image data

I am working on a motion detection program in Three.js which uses the difference between the current and previous frame. For now, before the subtraction, the current and the previous frame are both blurred using a Three.EffectComposer each.
The main problem is: Instead of having to blur the previous frame again, I want to use the previously blurred "current" frame as the texture in the subtraction process.
The closest I have managed to do is by using the function below to update the image.data of the Three.DataTexture. It was used in the render()-function after the Blurring composer is rendered, but before the subtraction is rendered.
Both of them were rendered to the screen with Three.CopyShader.
function getData(image) {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
return new Uint8Array(context.getImageData(0, 0, image.width, image.height).data);
}
Where the “image” is the renderer.domElement. This method feels quite inefficient and I needed to render the Blur-pass to the screen, which caused the result to flicker.
Edit 1 The current code is shown below, it blurs the current and previous images and then calculates the difference. The animate()-function is the point of interest.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Three.js Webcam Test</title>
<meta charset="utf-8">
<!-- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="lib/three.min.js"></script>
<!-- Effect composer scripts -->
<script src = "postprocessing/EffectComposer.js"></script>
<script src = "postprocessing/MaskPass.js"></script>
<script src = "postprocessing/RenderPass.js"></script>
<script src = "postprocessing/TexturePass.js"></script>
<script src = "postprocessing/ShaderPass.js"></script>
<script src = "postprocessing/SavePass.js"></script>
<script src = "shaders/CopyShader.js"></script>
<script src = "shaders/ColorifyShader.js"></script>
<script src = "shaders/DilationShader.js"></script>
<script src = "shaders/ErosionShader.js"></script>
<script src = "shaders/HorizontalBlurShader.js"></script>
<script src = "shaders/VerticalBlurShader.js"></script>
<script src = "shaders/BlendShader.js"></script>
<script src = "shaders/passThroughShader.js"></script>
<script src = "shaders/framediffShader.js"></script>
<script src = "shaders/PawaskarPostShader.js"></script>
<!-- ----------------------- -->
<script src="lib/Projector.js"></script>
<script src="lib/CanvasRenderer.js"></script>
<script src="lib/webcam.js"></script>
<script src="lib/perspective.js"></script>
<script src="lib/stats.min.js"></script>
<script src="lib/rStats.js"></script>
<script src="lib/rStats.extras.js"></script>
<script type="text/javascript" src="lib/dat.gui.min.js"></script>
<link href="css/style.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="http://bootswatch.com/lumen/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1>Motion Detection (in progress)</h1>
<p>Press P to print the current frame</p>
<div id="WebGL-output">
</div>
<div id="camera" class="camera">
<div class="label"></div>
<video id="theVideo" autoplay width="640" height="480" class="webcam"></video>
<canvas id="theCanvas" width="640" height="480" class="hidden"></canvas>
</div>
<script>
var SCREEN_HEIGHT = 480;
var SCREEN_WIDTH = 640;
var values = {
detectmotion: true,
softness: 0.17,
threshold: 0.11,
color: "#ffae23",
usecolor: false,
postprocess: false,
postprocessmethod: 0,
preprocess: true,
detectedges: false,
framedifference: false,
binarydifference: false,
bufferlength: 1
};
var stats, container, video, renderer, currTexture, uniforms, camera, scene, prevTexture, prevTexture2, prevTexture3, prevTextureBuffer = [], bufferLenght,
videoContext,
prevTime;
var rS, glS, tS;
var postProcessFilters = [];
var prepScene, prepRenderTarget, prepComposer, prepPrevComposer, hBlur, vBlur, temporalShader, prevTemporalShader, prevBlur;
var modelScene, modelRenderTarget, modelComposer, passShader;
var subtractScene, subtractRenderTarget,subtractComposer, subtractShader;
//GUI variables
var gui, cPostProcessMethod, doPostProcess = false;
var frameNumber;
/** TEST **/
var BlurSave;
function init(){
frameNumber = 0;
/* INIT */
scene = new THREE.Scene();
camera = new THREE.Camera();
scene.add(camera);
webcam.updateSources(function(s){
webcam.start('theVideo',s[0]);
});
var size = SCREEN_WIDTH * SCREEN_HEIGHT;
video = document.getElementById( 'theVideo' );
videoContext = document.getElementById('theCanvas').getContext('2d');
//The textures
currTexture = new THREE.DataTexture([],SCREEN_WIDTH,SCREEN_HEIGHT);
prevTexture = new THREE.DataTexture([],SCREEN_WIDTH,SCREEN_HEIGHT);
prevBlur = new THREE.DataTexture([], SCREEN_WIDTH, SCREEN_HEIGHT);
currTexture.minFilter = prevTexture.minFilter = prevBlur.minFilter= THREE.LinearFilter;
prevTime = -1;
renderer = new THREE.WebGLRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.domElement.width = SCREEN_WIDTH;
renderer.domElement.height = SCREEN_HEIGHT;
renderer.autoClear = false;
document.body.insertBefore(renderer.domElement, document.body.childNodes[0]);
uniforms = {
currentTexture: { type: "t", value: currTexture },
mirrorImage: { type: "i", value: 0}
}
var geometry = new THREE.PlaneBufferGeometry(1, 1);
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: THREE.passThroughShader.vertexShader,
fragmentShader: THREE.passThroughShader.fragmentShader
} );
// A plane with the current video context as texture
var mesh = new THREE.Mesh(geometry,material);
mesh.material.depthTest = false;
mesh.material.depthWrite = false;
scene.add(mesh);
// COPY SHADER, used to render the current context to the screen
var effectCopy = new THREE.ShaderPass(THREE.CopyShader);
effectCopy.renderToScreen = true;
/** Preprocess stage **/
prepScene = new THREE.Scene();
prepScene.add( new THREE.AmbientLight( 0xffffff ) );
prepScene.add(mesh) // add the current quad
var renderTargetParameters = {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false};
//blur shaders
hBlur = new THREE.ShaderPass(THREE.HorizontalBlurShader);
hBlur.uniforms["h"].value = 1 / SCREEN_WIDTH;
hBlur.enabled = values['preprocess'];
vBlur = new THREE.ShaderPass(THREE.VerticalBlurShader);
vBlur.uniforms["v"].value = 1 / SCREEN_HEIGHT;
vBlur.enabled = values['preprocess'];
BlurSave = new THREE.SavePass(new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters));
//preprocess scene render pass
var renderModelPrep = new THREE.RenderPass(prepScene, camera);
var prevPassShader1 = new THREE.ShaderPass(THREE.passThroughShader);
prevPassShader1.uniforms["mirrorImage"].value = 1;
//Preprocess of the current image
//It is this prepComposer's rendertarget value I want to use in the next loop
prepComposer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters));
prepComposer.addPass(renderModelPrep);
prepComposer.addPass(prevPassShader1);
prepComposer.addPass(hBlur);
prepComposer.addPass(vBlur);
prepComposer.addPass(BlurSave);
//
// subtractComposer.addPass(effectCopy);
//Preprocess of the previous image
//Want to skip this stage
var prevPassShader = new THREE.ShaderPass(THREE.passThroughShader, prevTexture);
prevPassShader.uniforms["currentTexture"].value = prevTexture;
prevPassShader.uniforms["mirrorImage"].value = 1;
var prevBlurSave = new THREE.SavePass(new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters));
prepPrevComposer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters));
prepPrevComposer.addPass(renderModelPrep);
prepPrevComposer.addPass(prevPassShader);
prepPrevComposer.addPass(hBlur);
prepPrevComposer.addPass(vBlur);
prepPrevComposer.addPass(prevBlurSave);
/**------------------**/
/**---------------------------**/
/** Background Subtraction stage **/
subtractScene = new THREE.Scene();
subtractScene.add( new THREE.AmbientLight( 0xffffff ) );
var renderTargetParameters3 = {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false};
//Background Subtraction shaders
subtractShader = new THREE.ShaderPass(THREE.framediffShader);
subtractShader.uniforms['currentTexture'].value = BlurSave.renderTarget; // from the preprocess
subtractShader.uniforms['previousTexture'].value = prevBlurSave.renderTarget; //modelled background
//Background subtraction scene render pass
var renderSubtract = new THREE.RenderPass(subtractScene, camera);
//Background subtraction Composer
subtractComposer = new THREE.EffectComposer(renderer, new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters3));
subtractComposer.addPass(renderSubtract);
subtractComposer.addPass(subtractShader);
//subtractComposer.addPass(effectCopy2);
/**------------------------------**/
/** Postprocessing stage **/
//Dilation
var dilationFilter = new THREE.ShaderPass(THREE.DilationShader);
dilationFilter.enabled = values['postprocess'];
postProcessFilters.push(dilationFilter);
//Erosion
var erosionFilter = new THREE.ShaderPass(THREE.ErosionShader);
erosionFilter.enabled = values['postprocess'];
postProcessFilters.push(erosionFilter);
//Pawaskar's postprocess filter
var pawaskarFilter = new THREE.ShaderPass(THREE.PawaskarPostShader);
pawaskarFilter.uniforms['threshold'].value = values['threshold'];
pawaskarFilter.enabled = values['postprocess'];
postProcessFilters.push(pawaskarFilter);
subtractComposer.addPass(pawaskarFilter);
//Opening
subtractComposer.addPass(erosionFilter);
subtractComposer.addPass(dilationFilter);
//Closing
subtractComposer.addPass(dilationFilter);
subtractComposer.addPass(erosionFilter);
//The final result rendered to the screen
subtractComposer.addPass(effectCopy);
/**----------------------**/
animate();
}
function animate()
{
if(video.readyState === video.HAVE_ENOUGH_DATA ){
var time = video.currentTime;
if(time !== prevTime){
//Because a firefox bug when drawImage is used, need to catch NS_ERROR_NOT_AVAILABLE
try {
videoContext.drawImage(video, 0, 0,SCREEN_WIDTH,SCREEN_HEIGHT); //update the video
if(currTexture.image.data.length){
//var imgData = getData(renderer.domElement);
//var imgData = renderer.domElement.toDataURL();
// var gl = renderer.getContext();
//gl.readPixels( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, gl.RGBA, gl.UNSIGNED_BYTE, prevBlur.image.data );
//prevBlur.image.data = imgData;
// prevBlur.needsUpdate = true;
/** I want to update the prevBlur texture with the BlurSave.renderTarget! **/
prevTexture.image.data = currTexture.image.data;
prevTexture.needsUpdate = true; //updates the previous texture in the shader
}
currTexture.image.data = new Uint8Array(videoContext.getImageData(0,0,SCREEN_WIDTH, SCREEN_HEIGHT).data);
currTexture.needsUpdate = true; //updates the current texture in the shader
prevTime = time;
}catch (e) {
if (e.name == "NS_ERROR_NOT_AVAILABLE") {
console.error(e);
} else {
throw e;
}
}
}
}
prepComposer.render(0.05);
prepPrevComposer.render(0.05);
subtractComposer.render(0.05);
frameNumber++;
requestAnimationFrame(animate);
}
function getData(image) {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
return new Uint8Array(context.getImageData(0, 0, image.width, image.height).data);
}
function copyCanvas(e) {
var imgData, imgNode;
if (e.which !== 80) {
return;
} else {
imgData = renderer.domElement.toDataURL();
}
// create a new image and add to the document
imgNode = document.createElement("img");
imgNode.src = imgData;
document.body.appendChild(imgNode);
}
window.onload = init;
window.addEventListener("keyup", copyCanvas);
</script>
</body>
</html>
How can I update the prevBlur.image.data with the current image data of the BlurSave.rendertarget?
Are there any other way to update a shader's Sampler2D uniform with the value from a WebGLRenderTarget’s image data from a previous time-step?
If you want to post-process your scene with a subtraction shader that uses the difference between the current and previous frames, you can do something like the following:
First create two render targets rt1 and rt2. Set currentRT = rt1 and prevRT = rt2.
Then in your render loop, (1) render to currentRT, then (2) pass currentRT and prevRT as uniforms to your subtraction shader and render to the screen, then (3) swap the render targets.
three.js r.70

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>

ShaderMaterial not work with MeshFaceMaterial

I use ShaderMaterial to create real material for my cube. But it not works well. As can see, only first face work well. Even when i use different texture for different faces, it not works. I don't know what is problem with my code.
Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Test_material</title>
<style type="text/css" media="all">
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<div id='container'></div>
<script type="text/javascript" src="js/threejs/Three.js">
</script>
<script type="text/javascript" src="js/lib/util.js">
</script>
<script type="text/javascript" src="js/threejs/TrackballControls.js"></script>
<script>
var WIDTH= 400;
var HEIGHT = 400;
var container = document.getElementById('container');
var camera =new THREE.PerspectiveCamera(25, WIDTH/HEIGHT, 1, 10000);
camera.position.set(0,300,100);
var animate;
var scene = new THREE.Scene();
scene.add(camera);
camera.lookAt(scene.position);
var controls = new THREE.TrackballControls(camera);
//custom shape
materialArr = [];
var data = new utils.Storage.ResourceStorage();
data.load({
'textures': {
'track_normal_0' : 'images/pattern/track_normal_0.jpg',
'track_diffuse_0' : 'images/pattern/track_diffuse_0.jpg',
'track_specular_0' : 'images/pattern/track_specular_0.jpg',
'track_normal_0' : 'images/pattern/track_normal_0.jpg',
'track_diffuse_0' : 'images/pattern/track_diffuse_0.jpg',
'track_specular_0' : 'images/pattern/track_specular_0.jpg',
'track_normal_1' : 'images/pattern/track_normal_1.jpg',
'track_diffuse_1' : 'images/pattern/track_diffuse_1.jpg',
'track_specular_1' : 'images/pattern/track_specular_1.jpg',
'track_normal_2' : 'images/pattern/track_normal_2.jpg',
'track_diffuse_2' : 'images/pattern/track_diffuse_2.jpg',
'track_specular_2' : 'images/pattern/track_specular_2.jpg',
'track_normal_3' : 'images/pattern/track_normal_3.jpg',
'track_diffuse_3' : 'images/pattern/track_diffuse_3.jpg',
'track_specular_3' : 'images/pattern/track_specular_3.jpg',
'track_normal_4' : 'images/pattern/track_normal_4.jpg',
'track_diffuse_4' : 'images/pattern/track_diffuse_4.jpg',
'track_specular_4' : 'images/pattern/track_specular_4.jpg',
'track_normal_5' : 'images/pattern/track_normal_5.jpg',
'track_diffuse_5' : 'images/pattern/track_diffuse_5.jpg',
'track_specular_5' : 'images/pattern/track_specular_5.jpg',
},
'onReady': init
});
function init(){
var materialArr = [];
for (var i=0; i< 6; i++){
var shader = THREE.ShaderLib['normalmap'];
var normalTexture = data.getTexture('track_normal_' + i).clone();
normalTexture.needsUpdate = true;
var diffuseTexture = data.getTexture('track_diffuse_' + i);
diffuseTexture.needsUpdate = true;
var specularTexture = data.getTexture('track_specular_' + i);
specularTexture.needsUpdate = true;
var uniforms = THREE.UniformsUtils.clone(shader.uniforms);
uniforms['tNormal'].value = normalTexture;
uniforms['tDiffuse'].value = diffuseTexture;
uniforms['tSpecular'].value = specularTexture;
uniforms['enableDiffuse'].value = true;
uniforms['enableSpecular'].value = true;
uniforms['uSpecularColor'].value.setHex(0x00cc00);
uniforms['uDiffuseColor'].value.setHex(0x0000ff);
<!--uniforms['uShininess'].value = 100;-->
var material = new THREE.ShaderMaterial({
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader + " ",
uniforms: uniforms,
lights: true
});
material.perPixel = true;
material.needsUpdate = true;
materialArr.push(material);
}
var geometry = new THREE.CubeGeometry(40, 40, 40);
geometry.computeTangents();
var material = new THREE.MeshFaceMaterial(materialArr);
for (var i=0; i< material.materials.length; i++){
material.materials[i].needsUpdate = true;
}
mesh =new THREE.Mesh(geometry, material);
scene.add(mesh);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(WIDTH, HEIGHT);
container.appendChild(renderer.domElement);
var dirLight = new THREE.DirectionalLight(0xffffff);
scene.add(dirLight);
var ambientLight = new THREE.AmbientLight(0xcddacc);
scene.add(ambientLight);
renderer.render(scene, camera);
animate = function (){
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
animate();
}
</script>
</body>
</html>
My result
I would suggest using a single material and tweaking the UVs of the geometry instead. Take a look at the minecraft example to see how to do that.

Resources