0

I'm trying to create webgl animation for my website background, inspired by "threejs - Cloud exemple" (http://mrdoob.com/lab/javascript/webgl/clouds/). On my computer it seems rather well... But for some PC it's very slow.

Is there a way to further optimize my code, and detect if the graphics card does not support webgl ?

My animation (in background) : http://wabeo.fr/?theme=auriga-7

My code :

var container = document.getElementById('container');
var wi       = window.innerWidth;
var he       = window.innerHeight;
var renderer  = new THREE.WebGLRenderer({
antialias: true
});
var scene    = new THREE.Scene();
var camera   = new THREE.PerspectiveCamera(75,wi/he,1,10000);
var distance = 500;
var geometry2 = new THREE.Geometry();

renderer.setSize(wi ,he);
container.appendChild(renderer.domElement);
scene.add(camera);

var texture = THREE.ImageUtils.loadTexture( '/wp-content/themes/auriga-7/i/cloud.png' );
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;

var m = new THREE.MeshBasicMaterial( {color:0x000000} );
var material = new THREE.MeshBasicMaterial( { map: texture,transparent: true} );
var plane = new THREE.PlaneGeometry( 400,400,4,4 );


for ( ix = 0; ix <45; ix++ ) {
    item = new THREE.Mesh( plane, m );
    item.position.x = ((Math.random()-0.5)*(Math.random() * wi/2) /4)*Math.random()*10;
    item.position.y = ((Math.random()-0.5)*(Math.random() * he/2) /4)*Math.random()*10;
    item.position.z = ix*10-50;
    item.rotation.z = Math.random() *250;
    item.scale.x = item.scale.y = Math.random() * Math.random() * 2 + 0.5;

    THREE.GeometryUtils.merge(geometry2,item);
}

mesh = new THREE.Mesh( geometry2, material );
scene.add(mesh);

camera.position.z = distance;
camera.lookAt(scene.position);
renderer.sortObjects = false;


// create a point light
var pointLight =
  new THREE.PointLight(0xFFFFFF);

// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;

// add to the scene
scene.add(pointLight);
requestAnimationFrame(wanarender);

document.addEventListener('mousemove',onMouseMove, false);
window.addEventListener('resize',onResizeMyFuckinBrowser,false);
function onMouseMove(event){

    var mouseX = event.clientX - wi/2;
    var mouseY = event.clientY - he/2;

    camera.position.x = (mouseX - camera.position.x) * 0.02;
    camera.position.y = (-mouseY - camera.position.y) * 0.02;
    camera.position.z = distance;
    camera.lookAt(scene.position);
}
function onResizeMyFuckinBrowser(){
    var wi       = window.innerWidth;
    var he       = window.innerHeight;
    renderer.setSize(wi ,he);
}
function wanarender(){
    requestAnimationFrame(wanarender);
    renderer.render(scene, camera);
}

Thanks for your help :-)

Willy
  • 23
  • 6
  • Hi there. Please consider marking an answer as correct. People on this site will often spend considerable time answering your questions, and marking an answer as correct is appreciated. It also helps to make the site better, by pointing people to the best information. Thanks. – null Oct 24 '12 at 23:24
  • @null He can't since there probably isn't a correct answer yet. - What I figured is, that it depends on the system your app is running on. There's really nothing you can do when the system is outdated. – Tom May 20 '20 at 13:12

2 Answers2

4

Just looking quickly at the Mr Doob code, I notice a couple of optimisations that might help you. If you inspect Mr Doob's example, you can see that his cloud texture is a 256 x 256 px image, while yours is 800 x 800. There are two things to consider here:

Firstly, try to use powers of 2 for your texture sizes, ie 256, 512, 1024... This is because the graphics card is optimised for textures with these dimensions.

Secondly, 800 x 800 is probably much bigger than you really need, as the Mr Doob demo demonstrates. Most of the time, your texture is being scaled down to half the size or less.

Another thing that stands out in the Mr Doob demo is that he is using mipmaps. Mipmaps are when the graphics card pre-caches multiple versions of the texture at different scales, and uses the closest one to the current level at any given time. This makes the texture scaling more efficient, so turning them on might speed things up for you a little.

Your Code:

texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;

Mr Doob's Code:

texture.magFilter = THREE.LinearMipMapLinearFilter;
texture.minFilter = THREE.LinearMipMapLinearFilter;

Regarding detection of WebGL, See this Stack Overflow answer for information:

Three.js detect webgl support and fallback to regular canvas

Community
  • 1
  • 1
null
  • 1,187
  • 1
  • 8
  • 20
0

I'm new to Three.jS myself but it is quite problematic to optimise your code. Few things I learned. Render before you append element if you don't like the flash of black. keep you geometry and textures simple. The more complicated the shape, and the more images used as textures, the slower it gets. I'm sure there's a way to optimise the graphics, but I don't know it yet. Start by trying to solve that problem.

Naman Goel
  • 1,525
  • 11
  • 16