2011年10月10日 星期一

[WebGL] Pass an array into fragment shader

At this moment (10/10/2011) is impossible!!

I wanna do multiple light sources so I have to pass a series of locations. The only way to do it now is to use texture. At this moment, webGL does support floating-point texture but my graphics card however doesn't. Here is the link to see if your card supports it (www.kludx.com/opengl_versions.php)

Here is the code to move your data into the texture:

var pix = [];
for from i=0 to n
{
for from j=0 to n
{
var x=...
var y=...
var z=...
pix.push(x,y,z);
}
}

Where n is the size of your array. I've searched on the internet, saying that using 2D array is better than 1D either performance is better or some of the hardware doesn't support 1D texture. So if you want a 1D array just use nx1 2D texture.

Here is the code you set up the texture:

texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_ALIGNMENT,1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.FLOAT, new Float32Array(pix));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);

However, if your card doesn't support floating-point texture (like mine,) you have to use fixed point texture.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.UNSIGNED_BYTE, newUint8Array(pix));

And then you can set up the shader parameters and access the texture like the normal image textures.

[Ignore this part if you can use floating-point texture]
If you only can use fixed point texture. The input value will be automatically scaled from [0,255] to [0,1]. So you will lose some precision and also you will have a fixed range of data. If you want to have data in [-100,100], All you have to do is to scale to [0,255], get [0,1] in the shader and then scale back to [-100,100]

沒有留言:

張貼留言