三js表演

时间:2014-03-28 10:38:04

标签: javascript html three.js rendering webgl

我开始使用three.js和webgl进行一个小项目。我想根据用户输入创建一个衣柜模型。你可以在这里找到这个项目:

http://jfeldmann.pf-control.de/threejs/

没有材质和阴影,它渲染速度非常快,轨道非常平滑,但如果我启用阴影贴图并添加我的材质,它会变得越来越慢。所以我的问题是,如果我的代码中存在任何性能问题或可能的增强功能。纹理的文件大小介于10到70 KB之间。

这是主要的JS代码:

var WIDTH = 800,
    HEIGHT = 600;

// set some camera attributes
var VIEW_ANGLE = 45,
    ASPECT = WIDTH / HEIGHT,
    NEAR = 1,
    FAR = 10000;

// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');

// create a WebGL/Canvas renderer, camera

var renderer = new THREE.WebGLRenderer();   
var camera = new THREE.PerspectiveCamera(  VIEW_ANGLE,
                                ASPECT,
                                NEAR,
                                FAR  );
var scene = new THREE.Scene();

var mouse = new THREE.Vector2()
var INTERSECTED;
var objects = [];

//Variables from Form

var stange, hoehe, breite, anzahl_tueren, mesh, schrank, door, door_1, door_2, door_3, plane, breite_hoehe_tiefe, material_selected, projector, raycaster;
var error_breite = document.getElementById('err_msg_breite');
var error_hoehe = document.getElementById('err_msg_hoehe');
var error_tiefe = document.getElementById('err_msg_tiefe');
var tiefe = 0;  
var mirrorCube, mirrorCubeCamera;


//Form-Data 
$("#submit_btn").bind("click", change);
$( "#opacity_slider" ).change(function() {    
        door_1.material.transparent = true;
        door_1.material.opacity = document.getElementById('opacity_slider').value/100;
        door_2.material.transparent = true;
        door_2.material.opacity = document.getElementById('opacity_slider').value/100;
        door_3.material.transparent = true;
        door_3.material.opacity = document.getElementById('opacity_slider').value/100;
});

//Materials 
var material_basic = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/basic.jpg'), color: 'white'});
material_selected = material_basic;

var material_schrank = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/basic.jpg')});

var material_door_1 = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/basic.jpg')});
var material_door_2 = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/basic.jpg')});
var material_door_3 = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/basic.jpg')});

var material_eiche = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/eiche.jpg')});    
var material_buche = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/buche.jpg')});    
var material_birke = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/birke.jpg')});
var material_mirror = new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('img/mirror.jpg')});  

//Lights
var pointLight_front = new THREE.DirectionalLight( 0xaaaaaa, 0.6 ); 
var pointLight_back = new THREE.AmbientLight( 0xaaaaaa ); 


function change(){      

    objects = [];   

    scene.remove(schrank);
    scene.remove(door);
    scene.remove(pointLight_front);
    scene.remove(stange);       

    if(document.getElementById('breite').value<=400){       
        breite = parseInt(document.getElementById('breite').value,10);
        error_breite.innerHTML = "";
    }
    else error_breite.innerHTML = "Maximale Breite 400cm.";

    if(document.getElementById('hoehe').value<=300){        
        hoehe = parseInt(document.getElementById('hoehe').value,10);
        error_hoehe.innerHTML = "";
    }
    else error_hoehe.innerHTML = "Maximale Höhe 300cm.";

    if(document.getElementById('tiefe').value<=90){     
        tiefe = parseInt(document.getElementById('tiefe').value,10);
        error_tiefe.innerHTML = "";
    }
    else error_tiefe.innerHTML = "Maximale Tiefe 90cm.";    

    anzahl_tueren = parseInt(document.getElementById('anzahl_tueren').value,10);

    breite_hoehe_tiefe = Math.max(breite,hoehe,tiefe);

    //Floor                 
    var ground = new THREE.CubeGeometry( breite_hoehe_tiefe*10, 1, breite_hoehe_tiefe*10 );
    var white_material = new THREE.MeshBasicMaterial( { color: 0xfafafa, opacity : 1 } );
    plane = new THREE.Mesh(ground, white_material);
    plane.position.y = -1;      
    plane.receiveShadow = true; 

    //Schrank Basis
    var basis_geo = new THREE.CubeGeometry( breite, hoehe, tiefe );
    var basis_mesh = new THREE.Mesh( basis_geo );
    basis_mesh.position.z = -10;
    var basis_bsp = new ThreeBSP( basis_mesh );

    var schrank_width = 10;

    var basis_inner_geo = new THREE.CubeGeometry( breite-schrank_width, hoehe-schrank_width, tiefe+schrank_width );
    var basis_inner_mesh = new THREE.Mesh( basis_inner_geo );
    basis_inner_mesh.position.z = 0;
    var basis_inner_bsp = new ThreeBSP( basis_inner_mesh );

    var subtract_bsp = basis_bsp.subtract( basis_inner_bsp );
    schrank = subtract_bsp.toMesh( material_schrank );
    schrank.position.y = (hoehe/2); 
    schrank.castShadow = true;
    schrank.receiveShadow = true;       

    //Kleiderstange           
    if(document.getElementById('kleiderstange_check').value == 1){
        var stange_geo = new THREE.CylinderGeometry( 3, 3, breite-schrank_width, 8, 1 );
        stange = new THREE.Mesh(stange_geo, material_basic);
        stange.rotation.z = 90*Math.PI/180;
        stange.position.y = hoehe-40;
        document.getElementById("data_test").innerHTML = "Stange: Ja"+document.getElementById('kleiderstange_check').value;
    }
    else document.getElementById("data_test").innerHTML = "Stange: Nein"+document.getElementById('kleiderstange_check').value;

    //Türen 
    var door_width = 5;
    var door_seperation = 0.5;
    var door_geo = new THREE.CubeGeometry( ((breite-schrank_width)/anzahl_tueren)-door_seperation, hoehe-schrank_width, door_width );       
    door = new THREE.Object3D();
    door.position.z = (tiefe/2)-schrank_width-(door_width/2);

    if (anzahl_tueren==1) {
        door_1 = new THREE.Mesh(door_geo, material_door_1);
        door_1.position.z = 0;
        door_1.position.x = 0;                  
        door_1.castShadow = true;
        door_1.receiveShadow = true;
        door.add(door_1);
    }

    //add new door to door Mesh!!
    if (anzahl_tueren==2){
        door_1 = new THREE.Mesh(door_geo, material_door_1);
        door_1.position.z = 0;              
        door_1.castShadow = true;
        door_1.receiveShadow = true;
        door.add(door_1);           
        door_1.position.x = ((breite-(schrank_width))/4*(-1))-(door_seperation/4);          

        door_2 = new THREE.Mesh(door_geo, material_door_2);
        door_2.position.z = 0;
        door_2.position.x = ((breite-(schrank_width))/4)+(door_seperation/4);
        door_2.castShadow = true;
        door_2.receiveShadow = true;
        door.add(door_2);               
    }
    if (anzahl_tueren==3){

        door_1 = new THREE.Mesh(door_geo, material_door_1);
        door_1.position.z = 0;              
        door_1.castShadow = true;
        door_1.receiveShadow = true;
        door.add(door_1);           
        door_1.position.x = ((breite-(schrank_width))/3*(-1))-(door_seperation/4);          

        door_2 = new THREE.Mesh(door_geo, material_door_2);
        door_2.position.z = 0;
        door_2.position.x = 0;
        door_2.castShadow = true;
        door_2.receiveShadow = true;    
        door.add(door_2);   

        door_3 = new THREE.Mesh(door_geo, material_door_3);
        door_3.position.z = 0;
        door_3.position.x = (((breite-(schrank_width))/3)+(door_seperation/4));
        door_3.castShadow = true;
        door_3.receiveShadow = true;    
        door.add(door_3);   

    }
    door.position.y = (hoehe/2);
    door.castShadow = true;
    door.receiveShadow = true;  

    // set Light position
    pointLight_front.position.x = breite;
    pointLight_front.position.y = hoehe+500;
    pointLight_front.position.z = tiefe+300;
    pointLight_front.shadowCameraNear = 20; 
    pointLight_front.shadowCameraFar = 5000;    
    pointLight_front.shadowBias = 0.001;

    pointLight_front.shadowCameraLeft = -breite_hoehe_tiefe;
    pointLight_front.shadowCameraRight = breite_hoehe_tiefe;
    pointLight_front.shadowCameraTop = breite_hoehe_tiefe;
    pointLight_front.shadowCameraBottom = -breite_hoehe_tiefe;

    pointLight_front.shadowCamera.near = pointLight_front.shadowCameraNear;
    pointLight_front.shadowCamera.far = pointLight_front.shadowCameraFar;       
    pointLight_front.shadowCamera.left = pointLight_front.shadowCameraLeft;
    pointLight_front.shadowCamera.right = pointLight_front.shadowCameraRight;
    pointLight_front.shadowCamera.top = pointLight_front.shadowCameraTop;
    pointLight_front.shadowCamera.bottom = pointLight_front.shadowCameraBottom;

    pointLight_front.shadowCamera.updateProjectionMatrix();

    objects.push(schrank);
    objects.push(door.children[0]); 
    objects.push(door.children[1]); 
    objects.push(door.children[2]); 
    objects.push(stange);   
}   


init();
animate();

function init() {       

    projector = new THREE.Projector();
    raycaster = new THREE.Raycaster();  

    // the camera starts at 0,0,0 so pull it back
    camera.position.set(0,500,500);

    // start the renderer
    renderer.setSize(WIDTH, HEIGHT);
    renderer.setClearColor( 0xfafafa );
    renderer.sortObjects = false;
    // to antialias the shadow
    renderer.shadowMapType = THREE.PCFSoftShadowMap;
    renderer.shadowMapEnabled = true;

    // attach the render-supplied DOM element
    $container.append(renderer.domElement);          

    // and the camera
    scene.add(camera);

    // create a point light     
    pointLight_front.castShadow = true;
    pointLight_front.shadowDarkness = 0.07;
    pointLight_front.shadowMapWidth = 4096;
    pointLight_front.shadowMapHeight = 4096;    

    //make Light Cone visible to camera
    //pointLight_front.shadowCameraVisible = true; 

    pointLight_back.position.set( -150, 200, 250 );

    controls = new THREE.OrbitControls(camera, renderer.domElement);

    document.addEventListener( 'click', onDocumentMouseClick, false );
    //window.addEventListener( 'resize', onWindowResize, false );
}

function onWindowResize() {

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );

}

function onDocumentMouseClick( event ) {

    event.preventDefault();

    mouse.x = ( (event.clientX-7) / WIDTH ) * 2 - 1; 
    mouse.y = 1 - ( (event.clientY-7) / HEIGHT ) * 2;
    //client.X / client.Y - 7 berücksichtigt den margin der body, der den canvas verschiebt

    // find intersections

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
    projector.unprojectVector( vector, camera );

    raycaster.set( camera.position, vector.sub( camera.position ).normalize() );

    var intersects = raycaster.intersectObjects( objects );

    if ( intersects.length > 0 ) {              
        INTERSECTED = intersects[0].object;
        INTERSECTED.material.map = material_selected.map;

    } else {    
        //document.getElementById("data_test").innerHTML = "not intersected";           
    }

}

function animate() {      

  // Read more about requestAnimationFrame at http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
  requestAnimationFrame(animate);      
  scene.add(pointLight_front);
  scene.add(pointLight_back);
  scene.add(plane);
  scene.add(schrank);
  scene.add(door);
  scene.add(stange);
  render();
}

function render(){    

  // Render the scene.    
  renderer.render(scene, camera);     
  controls.update();    
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

我建议您使用http://stemkoski.github.io/Three.js/GUI-Controller.html控件,您可以更改一些更轻的尺寸,其他示例:http://all.develoteca.com/builder/?model=book