Multi-platform (Chrome, IE, Firefox) - javascript

I don't undestand why this script doesn't work in IE, while it works in Firefox and Chrome. When I try to use this script in IE, I get this message "ACTIVEX stop script".
Please help me.
<!DOCTYPE html>
<html>
<head>
<title>Getting Started with Three.js</title>
<script type="text/javascript" src="http://www.html5canvastutorials.com/libraries/Three.js"></script>
<script type="text/javascript">
window.onload = function() {
var renderer = new THREE.WebGLRenderer();
renderer.setSize( 800, 600 );
document.body.appendChild( renderer.domElement );
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
35, // Field of view
800 / 600, // Aspect ratio
0.1, // Near plane
10000 // Far plane
);
camera.position.set( 15, 10, 10 );
camera.lookAt( scene.position );
scene.add( camera );
var cube = new THREE.Mesh(
new THREE.CubeGeometry( 5, 5, 5 ),
new THREE.MeshLambertMaterial( { color: 0xFF0000 } )
);
scene.add( cube );
var light = new THREE.PointLight( 0xFFFF00 );
light.position.set( 10, 0, 10 );
scene.add( light );
renderer.render( scene, camera );
};
</script>
</head>
<body></body>

The Three.js WebGLRenderer doesn't work in IE (no WebGL support)
try
var renderer = new THREE.CanvasRenderer()
instead

As an alternative to the very simple solution above you can utilize alteredq and mrdoob's great Detector.js script that is included with the examples for three.js. If you use code like below you can use the WebGLRenderer as default and use canvas only if WebGL is not available. You can also use a flag like webglEnabled in order to set other options depending on your renderer later in your code.
var webglEnabled = false;
var webglReq = false;
if (Detector.webgl) {
renderer = new THREE.WebGLRenderer(
{
antialias: true,
preserveDrawingBuffer: true
}); // allow screenshot
webglEnabled = true; // set flag
}
else if (webglReq) { Detector.addGetWebGLMessage(); return false; }
else {
renderer = new THREE.CanvasRenderer();
}
renderer.setClearColorHex(0x000000, 1);
renderer.setSize(window.innerWidth, window.innerHeight);

Related

Memory leak when updating material index in function animate() - three.js r84

Inspired by ParametricGeometries ( #author zz85 ), I have programmed an addon for three.js (named THREEf, updated 22.03.) to produce with only 9 properties, 18 functions and 1 array almost infinite many time-varying geometries:
geometry = new THREE.Geometry();
geometry.createMorphGeometry = THREEf.createMorphGeometry; // insert the methode from THREEf.js
geometry.createMorphGeometry(); // apply the methode ( here without parameters: all default )
After a while I noticed a memory leak. I thought I had made a mistake and searched the entire code. But nothing found! The error then suddenly disappeared when some code blocks were removed. The error occurs when the material index is renewed in the animate function.
geometry.faces[ index ].materialIndex = geometry.materialCover( .. , .. , t ); // in THREEf
respectively ( in animate() )
t = clock.getElapsedTime();
geometry.elementsNeedUpdate = true; // sufficient
// geometry.colorsNeedUpdate = true;
// material.needsUpdate = true;
geometry.faces[ 0 ].materialIndex = Math.floor( 5 * t ) % 3;
in the following very simple example that results in a fairly slow memory allocation.
'use strict'
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 2000 );
camera.position.set( 10, 20, 30 );
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xdddddd, 1 );
var container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
var orbit = new THREE.OrbitControls( camera, renderer.domElement );
orbit.enableZoom = true;
var clock = new THREE.Clock( true );
var t; // time
var materials = [
new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.DoubleSide } ), // red
new THREE.MeshBasicMaterial( { color: 0x00ff00, side: THREE.DoubleSide } ), // green
new THREE.MeshBasicMaterial( { color: 0x0000ff, side: THREE.DoubleSide } ) // blue
];
var material = new THREE.MultiMaterial( materials );
var geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( -10, -10, -10 ) );
geometry.vertices.push( new THREE.Vector3( 10, -10, 0 ) );
geometry.vertices.push( new THREE.Vector3( 10, 10, 10 ) );
var face = new THREE.Face3( 0, 1, 2 );
geometry.faces.push( face );
scene.add( new THREE.Mesh( geometry, material ) );
animate();
//...............
function animate() {
requestAnimationFrame( animate );
t = clock.getElapsedTime();
geometry.elementsNeedUpdate = true;
//geometry.colorsNeedUpdate = true;
//material.needsUpdate = true;
geometry.faces[ 0 ].materialIndex = Math.floor( 5 * t ) % 3;
renderer.render( scene, camera );
controls.update();
}
<!DOCTYPE html>
<!-- memory leak -->
<html lang="de"><head><title> memory leak </title> <meta charset="utf-8" /></head>
<body> memory leak when updating material index in function animate()</body>
<script src="../js/three.min.84.js"></script>
<script src="../js/OrbitControls.js"></script>
See under http://threejs.hofk.de/memoryleak/memoryLeak.html
In my "function geometry", the browser crashes faster. You can try this at http://sandbox.threejs.hofk.de/ (currently only with Firefox)
and there is a way to basic examples - also other browsers.
There is a library of forms in progress.
I have looked in three.js but this is really great and I have too little knowledge to recognize something there.
How to fix the memory leak?
After WestLangley had answered my Question ( to change the face colors ) I have looked for many examples.
I have found the following:
https://github.com/mrdoob/three.js/blob/master/examples/webgl_objects_update.html
And in this example the answer is.
To change the faces you need
geometry.elementsNeedUpdate = true;
but to change the material index is used
geometry.groupsNeedUpdate = true;
This update is not available in the documentation
"How to update things" where I've looked.
There is the enumeration
object.updateMatrix();
...
geometry.elementsNeedUpdate = true;
...
texture.needsUpdate = true;
Then I looked in three.js revision 84 to the function DirectGeometry ().
I found this.groupsNeedUpdate = ...
It can be seen that the material index is related to the group.
Conclusion:
I just had to change a single command instead
geometry.elementsNeedUpdate = true;
now
geometry.groupsNeedUpdate = true;
and the sandbox has no memory leak anymore.
But if I want to change the faces as in the example https://github.com/mrdoob/three.js/blob/master/examples/webgl_objects_update.html
there is still a problem.
I used the test 50 (given 1000 slowly)
function animate() { setTimeout( animate, 50 ); ...
Then the memory leak occurs:
function randomizeFaces( object ) { ... geometry.elementsNeedUpdate = true; ...
I think then you have to use shader.

Error in loading physi.js and ammo.js

I'm trying to develop a project with physijs. I have encountered this type of error (from mozilla firefox console):
NetworkError: Failed to load worker script at "js/libs/ammo.js"
I'm trying to fix it but with no results. This is my code snippet on physijs setup:
<script src="build/three.js"></script>
<script src="js/libs/physi.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/Detector.js"></script>
<script>
'use strict';
Physijs.scripts.worker = 'js/libs/physijs_worker.js';
Physijs.scripts.ammo = 'js/libs/ammo.js';
All javascript files are in js directory, except for Three.js building files (that are in build directory). I have no idea what's wrong in my code, I create only lights, ground (compoud shapes following Physijs rules) and a bag (that I want to apply a cone-twist constaint but for previous reasons doesn't work).
I add even the code that I use to initialize the scene (if in case there is something wrong):
function createScene() {
var container = document.getElementById( 'container' );
//stats = new Stats();
//container.appendChild( stats.dom );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.x = 0;
camera.position.z = 17;
camera.position.y = 12;
//scene = new THREE.Scene();
scene = new Physijs.Scene;
scene.setGravity(new THREE.Vector3( 0, -10, 0 ));
renderer = new THREE.WebGLRenderer();
renderer.physicallyCorrectLights = true;
//renderer.gammaInput = true;
//renderer.gammaOutput = true;
renderer.shadowMap.enabled = true;
//renderer.shadowMapType = THREE.PCFSoftShadowMap;
//renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.target.set( 0, 0, 0 );
controls.noPan = true; //disable panning of orbit control
controls.noKeys = true; //disable arrow keys of orbit control
controls.update();
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener( 'keydown', onKeyDown, false );
window.addEventListener( 'keyup', onKeyUp, false );
}
How can I fix this problem and import correctly Physi.js?
SOLVED I used a local web server (Three.js's reference)and changed this:
Physijs.scripts.worker = 'js/libs/physijs_worker.js';
Physijs.scripts.ammo = 'ammo.js';

Getting SSAO shader working with SkinnedMesh

I've been attempting to get the SSAO post-processing shader to work with the latest (r77) version of three.js. I've been using the EffectComposer, with the code entirely duplicated from the example page here:
http://threejs.org/examples/webgl_postprocessing_ssao.html
The relevant code being:
var renderPass = new THREE.RenderPass( Engine.scene, Engine.camera );
ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
ssaoPass.renderToScreen = true;
// ...various ShaderPass setup parameters
Engine.effectComposer = new THREE.EffectComposer( Engine.renderer );
Engine.effectComposer.addPass(renderPass);
Engine.effectComposer.addPass(ssaoPass);
The issue I have been having is that that SSAO doesn't seem to work with SkinnedMeshes. It seems to take into account the position of the meshes before the skinning calculations are performed.
It looks like this:
Problem with SSAO on SkinnedMesh
Does anyone have any experience with this on the latest version? I've looked all over the place, but can't find any documentation about how to start fixing this at all.
I found mention of a fix for this in another SO post (ThreeJS SSAO Shader w/ Skinned/Animated Models), but the solution has been deprecated.
Thanks in advance, and happy to go into more detail if needed.
As requested, here is the complete code for the simple demo page:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="js/libs/jquery.min.js"></script>
<script type="text/javascript" src="js/libs/three.min.js"></script>
<script type="text/javascript" src="js/libs/postprocessing/CopyShader.js"></script>
<script type="text/javascript" src="js/libs/postprocessing/EffectComposer.js"></script>
<script type="text/javascript" src="js/libs/postprocessing/MaskPass.js"></script>
<script type="text/javascript" src="js/libs/postprocessing/RenderPass.js"></script>
<script type="text/javascript" src="js/libs/postprocessing/ShaderPass.js"></script>
<script type="text/javascript" src="js/libs/postprocessing/DotScreenShader.js"></script>
<script type="text/javascript" src="js/libs/postprocessing/SSAOShader.js"></script>
<link rel="stylesheet" type="text/css" href="demo.css" />
</head>
<body>
<div id="demo-container"></div>
</body>
</html>
<script>
$(document).ready(function() {
window.doPostPro = 0;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 1, 1000);
camera.position.set(0, 200, 200);
camera.lookAt(new THREE.Vector3(0, 0, 0));
clock = new THREE.Clock();
// Setup the renderer.
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xFFFFFF );
function setupPostProcessing() {
// Setup render pass
var renderPass = new THREE.RenderPass( scene, camera );
// Setup depth pass
depthMaterial = new THREE.MeshDepthMaterial();
depthMaterial.depthPacking = THREE.RGBADepthPacking;
depthMaterial.blending = THREE.NoBlending;
depthRenderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
stencilBuffer: true
});
// Setup SSAO pass
ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
ssaoPass.renderToScreen = true;
//ssaoPass.uniforms[ "tDiffuse" ].value will be set by ShaderPass
ssaoPass.uniforms[ "tDepth" ].value = depthRenderTarget.texture;
ssaoPass.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight );
ssaoPass.uniforms[ 'cameraNear' ].value = camera.near;
ssaoPass.uniforms[ 'cameraFar' ].value = camera.far;
//ssaoPass.uniforms[ 'onlyAO' ].value = ( postprocessing.renderMode == 1 );
ssaoPass.uniforms[ 'aoClamp' ].value = 0.3;
ssaoPass.uniforms[ 'lumInfluence' ].value = 0.5;
// Add pass to effect composer
effectComposer = new THREE.EffectComposer( renderer );
effectComposer.addPass( renderPass );
effectComposer.addPass( ssaoPass );
};
setupPostProcessing();
// Load the mesh.
var loader = new THREE.JSONLoader();
loader.load( "js/zombie.js", function( geometry, materials ) {
var originalMaterial = materials[ 0 ];
originalMaterial.skinning = true;
geometry.computeVertexNormals();
var mesh = new THREE.SkinnedMesh(geometry, originalMaterial);
window.animMixer = new THREE.AnimationMixer(mesh);
var animAction = animMixer.clipAction(geometry.animations[0]);
animAction.play();
scene.add(mesh);
});
var ambientLight = new THREE.AmbientLight( 0xCCCCCC );
scene.add( ambientLight );
$("#demo-container").append( renderer.domElement );
function render() {
if ( doPostPro ) {
// Render depth into depthRenderTarget
scene.overrideMaterial = depthMaterial;
renderer.render( scene, camera, depthRenderTarget, true );
// Render renderPass and SSAO shaderPass
scene.overrideMaterial = null;
effectComposer.render();
}
else {
renderer.render( scene, camera );
}
}
function animate() {
requestAnimationFrame( animate );
if ( window.animMixer != undefined ) {
var deltaTime = clock.getDelta();
animMixer.update(deltaTime);
}
render();
}
animate();
$(document).keyup(function(e) {
// P is pressed.
if ( e.which == 80 ) {
window.doPostPro = !window.doPostPro;
}
});
});
</script>
If you are skinning, and using this pattern in your render loop
// Render depth into depthRenderTarget
scene.overrideMaterial = depthMaterial;
renderer.render( scene, camera, depthRenderTarget, true );
you have to make sure to set
depthMaterial.skinning = true;
Thing is, if there are other elements in the scene that are not skinned, doing so will throw errors. In which case, this may be a three.js design issue that will have to be addressed.
three.js r.77

Copy/pasted JsonLoader from Threejs.org not working

So I am trying to get a JSONLoader to work from threejs.org
Three.js is working for sure because I have no problem creating a cube. But when I try to load a js file throuh JSONLoader then nothing happens.
<html>
<head>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="three.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer( { alpha: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// instantiate a loader
var loader = new THREE.JSONLoader();
// load a resource
loader.load(
// resource URL
'logo.js',
// Function when resource is loaded
function ( geometry, materials ) {
var material = new THREE.MultiMaterial( materials );
var object = new THREE.Mesh( geometry, material );
scene.add( object );
}
);
camera.position.z = 5;
var render = function () {
renderer.setClearColor( 0x000000, 0 );
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
As mentioned in the title then the code is copy pasted from threejs own website and should be working.
Can someone help me figure what is going wrong?
here is a fiddle with the script of logo.js https://jsfiddle.net/380z6096/
the object has been exported from 3ds max with the 3ds Max JSExporter
I am using xampp and chrome.
Your camera is inside your geometry.
You can determine the dimensions of your geometry like so
geometry.computeBoundingSphere();
console.log( geometry.boundingSphere );
or
geometry.computeBoundingBox();
console.log( geometry.boundingBox );
Scale your geometry
object.scale.multiplyScalar( 0.01 );
Or move your camera back.
three.js r.75

Cannot initialize dat.GUI in Three.js

When i run my code, i get the following error in this line:
var gui = new dat.GUI();
error: Unable to get the 'getItem' property null reference or undefined.
I imported the library, i don't know what is wrong, here is my code:
<html>
<head>
<title>Stack Overflow</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<div id="container"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="js/three.min.js"></script>
<script src="js/optimer_regular.typeface.js"></script>
<script src="js/TrackballControls.js"></script>
<script src="js/stats.min.js"></script>
<script src="js/threex.dynamictexture.js"></script>
<script src="js/dat.gui.min.js"></script>
<script>
//Basic Three components
var scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000 );
//position camera
camera.position.z = 700;
//Set camera controls
var controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
//Set the renderer
var renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//Set the lights
var light;
scene.add( new THREE.AmbientLight( 0x404040 ) );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 1, 1 );
scene.add( light );
//Let's add a cute cube
var object;
var map = THREE.ImageUtils.loadTexture( 'images/UV_Grid_Sm.jpg' );
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 16;
var material = new THREE.MeshLambertMaterial( { ambient: 0xbbbbbb, map: map, side: THREE.DoubleSide } );
object = new THREE.Mesh( new THREE.BoxGeometry( 100, 100, 100, 4, 4, 4 ), material );
object.position.set( 400, 20, 50 );
scene.add( object );
//Let's add a GUI
var API = {
'show model' : true,
'show skeleton' : false
};
var gui = new dat.GUI();
function animate() {
requestAnimationFrame( animate );
render();
}
//Render scene
function render() {
controls.update();
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>
Solution: Don't use Internet Explorer, i run the same code in Firefox and it works.
Follow this steps
First Close your existing project and open a new folder.
then go to this folder location in terminal by {cd [path]}
Run this commands:
1.https://github.com/designcourse/threejs-webpack-starter.git
2.npm install
3.npm run dev
4.npm run build
after no.3 execution you may face some warnings try to ignore or if you see some fatal issues then run
npm audit fix
not solved yet ....run..
npm audit fix --force [couple of time if need]
after running no.3 if you browser opens then all is fine.
you can dat.gui is installed in your folder just use it customize as you want.
you will find all the required files in your newly created folder.

Categories