私は、CPUからOpenGLコンピューティングシェーダーへのマーチングキューブの実装の移植にほとんど成功しましたが、私はまだ法線に取り組んでおらず、そのための最善の方法を考えていません。
私の実装では特にバイナリ値フィールドを扱います(まだ距離推定器を持たない3Dフラクタル関数をモデル化しようとしているため)、勾配法と前方差分法は機能しません。動作する頂点を共有しました。私のCPU実装では、ここで説明するQuilezの方法を使用して、隣接する各頂点に面法線を蓄積します。
この実装を別のシェーダーに移植することもできますが、これで発生する問題は、必要なアトミックの膨大な数です。私たちはスカラー整数型でのみアトミックを使用でき、3つの符号付き整数を合計可能な方法で1にパックする方法を考えることができないので、シェーダー呼び出しごとに3軸* 3頂点= 9アトミック追加を意味します。もちろん、それらはメモリ全体に分散されるため、1つのアトミックカウンターを9回ヒットするようなものではありませんが、それでもまだかなりのようです。
もう1つの方法は、ポリゴンごとのシェーダー呼び出しを実行して面の法線リストを作成し(おそらくこの方法でx10y10z10にパックすることができます)、次に頂点ごとのシェーダーで隣接する面の法線をすべて蓄積します。ただし、これは膨大なメモリを消費しますが、最悪の場合に対処するには、面インデックスのストレージスペースに頂点ごとに12 intが必要になります。また、特定の頂点に既に書き込まれている面の数を計算するためにアトミックに頼らずに、このストレージに書き込む方法の問題もあります。
誰でもこれを行う方法についてもっと良いアイデアがありますか?