glkit/opengl-esの法線を自動的に計算します
質問
Appleのサンプルコードに基づいて、OpenGl-ESでいくつかのかなり基本的な形状を作成しています。彼らは一連のポイントを使用し、最初の配列にインデックスの配列があり、3つのインデックスの各セットがポリゴンを作成します。それはすべて素晴らしいことです、私は私が望む形を作ることができます。形状を正しく覆うには、各ポリゴンの各頂点の法線を計算する必要があると思います。最初は形状が立方体だったので、非常に簡単でしたが、今では(わずかに)より高度な形状を作成しています。ポリゴンの2つのエッジ(すべてのポリスはここでは三角形です)のベクトルを取得し、そのポリゴンのすべての頂点にクロス製品を使用すると、簡単に思えます。その後、以下のようなコードを使用して形状を描画します。
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, triangleVertices);
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, 0, triangleColours);
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 0, triangleNormals);
glDrawArrays(GL_TRIANGLES, 0, 48);
glDisableVertexAttribArray(GLKVertexAttribPosition);
glDisableVertexAttribArray(GLKVertexAttribColor);
glDisableVertexAttribArray(GLKVertexAttribNormal);
私が理解しているのは、私がこれを手動でしなければならない理由です。表面に垂直なベクトル以外のものが必要な場合は、これが最も人気のあるユースケースであると確信しているので、簡単な方法はありませんか?明白なものを逃したことがありますか? glcalculatenormals()は素晴らしいでしょう。
//ここに、glkvector3 []の回答パスがあります。これは、頂点(それぞれ3つがポリゴンにグループ化されている)、次に頂点のカウントで、通常の通常で満たされたいと考えています。
- (void) calculateSurfaceNormals: (GLKVector3 *) normals forVertices: (GLKVector3 *)incomingVertices count:(int) numOfVertices
{
for(int i = 0; i < numOfVertices; i+=3)
{
GLKVector3 vector1 = GLKVector3Subtract(incomingVertices[i+1],incomingVertices[i]);
GLKVector3 vector2 = GLKVector3Subtract(incomingVertices[i+2],incomingVertices[i]);
GLKVector3 normal = GLKVector3Normalize(GLKVector3CrossProduct(vector1, vector2));
normals[i] = normal;
normals[i+1] = normal;
normals[i+2] = normal;
}
}
解決
そして再び答えは次のとおりです。 OpenGLは、シーンマネジメントライブラリでもジオメトリライブラリでもありませんが、描画APIだけです それは画面に素敵な写真を描きます。照明には正規が必要であり、通常の通常を与えます。それで全部です。これをユーザーが実行することができ、実際の描画とは何の関係もないのに、なぜそれは正常に計算する必要があるのですか?
多くの場合、とにかく実行時にそれらを計算するのではなく、ファイルからそれらをロードします。また、通常の量を計算するには多くの方法があります。顔ごとの通常の法線またはverter-vertexの通常は必要ですか?特定のハードエッジまたは特定の滑らかなパッチが必要ですか?頂点法線を取得するために平均的な顔の正規標準時を取得する場合、これらをどのように平均化したいですか?
そして、シェーダーの出現と、新しいOpenGLバージョンのビルトイン通常の属性と照明計算の削除により、この質問全体は、あなたが望む方法で照明をすることができるので、とにかく時代遅れになり、従来の通常の正規を必要としないようにします。
ちなみに、現時点では、フェイスごとの通常の法線を使用しているように聞こえます。つまり、顔のすべての頂点は同じ正常を持っていることを意味します。これにより、ハードエッジを備えた非常にファセットモデルが作成され、インデックスと一緒にうまく機能しません。滑らかなモデルが必要な場合(私は知りません、たぶん、あなたは本当にファセットの外観が欲しいかもしれません)、あなたは各頂点の通常の法線を計算するために、各頂点の隣接面の顔の正常を平均する必要があります。それは実際には、より一般的なユースケースであり、フェイスごとの正規ではありません。
したがって、この擬似コードのようなことができます。
for each vertex normal:
intialize to zero vector
for each face:
compute face normal using cross product
add face normal to each vertex normal of this face
for each vertex normal:
normalize
スムーズなverter-vertex Normalを生成します。実際のコードでさえ、これは10〜20行のコードをもたらすはずですが、これは実際には複雑ではありません。