1

我正在尝试完成以下任务:

  • 我有一个 NxM 点的网格(计划)
  • 我有一个纹理,每个像素代表一个位置 X,Y 的力场
  • 我想使用力场纹理(和着色器)迭代更新初始网格

我想我们可以很容易地使用“几何着色器”来做到这一点,但是这些在 WebGL 中不存在。因此,我如何使用 GLSL 驱动程序来更新网格中顶点的位置?据我了解,常规的顶点着色器确实在一次通过中将源转换为其他东西,现在有没有办法在下一次迭代期间将此输出反馈回着色器?

[编辑] 我现在可以看到的一种可能方法是使用片段着色器,然后可以将结果存储在纹理中,我可能会在下一步中重新注入。

4

1 回答 1

2

是的,使用片段着色器。将网格的状态存储在纹理中(为方便起见,浮点纹理,尽管这需要扩展),并使用片段着色器计算下一次迭代的新纹理。然后在实际绘制时,顶点着色器读取纹理以确定要显示的顶点坐标。

我已经使用这种技术实现了一个粒子系统。这是进行状态更新的片段着色器,因此您可以了解它是如何工作的。对于每个粒子,一对相邻的纹素(提供 8 个浮点数)存储它的位置和速度。

#ifdef GL_ES
precision highp float;
#endif

uniform sampler2D uState;
uniform float uResolution;
uniform float uDT;
uniform float uHarmonicAccel;

vec4 lookup(float offset) {
  return texture2D(uState, (gl_FragCoord.xy + vec2(offset, 0.0)) / uResolution);
}

void main(void) {
  bool updatingPosition = mod(gl_FragCoord.x, 2.0) < 1.0;
  vec4 posp, velp;
  if (updatingPosition) {
    posp = lookup(0.0);
    velp = lookup(1.0);
  } else {
    posp = lookup(-1.0);
    velp = lookup(0.0);
  }
  vec3 pos = vec3(posp);
  vec3 vel = vec3(velp);

  // velocity update is applied to position as well
  vel += uHarmonicAccel * uDT * normalize(pos);

  if (updatingPosition) {
    gl_FragColor = vec4(pos + uDT * vel, posp[3]);
  } else {
    gl_FragColor = vec4(vel, velp[3]);
  }
}
于 2013-02-26T16:30:11.847 回答