繁体   English   中英

将顶点数据打包到WebGL纹理中

[英]Packing vertex data into a WebGL texture

我试图将顶点数组存储在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的错误ArrayBufferView not big enough for request

我还将扩展名OES_texture_float用于纹理中的浮点值。

我必须承认,我不确定自己在做什么。 到处都是来回的回想,直到我不觉得这段代码有任何错误时,我还是很高兴。 我的主要思想是将每个顶点的x,y,z值存储为纹理的每个像素的r,g,b值。 因此,纹理大小必须等于或大于我的3D模型的三角形数量。 不幸的是,WebGL中的纹理大小仅限于两个数的幂。 顶点的数量也应该是可变的,因为我计划在场景中渲染多个模型。

感谢您提供有关正确使用ArrayBufferFloat32ArraytexImage2D()命令以解决将顶点发送到WebGL中的片段着色器的问题的帮助。

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

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

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

我欢迎对此解决方案发表意见或评论,随时可以通过简化代码或其他方法做出贡献。

如果您不喜欢缓冲区,则应该从Learn WebGL开始(其他所有人都在这里学习 )。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM