gpt4 book ai didi

javascript - BufferGeometry 索引问题

转载 作者:行者123 更新时间:2023-11-29 19:34:10 26 4
gpt4 key购买 nike

我正在尝试将我在 openFrameworks 中编写的一些代码移植到 THREE.JS 中。该代码使用 perlin 噪声生成景观。我这样做是为了首先创建一个静态索引数组,然后将顶点的位置放置在一个正方形网格中,每个顶点都按指定的距离移动。这样阵列中顶点的位置可以移动(上、下、左或右),这样当相机移动时,可以更新风景,并根据相机移动的方向生成新的风景带。

对于每个顶点,索引数组中添加了 6 个索引,这些索引指向两个相邻的三 Angular 形。我不想浪费内存来存储每个三 Angular 形的每个顶点的副本。

例如例如

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

例如在顶点 v00 处,添加索引 {v00, v10, v11} 和 {v00, v11, v01} 等。

在我的 openFrameworks 代码中,这一切都完美无缺!在经历了很多麻烦之后,我终于在 THREE.js 中开始工作了,但是我注意到,一旦我增加了顶点的数量,一切就开始变得奇怪了——三 Angular 形连接(看起来)到处都是,而且有一大块的顶点开始被跳过。目前,任何高达 256*256 的网格大小(包括 256*256)都可以正常工作,但一旦我增加任何更高的尺寸,我就会开始看到所有的人工制品。

我认为这可能是偏移的问题,但我真的不明白这意味着什么,或者如何用我的代码实现它。我已经看到其他人在按顺序 (0, 1, 2, 3, ... ) 定义索引时成功使用它,而是为每个三 Angular 形使用 3 个单独的顶点(并按顺序为每个三 Angular 形添加三个顶点) .我似乎无法让同样的东西工作。

有什么想法吗?我在下面有我的代码以防万一。你可以看到我注释掉偏移的部分。

变种风景={ 尺寸:0, block 大小:21845, 距离:0, 几何:空, 网格:空, 职位:空, 法线:空, 颜色:空, 索引:空,

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 );

}

最佳答案

WebGL 基于不支持 32 位索引缓冲区的 OpenGL ES 2.0,因此一旦您拥有超过 256 * 256 个顶点,索引缓冲区就无法再对它们进行寻址。

来自OpenGL ES 2.0 Standard (第 2.8 节顶点数组):

Indexing support with ubyte and ushort indices is supported. Support for uint indices is not required by OpenGL ES 2.0. If an implementation supports uint indices, it will export the OES element index - uint extension.

假设这是问题所在,您可以通过获取并检查 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% 的机器支持扩展。


您需要更改您的generate 函数来创建一个 32 位数组:

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

应该是:

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

我快速深入研究了 source of three.js's renderer ,看起来它会检查索引数组的类型,如果您使用 Uint32Array,它会将 gl.UNSIGNED_INT 传递给 glDrawElements

关于javascript - BufferGeometry 索引问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25947436/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com