我是WebGL和Three.js的新手。我试图想象一下大的圆网格一次改变颜色。
当我增加实例数时,它会明显变慢,更新需要几秒钟。有什么改进我的代码的建议?我可以一次更新4000个圈子吗?
这是我现有的实施:
<html>
<head>
<title>My first Three.js app</title>
<style></style>
</head>
<body>
<script src="./three.js"></script>
<script>
var ROWS = 40
var COLS = 100
var SEGMENTS = 10;
var windowWidth = window.innerWidth, windowHeight = window.innerHeight;
var camera, scene, renderer;
var group, text, plane;
function init() {
// create and append container/canvas
container = document.createElement( 'div' );
document.body.appendChild( container );
// create camera
camera = new THREE.PerspectiveCamera(100, windowWidth / windowHeight, 0.1, 1000 );
// set position of camera
camera.position.z = 500;
camera.position.x = windowWidth/2
camera.position.y = windowHeight/2
// Create a scene
scene = new THREE.Scene();
renderer = new THREE.CanvasRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( windowWidth, windowHeight );
renderer.sortElements = false;
container.appendChild( renderer.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function addCircle(color, x, y, z, s , radius) {
var geometry = new THREE.CircleGeometry(radius, SEGMENTS, SEGMENTS)
var material = new THREE.MeshBasicMaterial( { color: color, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( x, y, z );
mesh.scale.set( s, s, s );
scene.add( mesh );
}
function toHex(d) {
var valueStr = d.toString(16);
valueStr = valueStr.length < 2 ? "0"+valueStr : valueStr;
var fillColor = "0x00" + valueStr + "00";
return parseInt(fillColor);
}
function drawData(data) {
var rows = data.length;
var cols = data[0].length;
distanceBetweenCircles = Math.min(windowWidth/(cols), windowHeight/(rows));
var radius = distanceBetweenCircles/2.0
for(var i = 0; i < data.length; i++) {
for (var j = 0; j < data[0].length; j++) {
var color = toHex(data[i][j])
var x = distanceBetweenCircles*j - radius
var y = distanceBetweenCircles*i - radius
addCircle( color, x, y, 0, 1 , radius-3);
}
}
}
function newData(){
var newData = []
for (var i = 0; i < ROWS; i++) {
var row = [];
for (var j = 0; j < COLS; j ++) {
row.push(Math.floor(Math.random()*255));
}
newData.push(row);
}
return newData;
}
function onDocumentMouseDown ( event ) {
event.preventDefault();
// Update circles
var randomData = newData()
drawData(randomData);
}
var render = function() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
init();
render();
</script>
</body>
</html>
答案 0 :(得分:0)
要将CircleGeometry对象添加到场景,需要将圆圈绘制。将圆形图像/纹理添加到场景中需要将圆圈打印,可以这么说。
乘以4000,绘图变得相当昂贵。
答案 1 :(得分:0)
维护网格数组并更新其属性会更快,而不是每次鼠标点击都会创建一组新的几何,材质和网格。
答案 2 :(得分:-1)
内存管理在软件设计中非常重要。您引入的每个变量都有成本,特别是那些实例化会在某些API调用后调用一系列分配的变量。这是使用像THREE这样的分层的缺点,它隐藏了复杂性,但也隐藏了使用他们的呼叫的后果。没有避免THREE并且自己完成所有WebGL管道(在忽略管道并且只使用像THREE这样的垫片之前总是很好的第一步),做一些功课来确定在调用任何API时创建的内容,例如三。撕掉内部循环变量创建对象,这些对象应该在调用之间重用。对于您的问题,是的,一旦您的架构经过仔细考虑,您可以轻松地在每个动画事件循环时间片上更新4000个圆圈,尤其是如果您使用着色器来制作对象并避免在CPU中进行此类计算
对于纯粹的速度,我建议您通过手工编写OpenGL / WebGL而不是更高级别的抽象库Three.js来学习图形...易于使用的价格往往是更高的计算负荷,可以减少不必要的逻辑如果用手写的话
这是我制作的一个没有Three.js的WebGL玩具......它可以实时更新数十个对象的10个几何体,并使用Web Audio API渲染音频 https://github.com/scottstensland/webgl-3d-animation