WebGL - How to pass unsigned byte vertex attribute colour values?
Solution 1
gl.vertexAttribPointer(this.material.aVertexPosition, 3, gl.FLOAT, false, 4, 0);
gl.vertexAttribPointer(this.material.aR, 1, gl.BYTE, false, 15, 12);
Your stride should be 16, not 15 and certainly not 4.
Also, each individual color does not need to be a separate attribute. The four bytes can be a vec4 input. Oh, and your colors should be normalized, unsigned bytes. That is, the values on the range [0, 255] should be scaled to [0, 1] when the shader gets them. Therefore, what you want is:
gl.vertexAttribPointer(this.material.aVertexPosition, 3, gl.FLOAT, false, 16, 0);
gl.vertexAttribPointer(this.material.color, 4, gl.UNSIGNED_BYTE, true, 16, 12);
Oh, and attributes are not materials. You shouldn't call them that.
Solution 2
GLfloat red=(GLfloat)red/255;
I hope that's what you are looking for ^^
Related videos on Youtube
Markus
Updated on June 04, 2022Comments
-
Markus almost 2 years
My vertices are made up of an array with this structure:
[ Position ][ colour ] [float][float][float][byte][byte][byte][byte]
Passing the vertex position is no problem:
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo); gl.vertexAttribPointer(this.material.aVertexPosition, 3, gl.FLOAT, false, 4, 0);
But I can't figure out how I can pass the colours to the shader. Unfortunately, it's not possible to use integers inside the glsl shader so I have to use floats. How can I get my unsigned byte colour value into the glsl float colour value? I tried it like this for r, g and b sepperately but the colours are all messed up:
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo); gl.vertexAttribPointer(this.material.aR, 1, gl.BYTE, false, 15, 12);
Vertex Shader (colouredPoint.vs)
precision highp float; attribute vec3 aVertexPosition; attribute float aR; attribute float aG; attribute float aB; uniform mat4 world; uniform mat4 view; uniform mat4 proj; varying vec3 vVertexColour; void main(void){ gl_PointSize = 4.0; gl_Position = proj * view * world * vec4(aVertexPosition, 1.0); vVertexColour = vec3(aR, aG, aB); }
Pixel Shader (colouredPoint.fs)
precision highp float; varying vec3 vVertexColour; void main(void){ gl_FragColor = vec4(vVertexColour, 1); }
-
Markus over 12 yearsThanks, but I tried that already. It just darkens the points. gebackene-ente.at/nudelsalat/sonstiges/webgl_01.png gebackene-ente.at/nudelsalat/sonstiges/webgl_02.png
-
Markus over 12 yearsThank you. I missunderstood the stride to be the gap between one set of data to the next. I tried to normalize colours before but what I was missing was the UNSIGNED_BYTE type. Material is an object that contains the shader, its attributes and some material settings so I think its just right to call it material. Works now.
-
Whiskas over 12 yearsThat's weird because I'm using this in C++ and it works pretty well, are you sure that your float have enough precision ?
-
Markus over 12 yearsSee Nicol Bolas answer for the solution. I was passing gl.BYTE instead of gl.UNISGNED_BYTE and I've got the stride wrong.