あなたが求めたものから始めましょう。
attribute float weights[25];
現在存在するほとんどのハードウェアでは、コンパイルできません。シェーダーは属性の配列を持つことができますが、各配列インデックスは新しい属性インデックスを表します。そして、現在存在するすべてのハードウェアで、属性インデックスの最大数は... 16 です。25 が必要です。これは重みのためだけです。
これで、属性を使用できることを覚えておくことで、これを簡単に軽減できvec4
ます。したがって、4 つの配列要素ごとに 1 つの属性に格納します。あなたの配列は実行可能attribute vec4 weights[7];
です。もちろん、重みを取得するロジックを変更する必要があります。
それでも、頂点データにとってこれが実際に意味することの影響を取り入れていないようです。各属性は、頂点のデータのコンポーネントを表します。レンダリング呼び出しの各頂点には、同じ量のデータが含まれます。そのデータの内容は異なりますが、データの量は異なります。
あなたが提案していることを行うには、メッシュ内のすべての頂点に、重みを表す 25 個の float が必要です。これが正規化された符号なしバイトとして格納されたとしても、少なくとも 25 バイト分のデータが追加されます。それは沢山。特に、大多数の頂点では、これらの値のほとんどが 0 になることを考慮してください。最悪の場合でも、1 つの頂点に影響を与える 6 ~ 7 個のボーンが表示されることになります。
頂点シェーダーでスキニングが一般的に行われる方法は、1 つの頂点に影響を与えるボーンの数を4に制限することです。この方法では、属性の配列を使用しません。vec4
重みに属性を使用するだけです。もちろん、どのボーンがどのウェイトに関連付けられているかも指定する必要があります。したがってvec4
、そのウェイトのボーン インデックスを指定する 2 番目のアトリビュートがあります。
これはバランスが良い。追加の属性を 2 つだけ使用します (サイズに関しては符号なしバイトである可能性があります)。また、ほとんどの頂点は 1 ~ 3 個のボーンの影響を受けるだけなので、ほとんどの頂点については気付かないでしょう。4 を使用する人もいますが、5 つ以上を使用する人はさらに少なくなります。そのような場合、最も低い重みを切り取り、他の重みを比例して再計算します。