5

我正在尝试将顶点数组存储在 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 中的纹理大小仅限于两个数字的幂。顶点的数量也应该是可变的,因为我打算在我的场景中渲染多个模型。

我将不胜感激有关正确使用ArrayBufferaFloat32ArraytexImage2D()命令的一些帮助,以解决我在 WebGL 中将顶点发送到片段着色器的问题。

4

2 回答 2

2

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

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

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 顶点纹理

我愿意对此解决方案发表评论或评论,随时为代码简化或其他方法做出贡献。

于 2013-07-04T09:23:14.220 回答
-3

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

纹理存储顶点数据是一个坏主意,因为每个颜色值只存储一个字节,并且您肯定希望顶点至少有一些 float32。无论如何,您的尝试都适用于着色器属性和点图。

于 2013-07-03T23:09:20.737 回答