如何在dat.gui预设更改时仅更新three.js场景一次?

时间:2017-08-26 04:11:07

标签: javascript three.js dat.gui

当我更改预设时,DAT.GUI会为每个属性触发更改事件。在这种情况下,场景会更新两次:

addGui( 'Ambientcolor', ambient.color.getHex(), function( val ) {
    ambient.color.setHex( val );
    renderer.render( scene, camera ); // renderScene()
}, true );
addGui( 'Ambient intensity', ambient.intensity, function( val ) {
    ambient.intensity = val;
    renderer.render( scene, camera ); // renderScene()
}, false, 0, 2.0 );

function addGui( name, value, callback, isColor, min, max ) {
    var node;
    param[ name ] = value;
    if ( isColor ) {
                    node = gui.addColor( param, name ).onChange( function() {
                    callback( param[ name ] );
                } );
    } else if ( typeof value == 'object' ) {
                    node = gui.add( param, name, value ).onChange( function() {
                    callback( param[ name ] );
                } );
    } else {
                    node = gui.add( param, name, min, max ).onChange( function() {
                    callback( param[ name ] );
                } );
            }
    gui.remember(param);
    return node;
}

每个预设更改我有27个控制器= 27个渲染。进行此场景更新的方法是什么?

编辑1 也许它与回调函数有关? 我现在做了一个(不那么漂亮)的解决方法。控制器更新在蹩脚的图形卡上大约需要5毫秒。所以我用一个计时器做了一个渲染函数,以防止渲染每20毫秒被激发一次以上。

    var t0=0, t1=0;
    var perf=[]; // for displaying time
    function renderScene() {
         t1 = performance.now();
         perf.push(t1);
         if (Math.abs(t1-t0)>20) {
             t0 = performance.now();
             var myVar = setInterval(myTimer, 19);

             function myTimer() {
                 renderer.render( scene, camera );
                    perf.push(performance.now());
                    clearInterval(myVar);
                    alert(perf.join('\n'));
             }
         }
    }

编辑2 我已经消除了回调函数,但我仍然有渲染更新问题。在这个示例中,我创建了2个控制器的2个文件夹,我在1个presetchange上获得了4个sceneupdates。

var o1 = gui_mesh.addFolder('Mesh1');
AddObjectToFolder(o1,0,mesh1);
var o2 = gui_mesh.addFolder('Mesh2');
AddObjectToFolder(o2,1,mesh2);

function AddObjectToFolder(f,fi,mesh) {
      paramMesh[fi][ 'XY Scale' ] = mesh.scale.x;
      f.add( paramMesh[fi], 'XY Scale', 0.50 , 6.00 ).onChange( function(val) {
                    mesh.scale.x = val;
                    mesh.scale.y = val;
                    renderer.render( scene, camera );
      } );


      paramMesh[fi][ 'Repeat x' ] = mesh.material.map.repeat.x;
      f.add( paramMesh[fi], 'Repeat x', 0, 2.0 ).onChange( function(val) {
                    mesh.material.map.repeat.x = val;
                    mesh.material.map.repeat.y = val;
                    mesh.material.map.needUpdate=true;
                    renderer.render( scene, camera );
       } );
       gui_mesh.remember(paramMesh[fi]);

 }

很明显为什么在每个onChange事件中使用render-function,但我该怎么做?

编辑3 /替代解决方案

我通过将Watch.JS与DAT GUI一起使用来想出另一种解决此问题的方法。这是必须为您需要的每个组件编码的函数。在这种情况下,一个three.js项目:

var guiObj = guiObj || {}


function guiWatch(idName) {

    this.params = {};
    this.paramObj={};

    this.setVal= function(name,val){
        this.paramObj[name].setValue(val);
        this.paramObj[name].updateDisplay();
    }

    this.createFloat = function(name, title, min, max, val0, steps, func) {
        this.params[name]=val0;
        this.paramObj[name]=this.gui.add(this.params, name, min, max).step(steps);
        watch(this.params, name, func);
    }

    this.createColor = function(name, title, val0, func) {
        this.params[name]=val0;
        this.paramObj[name]=this.gui.addColor(this.params, name);
        watch(this.params, name, func);
    }

}

然后我初始化一些Gui(不是文件夹):

guiObj['editRepair']= new guiWatch('guiEditRepair',function(val){ renderScene(); });
guiObj['editPaint']= new guiWatch('guiEditPaint',function(val){ renderScene(); });

然后创建组件:

guiObj['editRepair'].createColor('color','Color','#ffffff',
      function(prop, action, val){ 
           var hCol=hexToRgb(val);
          setColorDifMap(hCol.r,hCol.g,hCol.b); 
});

guiObj['editRepair'].createFloat('size','Size',2,200,50, 1,
      function(prop, action, val){ 
          scaleCursor(val,false); 

}); 

guiObj['editPaint'].createColor('color','Color','#ffffff',
    function(prop, action, val){ 
          var hCol=hexToRgb(val);
          setColorDifMap(hCol.r,hCol.g,hCol.b);
});

guiObj['editPaint'].createFloat('size','Size',2,200,50, 1,
      function(prop, action, val){ 
          scaleCursor(val,false); 
});

guiObj['editPaint'].createFloat('depth','Depth',2,256,10, 1,
      function(prop, action, val){ 
          setTextureDepth(val); 
});

我发现这是创建组件的简单方法。但当然总有更聪明的东西;-)

0 个答案:

没有答案