OpenGL ES軽い質問
-
22-09-2019 - |
質問
私はOpenGL ESを初めて使用しており、iPhone用のObjective-Cで開発しています。
私が理解しようとしているのは、光が私の閃光にどのように配置されているかです。これが私がそれをする方法です:
私は正方形を作り、それを私のフラストムに「床」として置きます。私は床の真ん中に光を置き、光の方向をすぐに向けています。今、私は床のライトサークルが真ん中にあることを期待しています。しかし、それはそうではありません、それは背中にもっと(未来)。どうして?
near = 8.0
far = 28
light position = {0.0, 0.0, -10.0}
light direction = {0.0, -1.0, 0.0}
Floor coordinates = {-0.3153, -0.473, -20.0},
{-0.3153, -0.473, 0.0},
{0.3153, -0.473, -20.0},
{0.3153, -0.473, 0.0},
これが一緒になって、光の輪を床の真ん中に置き、少し後方に配置しないようにするべきではありませんか?
これが私の重要なコードです:
ビューの設定:
-(void)setupView:(TDRoomView*)view
{
const GLfloat zNear = 8, zFar = 28, fieldOfView = 5;
GLfloat size;
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
NSLog(@"tanf(DEGREES_TO_RADIANS(fieldOfView)/2.0); %f ", tanf(DEGREES_TO_RADIANS(fieldOfView)/2.0));
CGRect rect = view.bounds;
glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size /
(rect.size.width / rect.size.height), zNear, zFar);
glViewport(-size, size, rect.size.width, rect.size.height);
glMatrixMode(GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
static const Color3D light0Ambient[] = {{1.0, 1.0, 1.0, 1.0}};
glLightfv(GL_LIGHT0, GL_AMBIENT, (const GLfloat *)light0Ambient);
static const Color3D light0Diffuse[] = {{0.5, 0.5, 0.5, 1.0}};
glLightfv(GL_LIGHT0, GL_DIFFUSE, (const GLfloat *)light0Diffuse);
static const Color3D light0Specular[] = {{0.5, 0.5, 0.5, 1.0}};
glLightfv(GL_LIGHT0, GL_SPECULAR, (const GLfloat *)light0Specular);
static const Vertex3D light0Position[] = {{0.0, 0.473, -10.0}};
glLightfv(GL_LIGHT0, GL_POSITION, (const GLfloat *)light0Position);
static const Vertex3D lightVector= {0.0, -1.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (GLfloat *)&lightVector);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 85);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}
と描画:
-(void)drawView:(TDRoomView*)view
{
static const Vertex3D vertices[]= {
{-0.3153, -0.473, -20.0},
{-0.3153, -0.473, 0.0},
{0.3153, -0.473, -20.0},
{0.3153, -0.473, 0.0},
{-0.1, -0.25, -3.0},
{0.0, 0.0, -10.0},
{0.1, -0.25, -3.0}
};
static const Color3D colors[] = {
{0.7, 0.7, 0.7, 1.0},
{0.7, 0.7, 0.7, 1.0},
{0.7, 0.7, 0.7, 1.0},
{0.7, 0.7, 0.7, 1.0},
{1.0, 0.0, 0.0, 1.0},
{0.0, 1.0, 0.0, 1.0},
{0.0, 0.0, 1.0, 1.0}
};
static const GLubyte roomFaces[] = {
0, 1, 2,
1, 2, 3};
static const Vector3D normals[] = {
{0.000000, 1.000000, 0.000000},
{0.000000, 1.000000, 0.000000},
{0.000000, 1.000000, 0.000000},
{0.000000, 1.000000, 0.000000},
{0.000000, 1.000000, 0.000000},
{0.000000, 1.000000, 0.000000},
{0.000000, 1.000000, 0.000000}
};
glLoadIdentity();
glClearColor(0.7, 0.7, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glNormalPointer(GL_FLOAT, 0, normals);
glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_BYTE, roomFaces);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY); }
また、変更を再確認します
static const Vertex3D light0Position[] = {{0.0, 0.473, -10.0}};
に
static const Vertex3D light0Position[] = {{0.0, 0.473, -8.0}};
ボルトは暗くなり、光が輝いていません。なぜ、私は光を2つのステップに近づけるだけです...?このようにさらに2つのステップを移動すると同じことが起こります:
static const Vertex3D light0Position[] = {{0.0, 0.473, -12.0}};
私の問題について「som光を流す」ための助けは大歓迎です! (それを助けることができませんでした...;))
前もって感謝します!
解決
より多くの頂点を備えたより大きなグリッド、できればn squares by n squaresを使用することをお勧めします。薄い三角形が長すぎないようにしてください。これにより、各頂点の光が計算され、表面のピクセルごとではなく、光が計算されるにつれて、光がどこにあるかを簡単に確認できます。
http://www.opengl.org/resources/features/kilgardtechniques/oglpitfall/
2.貧弱なテッセレーションは照明を傷つけます
OpenGLの照明計算は、ver-vertexごとに行われます。これは、3Dオブジェクトの表面材料と相互作用する光源によるシェーディング計算が、オブジェクトの頂点でのみ計算されることを意味します。通常、OpenGLは、頂点の色の間の補間または滑らかな色合いだけです。 OpenGLのver-vert-vertex照明は、オブジェクトの頂点によって効果が十分にサンプリングされないため、鏡面ハイライトやスポットライトなどの照明効果が失われたりぼやけたりする場合を除き、非常にうまく機能します。このような照明効果の過少サンプリングは、オブジェクトが最小限の頂点を使用するように粗くモデル化されている場合に発生します。
:
初心者のOpenGLプログラマーは、OpenGLのスポットライト機能を有効にし、単一の巨大なポリゴンとしてモデル化された壁にスポットライトを当てるように誘惑されることがよくあります。残念ながら、初心者が意図したように鋭いスポットライトパターンは表示されません。おそらく、スポットライトの影響はまったく見られないでしょう。問題は、スポットライトのカットオフは、頂点が指定されている壁の極端な角がスポットライトから寄与しないことを意味し、壁が持っている唯一の頂点であるため、壁にスポットライトパターンがないことを意味します。
他のヒント
GL_POSITION
均一な座標で指定されています。つまり、3つではなく4つの値が必要です。指定する必要があります w あなたの光源の場合= 1.0、しかしあなたの場合 w 代わりに、コンポーネントは隣にあるものから来ています light0Position
メモリで。
(その理由の一部 GL_POSITION
均一な座標にあることは、位置を設定することにより、方向ライトを定義できるようにするためです w = 0.0.)