これが私のSetup()関数です:
void Setup() // TOUCH IT !!
{
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
//Parameter handling
glShadeModel (GL_SMOOTH);
//glEnable(GL_NORMALIZE);
glDepthFunc(GL_LEQUAL); //renders a fragment if its z value is less or equal of the stored value
glClearDepth(1);
//Set up light source
GLfloat light_position[] = { 20.0, 0.0, 0.0, 0.0 };
GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, light_position);
glLightfv( GL_LIGHT0, GL_AMBIENT, ambientLight );
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseLight );
glEnable(GL_LIGHT0);
// polygon rendering mode
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glColorMaterial( GL_FRONT, GL_EMISSION );
// material identities
float specReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float ambReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float diffReflection[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);
glMaterialfv(GL_FRONT, GL_AMBIENT, ambReflection);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffReflection);
glMateriali(GL_FRONT,GL_SHININESS,20);
//// about texture
//glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// Black background
glClearColor(0.0f,0.0f,0.0f,1.0f);
}
これが私のCalcNormal()
関数で、法線が計算されています。v1とv2は、三角形の2つのベクトルです。
Point CalcNormal(Point v1, Point v2)
{
Point normal;
normal.x = v1.y*v2.z - v1.z*v2.y;
normal.y = -v1.x*v2.z + v2.x*v1.z;
normal.z = v1.x*v2.y - v2.x*v1.y;
float dist1 = sqrt( pow(v1.x,2) + pow(v1.y,2) + pow(v1.z,2));
float dist2 = sqrt( pow(v2.x,2) + pow(v2.y,2) + pow(v2.z,2));
float dist = dist1*dist2;
normal.x = normal.x/dist;
normal.y = normal.y/dist;
normal.z = normal.z/dist;
return normal;
}
これが私がCalcNormal()に送るベクトルです:
Point n;
Point a1, a2;
a1.x=triangles.at(i).p2.x-triangles.at(i).p1.x; a1.y=triangles.at(i).p2.y-triangles.at(i).p1.y; a1.z=triangles.at(i).p2.z-triangles.at(i).p1.z;
a2.x=triangles.at(i).p3.x-triangles.at(i).p1.x; a2.y=triangles.at(i).p3.y-triangles.at(i).p1.y; a2.z=triangles.at(i).p3.z-triangles.at(i).p1.z;
n = CalcNormal(a1, a2);
結果は次のようになります。
スムーズなシェーディングを効果的にするには、頂点ごとにスムーズな法線も必要です。これまでに投稿したコードは、三角形ごとの通常の計算のみを示しています。その場合、結果はフラットに見えます。
滑らかな法線を取得する最も簡単な方法は、三角形ごとの法線を計算した後、各頂点の隣接する三角形のすべての法線を平均化することです。より複雑なスキームでは、三角形の面積の関数に基づく加重平均を使用します。ハードエッジを節約しようとするヒューリスティックもいくつかありますが、ヒューリスティックでは常にそうであるため、常にいくつかのコーナーケースがあります。理想的には、法線はモデルが作成されてファイルに保存されるときに作成されます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加