将顶点数据打包成 WebGL 纹理

Fep*_*ter 5 javascript shader textures glsl 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);
Run Code Online (Sandbox Code Playgroud)

纹理宽度和高度为 2 时没有错误。取更高的值会导致错误ArrayBufferView not big enough for request

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

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

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

Fep*_*ter 2

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

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

var vMapTexture = gl.createTexture();
var vertexTextureWidth = Math.ceil(Math.sqrt(verticeCount/3));
Run Code Online (Sandbox Code Playgroud)

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

接下来,我们创建一个 Float32Array

var a = new Float32Array(vertexTextureWidth * vertexTextureWidth * 3);
Run Code Online (Sandbox Code Playgroud)

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

for(var i = 0; i < (verticeCount); i++){
a[i] = Model.VerticeMap[i];
}
Run Code Online (Sandbox Code Playgroud)

现在将纹理设置为活动状态并绑定它:

gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, vMapTexture);
gl.uniform1i(gl.getUniformLocation(this.program, "uVertexTexture"), 1);
Run Code Online (Sandbox Code Playgroud)

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

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, vertexTextureWidth, vertexTextureWidth, 0, gl.RGB, gl.FLOAT, a);
Run Code Online (Sandbox Code Playgroud)

我使用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);
Run Code Online (Sandbox Code Playgroud)

生成的纹理现在包含我的顶点数组,如下所示

RGB 顶点纹理

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