当我更改预设时,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);
});
我发现这是创建组件的简单方法。但当然总有更聪明的东西;-)