2011-08-26 6 views
16

Moi wierzchołki są wykonane z tablicą z tej struktury:WebGL - Jak przekazywać niepodpisane wartości kolorów atrybutu vertex bajtów?

[  Position  ][  colour  ] 
[float][float][float][byte][byte][byte][byte] 

minięciu pozycję wierzchołków ma problemu:

gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo); 
gl.vertexAttribPointer(this.material.aVertexPosition, 3, gl.FLOAT, false, 4, 0); 

Ale nie mogę dowiedzieć się, jak mogę przejść kolorów cieniowanie. Niestety, nie można używać liczb całkowitych w module cieniującym glsl, więc muszę używać pływaków. Jak mogę uzyskać wartość koloru niepodpisanego bajtu w wartości koloru ruchomego glsl? Próbowałem to tak dla R, G i B sepperately ale wszystkie kolory są pomieszane:

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); 
} 
+0

Pomijając twój problem, pomyślałeś o zaliczeniu attribu jako wektora 3-elementowego? Oszczędza to kod i czas. – Nobody

+0

@Nobody To, co pierwotnie zrobiłem. Przełączyłem się tylko na przekazywanie ich osobno, aby upewnić się, że tablica nie stanowiła problemu. – Markus

Odpowiedz

27
gl.vertexAttribPointer(this.material.aVertexPosition, 3, gl.FLOAT, false, 4, 0); 
gl.vertexAttribPointer(this.material.aR, 1, gl.BYTE, false, 15, 12); 

Twój krok powinien być 16, a nie 15 i pewno nie 4.

Ponadto, każdy indywidualny kolor nie musi być oddzielny atrybut. Cztery bajty mogą być wejściami vec4. Aha, i twoje kolory powinny być znormalizowane, unsigned bytes. Oznacza to, że wartości w zakresie [0, 255] powinny zostać przeskalowane do [0, 1], gdy moduł cieniowania je pobierze. Dlatego to, co chcesz:

gl.vertexAttribPointer(this.material.aVertexPosition, 3, gl.FLOAT, false, 16, 0); 
gl.vertexAttribPointer(this.material.color, 4, gl.UNSIGNED_BYTE, true, 16, 12); 

Aha, i atrybuty są nie materiały. Nie powinieneś ich tak nazywać.

+0

Dziękuję. Nie zdałem sobie sprawy z tego, że jest to luka między jednym zestawem danych a drugim. Próbowałem wcześniej normalizować kolory, ale tym, czego mi brakowało, był typ UNSIGNED_BYTE. Materiał jest obiektem zawierającym moduł cieniujący, jego atrybuty i niektóre ustawienia materiałów, więc uważam, że jest to prawo do nazwania go materiałem. Działa teraz. – Markus

1
GLfloat red=(GLfloat)red/255; 

mam nadzieję, że to co szukasz ^^

+0

Dzięki, ale już próbowałem. Po prostu przyciemnia punkty. http://gebackene-ente.at/nudelsalat/sonstiges/webgl_01.png http://gebackene-ente.at/nudelsalat/sonstiges/webgl_02.png – Markus

+0

To dziwne, ponieważ używam tego w C++ i działa całkiem nieźle, czy jesteś pewien, że twój float ma wystarczającą precyzję? – Whiskas

+1

Zobacz odpowiedź Nicola Bolasa na rozwiązanie. Mijałem gl.BYTE zamiast gl.UNISGNED_BYTE i mam zły krok. – Markus