2014-09-20 4 views
2

openFrameworks에서 만든 코드를 THREE.JS에 이식하려고합니다. 이 코드는 perlin 노이즈를 사용하여 풍경을 생성합니다. 먼저 정적 인덱스 배열을 생성 한 다음 정점의 위치를 ​​정해진 그리드에 배치하고 각 그리드는 지정된 거리만큼 이동되었습니다. 이는 배열 내의 정점 위치를 위, 아래, 왼쪽 또는 오른쪽으로 이동하여 카메라가 움직이면 풍경을 업데이트하고 카메라 이동 방향에 따라 새로운 풍경을 생성 할 수 있도록하기위한 것입니다.BufferGeometry 인덱스 문제

각 정점에 대해 인덱스 배열에 인접한 두 개의 삼각형을 나타내는 6 개의 인덱스가 추가됩니다. 각 삼각형에 대해 각 꼭지점의 중복을 저장하는 메모리를 낭비하고 싶지 않았습니다.

예를 들면.

v12 v11 v10 
*----*----* 
|\ |\ | 
| \ | \ | 
| \ | \ | 
| \| \| 
*----*----* 
v02 v01 v00 

등. 버텍스 v00에서 인덱스 {v00, v10, v11}과 {v00, v11, v01}이 추가되었습니다.

내 openFrameworks 코드에서이 모든 것이 완벽하게 작동합니다! 많은 문제가 발생한 후에 마침내 THREE.js에서 작동하는 것들을 얻었지만, 정점의 양을 늘리 자마자 모든 것이 이상하게 변하기 시작한다는 것을 알았습니다. 삼각형이 온통 연결되어있는 것 같고 큰 덩어리입니다. 정점의 시작은 건너 뛰기 시작합니다. 256 * 256의 격자 크기를 포함하여 현재까지는 아무 문제가 없지만 모든 높이를 증가 시키 자마자 모든 인공물을 보게됩니다.

아마 이것이 오프셋 (offsetting)과 관련된 문제라고 생각하지만, 이것이 의미하는 것이 무엇인지, 또는 내 코드로 구현하는 방법을 이해하지 못합니다. 나는 다른 사람들이 인덱스 (0, 1, 2, 3, ...)로 인덱스를 정의하고 각 삼각형에 3 개의 개별 꼭지점을 사용하고 (순서대로 각 삼각형에 각 꼭지점을 추가 할 때) 성공적으로 사용하는 것을 보았다. . 나는 똑같은 일을하는 것처럼 보일 수 없다.

아이디어가 있으십니까? 내가 도움이 될 경우에 대비하여 아래 코드가 있습니다. 내가 그 부분을 주석 처리 한 부분을 볼 수 있습니다.

VAR 풍경 = { 크기 : 0, chunksize 영역 : 21845, 거리 : 0, 구조 : 널 (null), 메쉬 : 널 (null), 위치 : 널 (null), 법선 : 널 (null), 색상 : 널 (null), 인덱스 : 널 (null),

generateVertex: function(r, c) 
{ 
    var pos, color; 

    // Set position 
    pos = new THREE.Vector3(); 
    pos.x = this.distance * c; 
    pos.z = this.distance * r; 
    pos.y = -2 + 5*simplex.noise2D(0.1*pos.x, 0.1*pos.z); 

    // Set color 
    color = new THREE.Color(); 
    color.setRGB(Math.random(1), 0, 0); 

    this.vertices.setXYZ(r * this.size + c, pos.x, pos.y, pos.z); 
    this.colors.setXYZ(r * this.size + c, color.r, color.g, color.b); 
}, 

generateIndices: function(i, r, c) 
{ 
    this.indices[ i ] = (r * this.size) + c; 
    this.indices[ i + 1 ] = ((r + 1) * this.size) + c; 
    this.indices[ i + 2 ] = ((r + 1) * this.size) + (c + 1); 

    this.indices[ i + 3 ] = (r * this.size) + c; 
    this.indices[ i + 4 ] = ((r + 1) * this.size) + (c + 1); 
    this.indices[ i + 5 ] = (r * this.size) + (c + 1); 

    /*this.indices[ i ] = ((r * this.size) + c) % (3 * this.chunkSize); 
    this.indices[ i + 1 ] = (((r + 1) * this.size) + c) % (3 * this.chunkSize); 
    this.indices[ i + 2 ] = (((r + 1) * this.size) + (c + 1)) % (3 * this.chunkSize); 

    this.indices[ i + 3 ] = ((r * this.size) + c) % (3 * this.chunkSize); 
    this.indices[ i + 4 ] = (((r + 1) * this.size) + (c + 1)) % (3 * this.chunkSize); 
    this.indices[ i + 5 ] = ((r * this.size) + (c + 1)) % (3 * this.chunkSize); */ 
}, 

generatePoint: function(x, z) 
{ 

}, 

generate: function(size, distance) 
{   
    var sizeSquared, i; 
    sizeSquared = size * size; 
    i = 0; 
    this.size = size; 
    this.distance = distance; 

    // Create buffer geometry 
    this.geometry = new THREE.BufferGeometry(); 

    this.indices = new Uint16Array(6*(size-1)*(size-1)); 

    this.vertices = new THREE.BufferAttribute(new Float32Array(sizeSquared * 3), 3); 
    this.colors = new THREE.BufferAttribute(new Float32Array(sizeSquared * 3), 3); 

    // Generate points 
    for(var r = 0; r < size; r = r + 1) 
    { 
     for(var c = 0; c < size; c = c + 1) 
     { 
      this.generateVertex(r, c); 

      if((r < size - 1) && (c < size - 1)) 
      { 
       this.generateIndices(i, r, c); 
       i = i + 6; 
      } 
     } 
    } 

    // Set geometry 
    this.geometry.addAttribute('index', new THREE.BufferAttribute(this.indices, 1)); 
    this.geometry.addAttribute('position', this.vertices); 
    this.geometry.addAttribute('color', this.colors);   

    // 
    /*this.geometry.offsets = []; 

    var triangles = 2 * (size - 1) * (size - 1); 
    var offsets = triangles/this.chunkSize; 

    for(var j = 0; j < offsets; j = j + 1) 
    { 
     var offset = 
     { 
      start: j * this.chunkSize * 3, 
      index: j * this.chunkSize * 3, 
      count: Math.min(triangles - (j * this.chunkSize), this.chunkSize) * 3 
     }; 

     this.geometry.offsets.push(offset); 
    }*/ 

    var material = new THREE.MeshBasicMaterial({vertexColors: THREE.VertexColors}); 
    //var material = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors }); 

    this.geometry.computeBoundingSphere(); 

    this.mesh = new THREE.Mesh(this.geometry, material); 
    scene.add(this.mesh); 

} 

답변

3

에서 WebGL은 OpenGL을 ES 2.0을 기반으로 않도록 즉시 256 개 * 256 정점을 가지고, 32 비트 인덱스 버퍼를 지원하지 않습니다, 인덱스 버퍼는 더 이상 그들 모두를 해결할 수 있습니다. OpenGL ES 2.0 Standard (2.8 정점 어레이) 발

: ubyte 및 USHORT 인덱스와

인덱싱 지원지지된다. uint 색인의 경우 지원은 OpenGL ES 2.0에서 필요하지 않습니다. 구현이 uint 인덱스를 지원하는 경우 OES 요소 index - uint 확장을 내 보냅니다.

OES_element_index_uint extension을 가져와 확인하여 32 비트 인덱스 버퍼를 사용하도록 설정할 수 있다고 가정합니다.

var uintExt = gl.getExtension("OES_element_index_uint"); 
if (!uintExt) { 
    alert("Sorry, this app needs 32bit indices and your device or browser doesn't appear to support them"); 
    return; 
} 

webglstats.com에 따르면 기계의 93.5 %가 확장을 지원합니다.


당신은 32 비트 배열을 만들려면 generate 기능을 변경해야합니다

:

this.indices = new Uint32Array(6*(size-1)*(size-1)); 

내가 source of three.js's renderer 내부 빠른 탐구가 있고, 그것을 :

this.indices = new Uint16Array(6*(size-1)*(size-1)); 

이 있어야한다 Uint32Array을 사용하면 인덱스 배열의 유형을 검사하는 것처럼 보이고 gl.UNSIGNED_INTglDrawElements으로 전달합니다.

+0

설명해 주셔서 감사합니다. 그래, 이상한 일이 256 * 256 정점 후에 일어난 것처럼 보입니다. 나는 약간의 코드를 시도했지만 다른 변경을하지 않으면 작동하지 않는 것 같습니다. 다른 곳에서 뭔가 잘못된 것이 있는지는 잘 모르겠지만 사람들이이 문제를 해결하기 위해 오프셋을 보았습니다. 저의 특정 설정에 대해서는 작동하지 않는 것 같습니다. 이유는 확실하지 않습니다. – jacknkandy

+0

'drawElements' 호출은 어떻게 생겼습니까? 32 비트 인덱스를 사용하려면 세 번째 매개 변수로'gl.UNSIGNED_INT'와 같은 것을 전달해야하지만, WebGL에 있다고 생각하지 않습니다. (실제로는 사용하지 않습니다.) – GuyRT

+0

@gman 실제로 사용 가능한지 알고 계십니까? http://msdn.microsoft.com/en-us/library/ie/dn302396(v=vs.85).aspx에 따르면, type 매개 변수는'gl.UNSIGNED_SHORT'이어야합니다. 나는 당신이 당신 자신의 상수를 전달함으로써 그것을 교묘히 빠져 나올 수 있다고 생각합니다. 내 플랫폼에서는 0x1405 (십진수로 5125)로 정의됩니다. 그것이 어디서나 동일하게 정의되어 있는지 확실하지 않습니다. – GuyRT