我开始使用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();
}
非常感谢任何帮助。
答案 0 :(得分:1)
我建议您使用http://stemkoski.github.io/Three.js/GUI-Controller.html控件,您可以更改一些更轻的尺寸,其他示例:http://all.develoteca.com/builder/?model=book