2013-06-23 38 views
3

我想在WebGL纹理中存储顶点数组,但无法真正弄清楚如何正确地执行它。 这样做的目的是将顶点传递给我的片段着色器并处理它们以进行光线跟踪。目前将顶点数据打包到WebGL纹理中

我的JavaScript代码如下所示:

var a = new ArrayBuffer(); 
// Model.VerticeMap is an array holding all vertices [x1, y1, z1, x2, y2, z2, ...] 
a = Model.VerticeMap; // array length: 36864 
var dataArray = new Float32Array(a); 
var vMapTexture = gl.createTexture(); 
gl.bindTexture(gl.TEXTURE_2D, vMapTexture); 
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 2, 2, 0, gl.RGB, gl.FLOAT, dataArray); 

我与纹理的宽度和高度2.以较高的值会导致错误ArrayBufferView not big enough for request没有错误。

我也使用扩展OES_texture_float作为纹理中的浮点值。

我必须承认,我不是100%确定我在那里做什么。这是更多的来回,我很高兴,当我的代码没有得到任何错误的时候。我的主要想法是将每个顶点的x,y,z值存储为纹理中每个像素的r,g,b值。因此,纹理尺寸必须与我的3D模型的三角形数量相等或更高。不幸的是,WebGL中的纹理大小限于两个数字的幂。顶点的数量也应该是可变的,因为我打算在场景中渲染多个模型。

对于正确使用ArrayBufferFloat32ArraytexImage2D()命令来解决我在WebGL中发送顶点到片段着色器的问题,我将不胜感激。

回答

1

我想我找到了我的问题的解决方案:

首先,我们需要计算出一个合适的纹理宽度

var vMapTexture = gl.createTexture(); 
var vertexTextureWidth = Math.ceil(Math.sqrt(verticeCount/3)); 

随着verticeCount是我们的顶点数组的长度,我们3分才将其放入像素的RGB分量中,取其平方根并将其四舍五入,以确保所有顶点都适合于纹理。纹理宽度也等于纹理高度。

接下来,我们创建了一个Float32Array

var a = new Float32Array(vertexTextureWidth * vertexTextureWidth * 3); 

我用值填充它从我的顶点数组

for(var i = 0; i < (verticeCount); i++){ 
a[i] = Model.VerticeMap[i]; 
} 

现在设置你的纹理被激活,并将其绑定:

gl.activeTexture(gl.TEXTURE1); 
gl.bindTexture(gl.TEXTURE_2D, vMapTexture); 
gl.uniform1i(gl.getUniformLocation(this.program, "uVertexTexture"), 1); 

要将数据打包到纹理中,我使用以下行

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, vertexTextureWidth, vertexTextureWidth, 0, gl.RGB, gl.FLOAT, a); 

我使用RGB格式和FLOAT类型。为此,您必须启用OES_texture_float扩展。

最后,添加以下纹理参数:

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 

产生的纹理现在包含我的顶点数组,看起来像这样

RGB Vertex Texture

我公开征求意见或言论此解决方案,随时提供代码简化或其他方法。

-2

如果你不喜欢缓冲区,那么你应该从Learning WebGL(其他人都这样做)开始。

贴图存储顶点数据是一个坏主意,因为每个颜色值只存储一个字节,并且您至少需要一些float32作为顶点。无论如何,你的尝试都是为了着色器属性和点绘图。