2013-07-01 38 views
5

Tôi đang sử dụng BufferGeometry để vẽ hàng ngàn hình khối tạo nên địa hình, nhưng gặp khó khăn trong việc tìm hiểu cách cập nhật hình học nếu tôi cần thay đổi vị trí của một trong các hình khối. Ví dụ, tôi có mã này để khởi tạo hình học của tôi: (Tôi đang làm thử nghiệm của tôi trên một phiên bản cập nhật của this example)Làm thế nào để cập nhật nhanh một BufferGeometry lớn?

// 12 triangles per cube (6 quads) 
var triangles = 12 * 150000; 

var geometry = new THREE.BufferGeometry(); 
geometry.attributes = { 

    position: { 
     itemSize: 3, 
     array: new Float32Array(triangles * 3 * 3), 
     numItems: triangles * 3 * 3 
    }, 

    normal: { 
     itemSize: 3, 
     array: new Float32Array(triangles * 3 * 3), 
     numItems: triangles * 3 * 3 
    }, 

    color: { 
     itemSize: 3, 
     array: new Float32Array(triangles * 3 * 3), 
     numItems: triangles * 3 * 3 
    } 
} 

positions = geometry.attributes.position.array; 
normals = geometry.attributes.normal.array; 
colors = geometry.attributes.color.array; 

Nếu tôi di chuyển một khối lập phương, nó sẽ không xuất hiện để được di chuyển cho đến khi tôi làm :

geometry.attributes.position.needsUpdate = true; 

Điều này làm cho FPS bị giảm khi được cập nhật. Có cách nào khác tôi có thể làm điều này không? Có vẻ hơi không cần thiết khi tôi chỉ thay đổi một khối lập phương (12 hình tam giác/36 đỉnh). Mặc dù nó có thể là - tôi đã không kiểm tra những gì needsUpdate thực sự không. Đoán nó sẽ gửi mảng đến shader một lần nữa.

Tôi đã nghĩ rằng tôi có thể chia hình học thành các BufferGeometries nhỏ hơn riêng biệt nhưng tôi không chắc chắn liệu điều đó có thể giúp hiệu suất tổng thể hay không. Từ những gì tôi hiểu, hình học hơn = FPS ít hơn.

Nếu có ai có ý tưởng làm thế nào tôi sẽ làm điều này, nó sẽ được đánh giá cao! :) Bên cạnh vấn đề cập nhật, BufferGeometry dường như chính xác những gì tôi cần. Cảm ơn!

Trả lời

7

Tôi đã có cùng một vấn đề với một BufferGeometry rất lớn khi cập nhật một vài đỉnh trong đó.

Giải pháp là sử dụng _gl.bufferSubData thay vì _gl.bufferData để cập nhật chỉ là một phần của bộ đệm. (Ba js chỉ sử dụng _gl.bufferData).

Vì vậy, nếu bạn cập nhật các vị trí bạn sẽ làm gì:

// Tạo một cái nhìn của các dữ liệu cập nhật từ chỉ số offsetSub để offsetSubEnd

var view = geometry.attributes.position.array.subarray(offsetSub, offsetSubEnd);

// Bind bộ đệm cho các vị trí (lấy bối cảnh gl với webglrenderer)

_gl.bindBuffer(_gl.ARRAY_BUFFER, geometry.attributes.position.buffer);

// Chèn mới giá trị tại chỉ số tốt trong bộ đệm gpu (offsetGeometry là trong byte)

_gl.bufferSubData(_gl.ARRAY_BUFFER, offsetGeometry,view);

Lưu ý rằng giải pháp này có thể chậm hơn nếu bạn thay đổi một phần lớn của các đỉnh đệm so với _gl.bufferData.

6

Kể từ r71 baj hỗ trợ bufferSubData.

Sử dụng một DynamicBufferAttribute, (hoặc chỉ cần thiết lập một cách chính xác updateRange)

var positionAttr = geometry.attributes.position 
// if not using DynamicBufferAttribute initialize updateRange: 
// positionAttr.updateRange = {}; 
positionAttr.updateRange.offset = 0; // where to start updating 
positionAttr.updateRange.count = 1; // how many vertices to update 
positionAttr.needsUpdate = true; 
+2

Không chắc chắn phiên bản nó đã được thay đổi, nhưng là của 'r81' này đã được sáp nhập vào [' BufferAttribute'] (https: // github.com/mrdoob/three.js/blob/r81/src/core/BufferAttribute.js#L27). – Jay

Các vấn đề liên quan