Sas*_*dar 6 3d animation webgl three.js
在我的场景中,我有4个点光源3连接在相机上,大约100到300个立方体.我有很多类别的立方体,每个立方体在100 - 300之间.根据用户菜单选择,我的场景中可能只会出现一类立方体.
(100个立方体的类别)renderer.info:
memory:
Objectgeometries: 2
programs: 3
textures: 100
render:
calls: 203
faces: 1360
points: 0
vertices: 4080
Run Code Online (Sandbox Code Playgroud)
在循环中,我为每个类别生成我的立方体,如下所示:
var materials = [
backgroundMaterial,
backgroundMaterial,
backgroundMaterial,
backgroundMaterial,
productMaterial,
backgroundMaterial
];
var cubeMaterial = new THREE.MeshFaceMaterial( materials );
var object3D = new THREE.Mesh( geometryBox, cubeMaterial );
Run Code Online (Sandbox Code Playgroud)
材料backgroundMaterial在循环外定义一次;
var backgroundMaterial = new THREE.MeshPhongMaterial({
color: this.options.models.boxColor,
specular: this.options.models.boxSpecular,
//emissive : 0xefefef,
//side: THREE.DoubleSide,
overdraw: false,
transparent: false,
metal:true,
shininess: this.options.models.boxShininess,
reflectivity: this.options.models.boxReflectivity,
fog:false
});
Run Code Online (Sandbox Code Playgroud)
因为每个立方体的纹理不同,所以每次在循环内都有productMaterial.
var productMaterial = new THREE.MeshBasicMaterial({
map: productModelTexture,
color: that.options.models.boxColor,
specular: that.options.models.boxSpecular,
//emissive : 0xefefef,
side: THREE.FrontSide,
overdraw: false,
transparent: false,
metal:true,
shininess: that.options.models.textureShininess,
reflectivity: that.options.models.textureReflectivity,
opacity: 1,
fog:false
});
Run Code Online (Sandbox Code Playgroud)
此时我还没有将网格添加到场景中,并将它们设置为 visible = false
之后我将立方体推入数组对象中,该对象内的每个数组都是一类长度在100到300之间的立方体.
当我的应用程序启动时,我运行一个动画,就像一个波纹管,它将一类立方体带入场景.
helix : function( category ) {
if ( this.models[category] && this.models[category].length > 0 ) {
TWEEN.removeAll();
new TWEEN.Tween( this.camera.position ).to( {x:0,y:0,z:90000}, 1000 ).easing( TWEEN.Easing.Exponential.InOut ).start();
new TWEEN.Tween( this.camera.rotation ).to( {x:0,y:0,z:0}, 1000 ).easing( TWEEN.Easing.Exponential.InOut ).start();
this.models.reset( category );
for ( var i in this.models[category] ) {
var model = this.models[category][i];
model.visible = true;
this.scene.add( model );
new TWEEN.Tween( model.position ).to({
x: model.helix.position.x,
y: model.helix.position.y,
z: model.helix.position.z
}, randBtwn( 1000, 3000 ) ).easing( TWEEN.Easing.Exponential.InOut ).delay( 1001 ).start();
new TWEEN.Tween( model.rotation ).to( {
x: model.helix.rotation.x,
y: model.helix.rotation.y,
z: model.helix.rotation.z
}, randBtwn( 1000, 3000 ) ).easing( TWEEN.Easing.Exponential.InOut ).delay( 1001 ).onComplete(function(){
}).start();
}
}
}.bind( that )
Run Code Online (Sandbox Code Playgroud)
此外,你会注意到helix中的另一个函数调用,这个: this.models.reset( category );
这是下面的代码,主要是重置对象位置并将它们设置为visible = false最终从场景中删除它们.
reset : function( category, callback ) {
for ( var j in this.models ) {
if ( this.models[j] instanceof Array && this.models[j].length > 0 && category !== j ) {
for ( var i in this.models[j] ) {
var model = this.models[j][i];
model.visible = true;
new TWEEN.Tween( model.position ).to({
x: model.outside.position.x,
y: model.outside.position.y,
z: model.outside.position.z
}, 1000 ).easing( TWEEN.Easing.Exponential.InOut ).start();
new TWEEN.Tween( model.rotation ).to( {
x: model.outside.rotation.x,
y: model.outside.rotation.y,
z: model.outside.rotation.z
}, 1000 ).easing( TWEEN.Easing.Exponential.InOut ).onComplete(function ( m ){
m.visible = false;
this.scene.remove( m );
if ( callback ) {
callback();
}
}.bind( that, model )).start();
}
}
}
}.bind( that )
Run Code Online (Sandbox Code Playgroud)
在个人电脑中,一切顺利,我以36 fps运行.我的gpu是一个新的nvidia GTX(我不知道36是否可以接受).
问题是,当我尝试在我的nexus 5上使用最新的chrome运行我的应用程序时,在场景外的立方体转换和其他立方体进入之间会出现巨大的fps损失.大多数情况下,这会导致Chrome崩溃...除此之外,如果我不更改类别并且没有播放动画,则可以在我的手机中正常使用.
PS:我不能合并几何,因为每个网格必须在用户选择时自己移动.(如果我没有错误至少)
这可能是导致性能下降/崩溃的原因,以及如何处理在场景外移动200个立方体而在场景内移动200个立方体的类似场景?是否有任何我应该考虑的提示,请记住,我仍然是three.js的新手.
任何其他来源可能是原因请告诉我,我会更新我的问题.
首先,36 fps 是可以接受的。根据经验,我使用 25 fps 作为最低限度。
现在来解决这个问题。Nexus 5 的 GPU 比您的电脑慢得多。由于着色器直接传递到 GPU,因此速度很重要。当您尝试在廉价电脑上玩《孤岛危机》时,这也是同样的问题,GPU 的功能不够强大,无法足够快地处理所有数据。
将所有立方体几何形状添加到一个网格中可能是一种解决方案,也许可以将THREE.MeshFaceMaterial不同的材质应用于每个立方体。具有 100 个几何图形的单个网格的处理速度比具有 1 个几何图形的 100 个网格的处理速度更快。但正如我所说。也可能这根本解决不了任何问题,这更像是万福玛丽。
编辑:在单个网格中添加几何图形并检测单击了哪些几何图形。
我又想了想,检测到点击的几何体是可能的。它并不漂亮,但它可能会给您一些关于如何做得漂亮的想法。只需向几何体的面添加另一个属性即可。
var addGeometry = function(baseGeometry, addedGeometry){
for(i in addedGeometry.faces){
addedGeometry.faces[i].parent = addedGeometry;
}
baseGeometry.add(addedGeometry);
}
Run Code Online (Sandbox Code Playgroud)
那么,当光线投射时,你不会调用该object属性,而是调用face.parent调用属性,它应该包含单击的几何体,您可以随意操作它。
但同样,我不知道这将如何提高性能。不过值得一试。
您可以尝试的其他方法是使用webworkers。
| 归档时间: |
|
| 查看次数: |
642 次 |
| 最近记录: |