2016-03-31 37 views
2

我需要從我的着色器訪問緩衝區。緩衝區是從數組創建的。 (在真實的情景,陣中擁有10K +(變量)的數字。)WebGL:來自着色器的訪問緩衝區

var myBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER, myBuffer); 
gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([1,2,3,4,5,6,7]), gl.STATIC_DRAW); 

如何發送它,所以它的使用着色器?

precision mediump float; 
uniform uint[] myBuffer;//??? 

void main() { 
    gl_FragColor = vec4(myBuffer[0],myBuffer[1],0,1); 
} 

通常情況下,如果它是一個屬性,它會是

gl.vertexAttribPointer(myBuffer, 2, gl.UNSIGNED_BYTE, false, 4, 0);

,但我需要能夠從任何着色器像素訪問整個陣列,所以它不是一個頂點屬性。

+2

您是否嘗試將數組加載到紋理?使用Sampler2D對象我希望你可以訪問整個數組.. – Raki

+0

這是你應該這樣做的方式嗎?我認爲Sampler2D是用於隨機自定義二進制數據的圖像和緩衝區。 – RainingChain

+0

如何從數組中創建Sampler2D對象? – RainingChain

回答

4

如果要隨機訪問着色器中的大量數據,請使用紋理。

如果您有10000個值,則可以製作100x100像素的紋理。那麼你就可以得到紋理的每個值的東西,如

uniform sampler2D u_texture; 

vec2 textureSize = vec2(100.0, 100.0); 

vec4 getValueFromTexture(float index) { 
    float column = mod(index, textureSize.x); 
    float row = floor(index/textureSize.x); 
    vec2 uv = vec2(
     (column + 0.5)/textureSize.x, 
     (row + 0.5)/textureSize.y); 
    return texture2D(u_texture, uv); 
} 

確保您的紋理過濾設置爲gl.NEAREST

當然,如果你製作textureSize制服,你可以傳遞紋理的大小。

至於爲什麼+ 0.5部分see this answer

您可以正常使用gl.RGBAgl.UNSIGNED_BYTE紋理和添加/乘通道來獲得大範圍的值。或者,如果你不想搞砸,你可以使用浮點紋理。 You need to enable floating point textures