1

私は次のタスクを達成しようとしています:

  • NxM ポイントのグリッド (計画) があります
  • 各ピクセルが位置 X、Y の力場を表すテクスチャがあります。
  • 力場テクスチャ (およびシェーダー) を使用して、初期グリッドを繰り返し更新したいと考えています。

「ジオメトリ シェーダー」を使用してこれを簡単に行うことができると思いますが、それらは WebGL には存在しません。したがって、グリッド内の頂点の位置を更新するために GLSL 駆動プログラムを使用するにはどうすればよいですか? 私が理解しているように、通常の頂点シェーダーは 1 つのパスでソースを別のものに変換しますが、次の反復中にシェーダーでこの出力をフィードバックする方法はありますか?

[編集] 現時点で考えられる方法は、フラグメント シェーダーを使用して、結果をテクスチャに格納し、次のステップで再注入することです。

4

1 に答える 1

2

はい、フラグメント シェーダーを使用します。グリッドの状態をテクスチャ (拡張が必要ですが、最も便利なように浮動小数点テクスチャ) に保存し、フラグメント シェーダを使用して次の反復である新しいテクスチャを計算します。次に、実際に描画するときに、頂点シェーダーがテクスチャを読み取り、表示する頂点座標を決定します。

この手法を使用してパーティクル システムを実装しました。これは、状態の更新を行うフラグメント シェーダーです。その仕組みを理解することができます。パーティクルごとに、隣接するテクセルのペア (8 つの float を提供) がその位置と速度を格納します。

#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 に答える