Insufficient buffer size, a buffer must be bound - javascript

I'm trying to add a lamp to my scene with an OBJLoader object. The object is exported from Blender. If I set its children[i].castShadow property to true the following errors show up but still it appears and its shadow can be seen on the wall:
What am I doing wrong? If and when I add some other object to my scene and set its castShadow property to true I get no error messages whatsoever. This is the only problematic object I have currently.
One more thing. My project won't work in Firefox, but it displays in Edge or Chrome for example. What is so special about Firefox?
<!DOCTYPE html>
<html>
<head>
<title>Jaj de jó</title>
<script type="text/javascript" src="libs/three.js"></script>
<script type="text/javascript" src="libs/OBJLoader.js"></script>
<script type="text/javascript" src="libs/MTLLoader.js"></script>
<script type="text/javascript" src="libs/OBJMTLLoader.js"></script>
<script type="text/javascript" src="libs/OrbitControls.js"></script>
<script type="text/javascript" src="libs/ThreeBSP.js"></script>
<script type="text/javascript" src="libs/stats.js"></script>
<script type="text/javascript" src="libs/dat.gui.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<meta charset="UTF-8">
</head>
<body>
<div id="WebGL-output"></div>
<script type="text/javascript">
var webGLRenderer;
function init() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0x666666, 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
webGLRenderer.shadowMapEnabled = true;
webGLRenderer.shadowMapType = THREE.PCFShadowMap;
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 50;
camera.lookAt(new THREE.Vector3(0, 0, 0));
var orbitControls = new THREE.OrbitControls(camera);
orbitControls.autoRotate = false;
var clock = new THREE.Clock();
document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
/* prepare, load textures and add geometries to the scene */
var planeGeometry = new THREE.PlaneBufferGeometry(200, 200, 1, 1);
var texture = THREE.ImageUtils.loadTexture("textures/floor_wood.jpg");
var planeMaterial = new THREE.MeshPhongMaterial();
planeMaterial.map = texture;
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.x = 200 / 100;
texture.repeat.y = 200 / 100;
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = -20;
scene.add(plane);
/* FLOOR ADDED */
/* WALLS START */
var wallGeometry = new THREE.BoxGeometry(150, 100, 175);
texture = THREE.ImageUtils.loadTexture("textures/brick-wall.jpg");
var material = new THREE.MeshPhongMaterial();
material.map = texture;
var wall = new THREE.Mesh(wallGeometry, material);
wall.receiveShadow = true;
wall.material.side = THREE.BackSide;
wall.material.map.repeat.set(200 / 100, 175 / 100);
wall.material.map.wrapS = THREE.RepeatWrapping;
wall.material.map.wrapT = THREE.RepeatWrapping;
wall.material.needsUpdate = true;
wall.position.y = 25;
wall.position.z -= 25;
scene.add(wall);
/* WALLS END */
/* LAMP */
var loader = new THREE.OBJLoader();
loader.load("models/lamp.obj", function (object) {
console.log("LAMP");
console.log(object);
var blackMaterial = new THREE.MeshPhongMaterial({ color: 0x222222 });
for(var i = 0; i < object.children.length; i++) {
object.children[i].material = blackMaterial;
object.children[i].castShadow = true;
}
object.scale.set(5, 5, 5);
object.position.x = -14.5;
object.position.y = 40;
object.position.z = -17;
scene.add(object);
});
/* LAMP END */
// add spotlight for the shadows
var spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.position.set(75, 75, 15);
spotLight.castShadow = true;
spotLight.shadowCameraNear = 20;
spotLight.shadowDarkness = .6;
spotLight.shadowMapWidth = 512;
spotLight.shadowMapHeight = 512;
spotLight.shadowCameraFov = 64;
scene.add(spotLight);
render();
function render() {
var delta = clock.getDelta();
orbitControls.update(delta);
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}
}
window.onload = init;
</script>
</body>
</html>

Related

three.js rendering text to scene

I'm new at three.js.
In my work, I have to made 3d graphical website.
So after searched in google, I found that three.js is suitable to manipulate WebGL conveniently.
In three.js document(https://threejs.org/docs/#api/en/geometries/TextGeometry),
TextGeometry is API for draw text in the scene.
[src.js]
init = () => {
window.addEventListener('resize', resizeWindow);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
var controls = new THREE.OrbitControls( camera );
controls.update();
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xdd3b56);
renderer.setSize(window.innerWidth, window.innerHeight);
// Set shadow
renderer.shadowMap.enabled = true;
// Show Axis
var axes = new THREE.AxisHelper(5);
scene.add(axes);
// Text
var loader = new THREE.FontLoader();
loader.load( './helvetiker_regular.typeface.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Hello three.js!', {
font: font,
size: 80,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
} );
} );
var textMaterial = new THREE.MeshPhongMaterial({color: 0xFE98A0});
var text = new THREE.Mesh(geometry, textMaterial);
text.position.x = 0;
text.position.y = 10;
text.position.z = 10;
scene.add(text);
// Light
var spotLight = new THREE.SpotLight(0xFFFFFF);
spotLight.position.set(-40, 60, 30);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 5120;
spotLight.shadow.mapSize.height = 5120;
scene.add(spotLight);
// Camera Setting
camera.position.x = 0;
camera.position.y = 30;
camera.position.z = 30;
camera.lookAt(scene.position);
document.getElementById("threejs_scene").appendChild(renderer.domElement);
renderScene();
function renderScene() {
requestAnimationFrame(renderScene);
controls.update();
renderer.render(scene, camera);
}
}
window.onload = init();
[index.html]
<html>
<head>
<script src="three.js"></script>
<script src="OrbitControls.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="threejs_scene"></div>
<script src="src.js"></script>
</body>
</html>
When I execute my code, it throws [.WebGL-0x7fb612852000]RENDER WARNING: Render count or primcount is 0. and WebGL: too many errors, no more errors will be reported to the console for this context. errors.
So I searched it at google, it occured when Three.js is trying to render an object that does not exist yet.
But in my code, I already defined it.
var textMaterial = new THREE.MeshPhongMaterial({color: 0xFE98A0});
var text = new THREE.Mesh(geometry, textMaterial);
text.position.x = 0;
text.position.y = 10;
text.position.z = 10;
How can I solve this issue?
My last goal is display text in the scene.
Thanks.
window.onload = function(params) {
/*
*
* SET UP THE WORLD
*
*/
//set up the ratio
var gWidth = window.innerWidth;
var gHeight = window.innerHeight;
var ratio = gWidth / gHeight;
var borders = [40, 24] //indicate where the ball needs to move in mirror position
var light = new THREE.AmbientLight(0xffffff, 0.5);
var light1 = new THREE.PointLight(0xffffff, 0.5);
light1.position.set(0, 5, 0);
light1.castShadow = true;
// set the renderer
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera();
camera.position.set(10, 10, 10);
camera.lookAt(new THREE.Vector3(0, 0, 0));
//properties for casting shadow
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(gWidth, gHeight);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
scene.add(light);
scene.add(light1);
var ground = new THREE.Mesh(new THREE.BoxGeometry(10, 0.5, 10), new THREE.MeshLambertMaterial())
ground.receiveShadow = true;
scene.add(ground)
var geometry;
var loader = new THREE.FontLoader();
var mesh;
requestAnimationFrame(render);
function render() {
if (mesh) {
mesh.rotation.y += 0.01;
mesh.rotation.z += 0.007;
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
loader.load('https://cdn.rawgit.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.json', function(font) {
var geometry = new THREE.TextGeometry('Hello three.js!', {
font: font,
size: 80,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
});
var material = new THREE.MeshLambertMaterial({
color: 0xF3FFE2
});
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 2, 0);
mesh.scale.multiplyScalar(0.01)
mesh.castShadow = true;
scene.add(mesh);
var canv = document.createElement('canvas')
canv.width = canv.height = 256;
var ctx = canv.getContext('2d')
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canv.width, canv.height);
ctx.fillStyle = 'black'
ctx.fillText("HERE IS SOME 2D TEXT", 20, 20);
var tex = new THREE.Texture(canv);
tex.needsUpdate = true;
var mat = new THREE.MeshBasicMaterial({
map: tex
});
var plane = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), mat);
scene.add(plane)
});
}
body {
padding: 0;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<html>
<head>
</head>
<body>
</body>
</html>

Change the position of a piechart slice in threejs

I have created a pie chart object using 3js ExtrudeGeometry. My requirement is to move out a slice from the piechart object as shown in the following image.
Here is the code I have tried.
<!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 {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/Detector.js" type="text/javascript"></script>
<script src="js/renderers/CanvasRenderer.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"> </script>
<script>
var container, scene, camera, renderer, controls;
var segments = [];
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(5, 10, -10);
scene.add(camera);
var dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(100, 100, 100);
camera.add(dirLight);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var i;
var startAngle=0;
var color="blue";
for(i=0;i<4;i++){
var smallSegment=createSegment(1, THREE.Math.degToRad(startAngle) ,THREE.Math.degToRad(startAngle+90), color);
if(color=="blue"){
color="red"
}else{
color="blue"
}
startAngle=startAngle+90;
scene.add(smallSegment);
segments.push(smallSegment);
}
//segments[0].position.x=segments[0].position.x+0.5;
//segments[1].position.x=segments[1].position.x+0.5;
//segments[2].position.x=segments[2].position.x+0.5;
segments[3].position.x=segments[3].position.x+0.5;
}
function createSegment(radius, angleStart, angleEnd, color) {
var extrOpt = {
curveSegments: 32,
steps: 1,
amount: 0.1,
bevelEnabled: false,
};
var Shape = new THREE.Shape();
Shape.moveTo(0, 0);
Shape.absarc(0, 0, radius, angleStart, angleEnd, false);
Shape.lineTo(0, 0);
var SegmentGeom = new THREE.ExtrudeGeometry( Shape, extrOpt );
SegmentGeom.rotateX(-Math.PI / 2);
var SegmentMat = new THREE.MeshLambertMaterial({
color: color
});
var Segment = new THREE.Mesh(SegmentGeom, SegmentMat);
return Segment;
}
function animate() {
var time = new Date() * 0.001;
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
</body>
</html>
I tried to change the x position of the slices which I need to move out. But that did not workout. When I change the x positions some slices have overlapped with each other.
Are there any solutions to make this work correctly?
To move the slice outward, you need to figure out the angle in radians of the direction that you want to move it..
var renderer = new THREE.WebGLRenderer();
var w = 300;
var h = 200;
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
45, // Field of view
w / h, // Aspect ratio
0.1, // Near
10000 // Far
);
camera.position.set(15, 10, 15);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.PointLight(0xFFFF00);
light.position.set(20, 20, 20);
scene.add(light);
var light1 = new THREE.AmbientLight(0x808080);
light1.position.set(20, 20, 20);
scene.add(light1);
var i;
var startAngle = 0;
var rnd = (rng) => {
return Math.random() * rng
}
var color = "blue";
//Make a random pie chart...
for (startAngle = 0; startAngle < 360;) {
var ang = rnd(40) + 5;
if (ang + startAngle > 360) ang = 360 - startAngle;
var smallSegment = createSegment(1, THREE.Math.degToRad(startAngle), THREE.Math.degToRad(startAngle + ang), color);
if (color == "blue") {
color = "red"
} else {
color = "blue"
}
scene.add(smallSegment);
startAngle += ang;
}
console.log("start!")
var time = 0;
function createSegment(radius, angleStart, angleEnd, color) {
var extrOpt = {
curveSegments: 32,
steps: 1,
depth: 0.1,
bevelEnabled: false,
};
var Shape = new THREE.Shape();
Shape.moveTo(0, 0);
Shape.absarc(0, 0, radius, angleStart, angleEnd, false);
Shape.lineTo(0, 0);
var SegmentGeom = new THREE.ExtrudeGeometry(Shape, extrOpt);
SegmentGeom.rotateX(-Math.PI / 2);
var SegmentMat = new THREE.MeshLambertMaterial({
color: color
});
var Segment = new THREE.Mesh(SegmentGeom, SegmentMat);
Segment.userData.angleStart = angleStart;
Segment.userData.angleEnd = angleEnd;
Segment.onBeforeRender = function() {
//degrees is the angle of the direction you want to move the slice
//We do the average of startAngle+endAngle to get the center angle of the slice
var radians = (this.userData.angleEnd + this.userData.angleStart) * 0.5; //45;
var vx = Math.cos(radians);
var vz = -Math.sin(radians);
//This is just some values I fake up to make it animate
var tmp = this.userData.angleStart * 0.2;
var sinTime = Math.abs(Math.sin(tmp + (time * 0.001)));
//Move the actual piece
this.position.x = sinTime * vx;
this.position.z = sinTime * vz;
}
return Segment;
}
renderer.setClearColor(0xdddddd, 1);
(function animate(dt) {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
time = dt;
})();
<script src="https://threejs.org/build/three.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

Trackballcontrols and gui can't work together

The gui change together when I click on them and I've seen other answer, but don't know where should I put the listener, I've tried to put the listener in render(), but still don't so how can I fix my code? This coding relates to my graduation.
Here is my code:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>map draw</title>
<!-- Original:
<script type="text/javascript" src="../build/three.js"></script>
<script type="text/javascript" src="../examples/js/libs/dat.gui.js"></script>
<script type="text/javascript" src="../examples/js/libs/stats.min.js"></script>
<script type="text/javascript" src="../examples/js/controls/TrackballControls.js"></script>
-->
<!-- Added by TheJim01 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.js"></script>
<script src="https://threejs.org/examples/js/libs/dat.gui.min.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
<!-- End TheJim01 additions -->
</head>
<body>
<div id="Stats-output"></div>
<div id="camera"></div>
<div id="airport"></div>
<script type="text/javascript">
function init() {
var controls = new Array(cube_number);
console.log(controls);
var cubes = new Array(cube_number);
var guicube = new Array(cube_number);
var cube_number = 4; //change this word,you can change the number of cubes
var stats = initStats()
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 10;
camera.position.y = 10;
camera.position.z = 30;
camera.lookAt(scene.position);
var trackballControls = new THREE.TrackballControls(camera); //配置控制器
var clock = new THREE.Clock();
trackballControls.rotateSpeed = 1.0;
trackballControls.zoomSpeed = 1.0;
trackballControls.panSpeed = 1.0;
trackballControls.domElement = document.querySelector('#camera')
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000)); //背景颜色设置
renderer.setSize(window.innerWidth, window.innerHeight);
var axes = new THREE.AxisHelper(60);
scene.add(axes);
for (var i = 0; i < cube_number; i++) {
controls[i] = new function() {
this.PositionX = 0;
this.PositionY = 0;
this.PositionZ = 0;
this.ScaleX = 1;
this.ScaleY = 1;
this.ScaleZ = 1;
this.RotationX = 0;
this.RotationY = 0;
this.RotationZ = 0;
}
}
var planeGeometry = new THREE.PlaneGeometry(65, 65);
var planeMaterial = new THREE.MeshBasicMaterial({
color: 0x808080
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane);
for (var i = 0; i < cube_number; i++) {
var cubeGeometry = new THREE.BoxGeometry(6, 6, 6);
var cubeMaterial = new THREE.MeshBasicMaterial({
color: Math.random() * 0xFFFFFF,
wireframe: false
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 2 * i;
cube.position.y = 0;
cube.position.z = 0;
cube.scale.set(1, 1, 1);
cube.name = "cube-" + i;
scene.add(cube);
}
//render the scene
render();
document.getElementById("airport").appendChild(renderer.domElement);
function render() {
for (i = 0; i < cube_number; i++) {
stats.update();
cubes[i] = scene.getObjectByName("cube-" + i);
cubes[i].position.x = controls[i].PositionX;
cubes[i].position.y = controls[i].PositionY;
cubes[i].position.z = controls[i].PositionZ;
cubes[i].scale.set(controls[i].ScaleX, controls[i].ScaleY, controls[i].ScaleZ);
cubes[i].rotation.x = controls[i].RotationX;
cubes[i].rotation.y = controls[i].RotationY;
cubes[i].rotation.z = controls[i].RotationZ;
}
requestAnimationFrame(render);
renderer.render(scene, camera);
var delta = clock.getDelta();
trackballControls.update(delta);
}
//here is the biggest problem
var gui = new dat.GUI();
for (i = 0; i < cube_number; i++) {
guicube[i] = gui.addFolder(cubes[i].name);
guicube[i].add(controls[i], 'PositionX', -20, 20);
guicube[i].add(controls[i], 'PositionY', -8, 40);
guicube[i].add(controls[i], 'PositionZ', -20, 20);
guicube[i].add(controls[i], 'ScaleX', 1, 8);
guicube[i].add(controls[i], 'ScaleY', 1, 8);
guicube[i].add(controls[i], 'ScaleZ', 1, 8);
guicube[i].add(controls[i], 'RotationX', -4, 4);
guicube[i].add(controls[i], 'RotationY', -4, 4);
guicube[i].add(controls[i], 'RotationZ', -4, 4);
}
}
function initStats() {
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
window.onload = init();
</script>
//改动cube_number参数,可以改变添加立方体的个数
</body>
</html>
You're declaring the domElement of trackballControls in the wrong place. It has to be passed as the second parameter of the constructor. Additionally, make sure you're passing the same domElement as the renderer so you won't run into z-indexing issues.
Wrong
var trackballControls = new THREE.TrackballControls(camera);
trackballControls.domElement = document.querySelector('#camera'); // too late to declare here
...
document.getElementById("airport").appendChild(renderer.domElement); // Will lead to stacking issues
Correct:
var trackballControls = new THREE.TrackballControls(camera, document.querySelector('#airport'));
...
document.getElementById("airport").appendChild(renderer.domElement); // Same element as trackball
Additionally
Make sure you're calling stats.update(); outside the for() loop, otherwise it'll run 4 times per frame, leading to an incorrect 240 FPS.
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>map draw</title>
<!-- Added by TheJim01 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.js"></script>
<script src="https://threejs.org/examples/js/libs/dat.gui.min.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
<!-- End TheJim01 additions -->
</head>
<body>
<div id="Stats-output"></div>
<div id="airport"></div>
<script type="text/javascript">
function init() {
var controls = new Array(cube_number);
console.log(controls);
var cubes = new Array(cube_number);
var guicube = new Array(cube_number);
var cube_number = 4; //change this word,you can change the number of cubes
var stats = initStats()
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 10;
camera.position.y = 10;
camera.position.z = 30;
camera.lookAt(scene.position);
var trackballControls = new THREE.TrackballControls(camera, document.querySelector('#airport')); // pass the #airport DIV as its second parameter.
var clock = new THREE.Clock();
trackballControls.rotateSpeed = 1.0;
trackballControls.zoomSpeed = 1.0;
trackballControls.panSpeed = 1.0;
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000)); //背景颜色设置
renderer.setSize(window.innerWidth, window.innerHeight);
var axes = new THREE.AxisHelper(60);
scene.add(axes);
for (var i = 0; i < cube_number; i++) {
controls[i] = new function() {
this.PositionX = 0;
this.PositionY = 0;
this.PositionZ = 0;
this.ScaleX = 1;
this.ScaleY = 1;
this.ScaleZ = 1;
this.RotationX = 0;
this.RotationY = 0;
this.RotationZ = 0;
}
}
var planeGeometry = new THREE.PlaneGeometry(65, 65);
var planeMaterial = new THREE.MeshBasicMaterial({
color: 0x808080
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane);
for (var i = 0; i < cube_number; i++) {
var cubeGeometry = new THREE.BoxGeometry(6, 6, 6);
var cubeMaterial = new THREE.MeshBasicMaterial({
color: Math.random() * 0xFFFFFF,
wireframe: false
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 2 * i;
cube.position.y = 0;
cube.position.z = 0;
cube.scale.set(1, 1, 1);
cube.name = "cube-" + i;
scene.add(cube);
}
//render the scene
render();
document.getElementById("airport").appendChild(renderer.domElement);
function render() {
stats.update();
for (i = 0; i < cube_number; i++) {
cubes[i] = scene.getObjectByName("cube-" + i);
cubes[i].position.x = controls[i].PositionX;
cubes[i].position.y = controls[i].PositionY;
cubes[i].position.z = controls[i].PositionZ;
cubes[i].scale.set(controls[i].ScaleX, controls[i].ScaleY, controls[i].ScaleZ);
cubes[i].rotation.x = controls[i].RotationX;
cubes[i].rotation.y = controls[i].RotationY;
cubes[i].rotation.z = controls[i].RotationZ;
}
requestAnimationFrame(render);
renderer.render(scene, camera);
var delta = clock.getDelta();
trackballControls.update(delta);
}
//here is the biggest problem
var gui = new dat.GUI();
for (i = 0; i < cube_number; i++) {
guicube[i] = gui.addFolder(cubes[i].name);
guicube[i].add(controls[i], 'PositionX', -20, 20);
guicube[i].add(controls[i], 'PositionY', -8, 40);
guicube[i].add(controls[i], 'PositionZ', -20, 20);
guicube[i].add(controls[i], 'ScaleX', 1, 8);
guicube[i].add(controls[i], 'ScaleY', 1, 8);
guicube[i].add(controls[i], 'ScaleZ', 1, 8);
guicube[i].add(controls[i], 'RotationX', -4, 4);
guicube[i].add(controls[i], 'RotationY', -4, 4);
guicube[i].add(controls[i], 'RotationZ', -4, 4);
}
}
function initStats() {
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
window.onload = init();
</script>
//改动cube_number参数,可以改变添加立方体的个数
</body>
</html>

THREE.JS does not cast shadows

I was doing a Three js tutorial and this code should cast shadows, but when render shadows does not exists over the plane.
What is wrong on code? I'm reading documentation and other codes and I can not find the problem.
Best regards!
EDIT:
If i make a loop with requestAnimationFrame just works... but only in that case... why?
<!DOCTYPE html>
<html>
<head>
<title>Learning THREE JS Basic</title>
<script src="../../libs/three.js"></script>
<script src="../../libs/jquery.js"></script>
<style>
body {
margin : 0;
overflow : hidden;
}
</style>
</head>
<body>
<div id="visor"></div>
<script>
$(function () {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xEEEEEE);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
var axes = new THREE.AxisHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0xFFFFFF
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.x = 15;
plane.position.y = 0;
plane.position.z = 0;
plane.receiveShadow = true;
scene.add(plane);
var cubeGeometry = new THREE.BoxGeometry(4,4,4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0xFF0000
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = -4;
cube.position.y = 3;
cube.position.z = 0;
cube.castShadow = true;
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777FF
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.x = 20;
sphere.position.y = 4;
sphere.position.z = 2;
sphere.castShadow = true;
scene.add(sphere);
var spotLight = new THREE.SpotLight(0xFFFFFF);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
scene.add(spotLight);
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
$("#visor").append(renderer.domElement);
renderer.render(scene, camera);
});
</script>
</body>
</html>
three.js r.74 and r.75 have a bug in which shadows are not always rendered in the first call to render(). This bug has been fixed in three.js r.76dev.
Your work-around is to call renderer.render( scene, camera ) a 2nd time, or to have an animation loop.
three.js r.75

Three js 25000 BoxGeometry 200 models How to increase performance

I am knew to WebGL and Three js having been able to get enough code together to be able to add 25K BoxGeometry Meshes and about 200 models which move simultaneously and interact with the BoxGeometry.
I need to be able to move the camera smoothly through these boxes.
So, I have tried to merge all the geometry together (got that idea from a google search) and that made the performance worse.
I watched several YouTube videos and did not a lot about performance.
I am currently using mrdoob-three.js-4bab468 if that helps.
The functions addCube20 addCube40 are called a little over 25,000 times with different coordinates to display at.
then they are not called again unless something in the scene alters their position.
MJMotion.js is my keyboard camera view controls that do not need to be included. You can remove them by altering the render section taking out
keyboardControls();
updateCamera();
and replacing them with your own controls.
this thing gets about 3 fps.
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, minimum-scale=1.0">
<title>CubeTest</title>
<style>
body {
margin: 0;
}
</style>
<script>
var pageE;
</script>
</head>
<body style="touch-action:none">
<div id="canvas_container" style="position: absolute; left:0px; top:0px; touch-action:pan-y;"></div>
<script src="js/three.js"></script>
<script src="js/Cache.js"></script>
<script src="js/DDSLoader.js"></script>
<script src="js/MTLLoader.js"></script>
<script src="js/OBJMTLLoader.js"></script>
<script src="js/OBJLoader.js"></script>
<script src="js/XHRLoader.js"></script>
<script src="js/LoadingManager.js"></script>
<script src="js/JSONLoader.js"></script>
<script src="js/MJMotion.js"></script>
<script src="js/stats.min.js"></script>
<script>
// Our Javascript will go here.
var domContainer = null;
domContainer = document.getElementById("canvas_container");
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
domContainer.appendChild( stats.domElement );
var camera = new THREE.PerspectiveCamera( 30, window.innerWidth/window.innerHeight, 0.1, 500.0);
var aspectratio = window.innerWidth/window.innerHeight;
var renderer = new THREE.WebGLRenderer();
var connected = false;
var SaveAUseB = true;
var UpdateCount = 0;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.cullFace = THREE.CullFaceFrontBack;
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
domContainer.appendChild( renderer.domElement );
var INTERSECTED;
var mouse = new THREE.Vector2();
var raycaster = new THREE.Raycaster();
var scene = new THREE.Scene();
var objects = [], plane;
var mouseDown = 0;
scene.add(camera);
scene.fog = new THREE.Fog( 0xaaccff,10,150);
window.addEventListener('resize', resize, false);
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
renderer.domElement.addEventListener('mousewheel',onMouseWheel, false);
renderer.domElement.addEventListener( 'touchstart',touchstart, false );
renderer.domElement.addEventListener( 'touchend', touchend, false );
renderer.domElement.addEventListener('touchmove', touchmove, false);
// this must be defined before MJMotion.js
// we use it in there.
var scenesizereduction = 100.0;
// defined in MJMotion.js
SetScreenReduction(scenesizereduction);
var directionalLight = new THREE.DirectionalLight(0xffffff, 0.15);
directionalLight.position.set(-100/scenesizereduction, 1000/scenesizereduction,2000/scenesizereduction);
scene.add(directionalLight);
var hemiLight = new THREE.HemisphereLight(0xAAAAAA, 0x080808, 0.25);
hemiLight.position.set(0, 500/scenesizereduction, 0);
scene.add(hemiLight);
var dirLight = new THREE.DirectionalLight( 0xffffff, 0 );
dirLight.color.setHSL( 0.1, 1, 0.95 );
dirLight.position.set( -1, 1.75, 1 );
dirLight.position.multiplyScalar( 50 );
scene.add( dirLight );
dirLight.castShadow = true;
dirLight.shadowMapWidth = 2048;
dirLight.shadowMapHeight = 2048;
var d = 150;
dirLight.shadowCameraLeft = -d;
dirLight.shadowCameraRight = d;
dirLight.shadowCameraTop = d;
dirLight.shadowCameraBottom = -d;
dirLight.shadowCameraFar = 3500;
dirLight.shadowBias = -0.00005;
// 50 perccent
var pixelsperfoot = 2.0 / scenesizereduction;
var GroundWidth = 30346/scenesizereduction;
var GroundLength = 6001/scenesizereduction;
var xoffset = (GroundWidth / 2.0) - (87.0390550000001 * pixelsperfoot);
var zoffset = (GroundLength/2.0) - (607.80843 * pixelsperfoot);
var textures20Geometry = new THREE.BoxGeometry(20 * pixelsperfoot, 9.5 * pixelsperfoot, 8.0 * pixelsperfoot);
var textures40Geometry = new THREE.BoxGeometry(40 * pixelsperfoot, 9.5 * pixelsperfoot, 8.0 * pixelsperfoot);
var Cube20Mesh= new THREE.Mesh( textures20Geometry);
var Cube40Mesh= new THREE.Mesh(textures40Geometry);
var CubeGeometry = new THREE.Geometry();
var cubeMaterial1 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube01.png')
});
var cubeMaterial2 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube02.png')
});
var cubeMaterial3 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube03.png')
});
var cubeMaterial4 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube04.png')
});
var cubeMaterial5 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube05.png')
});
var cubeMaterial6 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube06.png')
});
var cubeMaterial7 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube07.png')
});
var cubeMaterial8 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube08.png')
});
var cubeMaterial9 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube09.png')
});
var cubeMaterial10 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube10.png')
});
var cubeMaterial11 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube11.png')
});
var cubeMaterial12 = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('textures/cube12.png')
});
for(var i = 0; i < 2500; i++)
{
addCube20("cube" + i, Math.random() * 800 - 400,Math.random() * 800 - 400,Math.random() * 2 * Math.PI,1);
addCube40("cube" + i, Math.random() * 800 - 400,Math.random() * 800 - 400,Math.random() * 2 * Math.PI,1);
}
DisplayCubes();
function addCube20(name, x1,z1,azimuth,MaterialIndex)
{
Cube20Mesh.position.set(x1, ((0.5 + 4.25) * pixelsperfoot) + ((MaterialIndex - 1) * (9.5 * pixelsperfoot)), z1);
Cube20Mesh.rotation.y = (Math.PI / 180.0) * azimuth;
Cube20Mesh.name = name;
Cube20Mesh.updateMatrix();
CubeGeometry.merge(Cube20Mesh.geometry, Cube20Mesh.matrix,MaterialIndex);
};
function addCube40(name, x1,z1,azimuth,MaterialIndex)
{
Cube40Mesh.position.set(x1, ((0.5 + 4.25) * pixelsperfoot) + ((MaterialIndex - 1) * (9.5 * pixelsperfoot)), z1);
Cube40Mesh.rotation.y = (Math.PI / 180.0) * azimuth;
Cube40Mesh.name = name;
Cube40Mesh.updateMatrix();
CubeGeometry.merge(Cube40Mesh.geometry, Cube40Mesh.matrix, MaterialIndex);
};
function DisplayCubes()
{
var CubeMaterials = [];
CubeMaterials.push(cubeMaterial1);
CubeMaterials.push(cubeMaterial2);
CubeMaterials.push(cubeMaterial3);
CubeMaterials.push(cubeMaterial4);
CubeMaterials.push(cubeMaterial5);
CubeMaterials.push(cubeMaterial6);
CubeMaterials.push(cubeMaterial7);
CubeMaterials.push(cubeMaterial8);
CubeMaterials.push(cubeMaterial9);
CubeMaterials.push(cubeMaterial10);
CubeMaterials.push(cubeMaterial11);
CubeMaterials.push(cubeMaterial12);
var CubeGroup = new THREE.Mesh(CubeGeometry, new THREE.MeshFaceMaterial(CubeMaterials));
CubeGroup.matrixAutoUpdate = false;
CubeGroup.updateMatrix();
scene.add(CubeGroup);
};
function resize()
{
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
};
function animate()
{
requestAnimationFrame( animate );
render();
stats.update();
};
function render()
{
keyboardControls();
updateCamera()
renderer.render(scene, camera);
};
animate();
</script>
I have found the issue. It is the materials. If I use images it slows down to 7 fps. If I use something simple like a MeshNormalMaterial it works at 60fps.
Is there any way to rectify this?

Categories