【问题标题】:Texture driven particles in WebGL / OpenGL using a shaderWebGL / OpenGL 中使用着色器的纹理驱动粒子
【发布时间】:2013-02-27 04:36:03
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: opengl-es webgl shader vertex-shader


    【解决方案1】:

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

    我有implemented a particle system using this technique。这是进行状态更新的片段着色器,因此您可以了解它是如何工作的。对于每个粒子,一对相邻的纹素(提供 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]);
      }
    }
    

    【讨论】:

    • 使用 N x 2 x Vec4 维度的纹理甚至比 2 个相邻的纹素更容易处理。顺便说一句,好把戏:-)
    • @FlavienVolken 对于使用一维非常大的纹理要谨慎。我的印象是有时可能不受支持。
    猜你喜欢
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    相关资源
    最近更新 更多