检索 THREE.js 中的顶点数据
Retrieve Vertices Data in THREE.js
我正在使用自定义着色器创建网格。在顶点着色器中,我正在修改几何顶点的原始位置。然后我需要从着色器外部访问这个新的顶点位置,我该如何实现?
代替变换反馈(WebGL 1.0 不支持),您将不得不使用直通片段着色器和浮点纹理(这需要加载扩展 OES_texture_float
)。这是在 WebGL 的 GPU 上生成顶点缓冲区的唯一方法。 WebGL 也不支持像素缓冲对象,因此读回输出数据的效率会非常低。
尽管如此,您可以通过以下方式完成此操作:
这将是一个粗略的概述,重点是 OpenGL,而不是任何 Three.js 具体的内容。
首先,以这种方式编码您的顶点数组(为索引添加第 4 个组件):
Vec4 pos_idx : xyz = Vertex Position, w = Vertex Index (0.0 through NumVerts-1.0)
将顶点索引存储为w
组件是必要的,因为OpenGL ES 2.0 (WebGL 1.0) 不支持gl_VertexID
.
接下来,你需要一个2D浮点纹理:
MaxTexSize = Query GL_MAX_TEXTURE_SIZE
Width = MaxTexSize;
Height = min (NumVerts / MaxTexSize, 1);
创建具有这些尺寸的 RGBA 浮点纹理并将其用作 FBO 颜色附件 0。
顶点着色器:
#version 100
attribute vec4 pos_idx;
uniform int width; // Width of floating-point texture
uniform int height; // Height of floating-point texture
varying vec4 vtx_out;
void main (void)
{
float idx = pos_idx.w;
// Position this vertex so that it occupies a unique pixel
vec2 xy_idx = vec2 (float ((int (idx) % width)) / float (width),
floor (idx / float (width)) / float (height)) * vec2 (2.0) - vec2 (1.0);
gl_Position = vec4 (xy_idx, 0.0f, 1.0f);
//
// Do all of your per-vertex calculations here, and output to vtx_out.xyz
//
// Store the index in the W component
vtx_out.w = idx;
}
直通片段着色器:
#version 100
varying vec4 vtx_out;
void main (void)
{
gl_FragData [0] = vtx_out;
}
绘图并回读:
// Draw your entire vertex array for processing (as `GL_POINTS`)
glDrawArrays (GL_POINTS, 0, NumVerts);
// Bind the FBO's color attachment 0 to `GL_TEXTURE_2D`
// Read the texture back and store its results in an array `verts`
glGetTexImage (GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, verts);
我正在使用自定义着色器创建网格。在顶点着色器中,我正在修改几何顶点的原始位置。然后我需要从着色器外部访问这个新的顶点位置,我该如何实现?
代替变换反馈(WebGL 1.0 不支持),您将不得不使用直通片段着色器和浮点纹理(这需要加载扩展 OES_texture_float
)。这是在 WebGL 的 GPU 上生成顶点缓冲区的唯一方法。 WebGL 也不支持像素缓冲对象,因此读回输出数据的效率会非常低。
尽管如此,您可以通过以下方式完成此操作:
这将是一个粗略的概述,重点是 OpenGL,而不是任何 Three.js 具体的内容。
首先,以这种方式编码您的顶点数组(为索引添加第 4 个组件):
Vec4 pos_idx : xyz = Vertex Position, w = Vertex Index (0.0 through NumVerts-1.0)
将顶点索引存储为w
组件是必要的,因为OpenGL ES 2.0 (WebGL 1.0) 不支持gl_VertexID
.
接下来,你需要一个2D浮点纹理:
MaxTexSize = Query GL_MAX_TEXTURE_SIZE
Width = MaxTexSize;
Height = min (NumVerts / MaxTexSize, 1);
创建具有这些尺寸的 RGBA 浮点纹理并将其用作 FBO 颜色附件 0。
顶点着色器:
#version 100
attribute vec4 pos_idx;
uniform int width; // Width of floating-point texture
uniform int height; // Height of floating-point texture
varying vec4 vtx_out;
void main (void)
{
float idx = pos_idx.w;
// Position this vertex so that it occupies a unique pixel
vec2 xy_idx = vec2 (float ((int (idx) % width)) / float (width),
floor (idx / float (width)) / float (height)) * vec2 (2.0) - vec2 (1.0);
gl_Position = vec4 (xy_idx, 0.0f, 1.0f);
//
// Do all of your per-vertex calculations here, and output to vtx_out.xyz
//
// Store the index in the W component
vtx_out.w = idx;
}
直通片段着色器:
#version 100
varying vec4 vtx_out;
void main (void)
{
gl_FragData [0] = vtx_out;
}
绘图并回读:
// Draw your entire vertex array for processing (as `GL_POINTS`)
glDrawArrays (GL_POINTS, 0, NumVerts);
// Bind the FBO's color attachment 0 to `GL_TEXTURE_2D`
// Read the texture back and store its results in an array `verts`
glGetTexImage (GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, verts);