WebGL: vertex buffer with more than 4-dimensional coordinates?

Now I have three separate vertex buffers: 1. XYZ buffer 2. NX, NY, NZ buffer 3. UV buffer

So these are just 8 floats. In the future, tangential and binagent information will also be added, so +6 floats.

This is how I declare them for shaders:

shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal"); gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute); shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); 

Here I pass them to the shader program:

 gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexCoordBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexNormalBuffer); gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexTextureCoordBuffer); gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); 

Since the buffers are separated, I can define them as vec3 and vec2 in the shader:

 attribute vec3 aVertexPosition; attribute vec3 aVertexNormal; attribute vec2 aTextureCoord; 

But what if I combine them into one buffer with 8 floats on top? Thus, the size of the element will be 8:

 gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexCoordBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 8, gl.FLOAT, false, 0, 0); 

But how do I access them in the shader? vec8 ? There is a maximum of vec4! So how am I?

+4
source share
2 answers

You can create one buffer that contains all the attributes for each vertex using the step and offset parameters (which are currently set to 0) to determine the rotation of the attributes. In fact, I heard you should do this to improve the locality of memory access to the top.

A step is the total number of bytes per vertex (rather, the distance between occurrences of the same attribute), and the offset is the byte index, where is the first occurrence of a particular attribute. So, to take your example attributes and read them from one buffer:

 gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexAttrBuffer); var step = Float32Array.BYTES_PER_ELEMENT; var total = 3 + 3 + 2; var stride = step * total; gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 3, gl.FLOAT, stride, 0); gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, 3, gl.FLOAT, false, stride, step * 3); gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, stride, step * 6); 

The buffer will be loaded from Float32Array , whose elements go

 [px1, py1, pz1, nx1, ny1, nz1, u1, v1, px2, py2, pz2, nx2, ny2, nz2, u2, v2, ...] 
+5
source

Maximum vec4, you're right and only way for webGL. You can try passing arrays as an attribute: GLSL for each fixed array size , but OpenGL ES 2.0 does not support it, so this option is only available on the OpenGL desktop. But I don’t see the real need to do this, so with vec4 you will be fine no matter what you do, and passing the attribute of arrays is something you probably shouldn't do.

Hope this helps.

0
source

Source: https://habr.com/ru/post/1484092/


All Articles