我需要座標軸對齊法線,所以我想要安全的內存併發送它作爲字節而不是alpha通道的位置。緩衝區對象由4個字節組成:glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 4 * sizeof(GLubyte), (void*)0);
編碼應該像這樣。如何將字節解壓到vec3中?
//byte in buffer object | unpacked vector
x+ 0010 1011 == vec3(1, 0, 0)
x- 0010 1001 == vec3(-1, 0, 0)
y+ 0010 1110
y- 0010 0110
z+ 0011 1010
z- 0001 1010
//Lets take vec3(-1, 0, 1) encoded velue looks like 0011 1001
// ,(operation) -> (result),
//Z = >>4 -> 0000 0011, &mask -> 0000 0011, -2 -> 0000 0001
//Y = >>2 -> 0000 1110, &mask -> 0000 0010, -2 -> 0000 0000
//X = >>0 -> 0011 1001, &mask -> 0000 0001, -2 -> 1111 1111
我檢查了gDEBuggerGL中的編碼,它是正確的。問題出現在頂點着色器中,因爲拆箱非常笨拙。
layout(location = 0) in vec4 vertex_position;
//...
int byte = int(vertex_position.w);
const int mask = 0x00000003;
vec3 v_normal;
v_normal.x = float(((byte >> 0) & mask) - 2);
v_normal.y = float(((byte >> 2) & mask) - 2);
v_normal.z = float(((byte >> 4) & mask) - 2);
首先:有沒有更好的辦法如何做到這一點?
其次:我把這個法線向量渲染成浮動紋理,發現有些值是錯誤的。他們中的許多人不是{1,0,-1}但接近此。那麼我不認爲這段代碼應該引入任何精度錯誤,那麼爲什麼會發生這種情況呢?
更新: 精度誤差在過渡引入從頂點着色器到片段着色器和可通過添加flat
關鍵字來解決。 (感謝多德)
'8 * sizeof(GLubyte)'看起來有點嫌疑? – 2015-02-08 23:31:43
對不起,我應該改變它。有兩個4 *字節的緩衝區。但另一個不涉及這個問題。 – Keo 2015-02-08 23:34:29
你知道在頂點着色器和片段着色器之間,你的'v_normal'將被插值,除非你採取其他的步驟...... – 2015-02-09 05:13:23