在THREE.js中检索顶点数据

Mic*_*use 7 shader textures webgl vertex-shader three.js

我正在使用自定义着色器创建网格.在顶点着色器中,我正在修改几何顶点的原始位置.然后我需要从着色器外部访问这个新的顶点位置,我该如何实现呢?

And*_*man 8

代替转换反馈(WebGL 1.0不支持),您将不得不使用直通片段着色器和浮点纹理(这需要加载扩展OES_texture_float).这是在WebGL中在GPU上生成顶点缓冲区的唯一方法.WebGL也不支持像素缓冲对象,因此回读输出数据效率非常低.

不过,这是你如何做到这一点:

这将是一个关注OpenGL的粗略概述,而不是具体的Three.js.

首先,以这种方式编码顶点数组(为索引添加第四个组件):

Vec4 pos_idx  :  xyz = Vertex Position,  w = Vertex Index (0.0 through NumVerts-1.0)
Run Code Online (Sandbox Code Playgroud)

将顶点索引存储为w组件是必要的,因为OpenGL ES 2.0(WebGL 1.0)不支持gl_VertexID.

接下来,您需要一个2D浮点纹理:

MaxTexSize = Query GL_MAX_TEXTURE_SIZE

Width  = MaxTexSize;
Height = min (NumVerts / MaxTexSize, 1);
Run Code Online (Sandbox Code Playgroud)

使用这些尺寸创建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;
}
Run Code Online (Sandbox Code Playgroud)

Passthrough片段着色器:

#version 100

varying vec4 vtx_out;

void main (void)
{
  gl_FragData [0] = vtx_out;
}
Run Code Online (Sandbox Code Playgroud)

绘制和回读:

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