2

私は 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}};

私の問題に「光を当てる」ための助けは大歓迎です! (しょうがない…;))

前もって感謝します!

4

2 に答える 2

4

より多くの頂点、できればnxnの正方形でより大きなグリッドを作成することをお勧めします。細い三角形が長すぎないようにしてください。これにより、サーフェスのピクセルごとではなく、頂点ごとにライトが計算されるため、ライトがどこにあるように見えるかを簡単に確認できます。

http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/

2.テッセレーションが不十分だと照明が損なわれる

OpenGLのライティング計算は、頂点ごとに行われます。これは、3Dオブジェクトの表面マテリアルと相互作用する光源によるシェーディング計算が、オブジェクトの頂点でのみ計算されることを意味します。通常、OpenGLは、頂点カラー間のシェードを補間または滑らかにするだけです。OpenGLの頂点ごとのライティングは、鏡面ハイライトやスポットライトなどのライティングエフェクトがオブジェクトの頂点によって十分にサンプリングされていないために失われたりぼやけたりした場合を除いて、非常にうまく機能します。このような照明効果のアンダーサンプリングは、オブジェクトが最小数の頂点を使用するように粗くモデル化されている場合に発生します。

初心者のOpenGLプログラマーは、OpenGLのスポットライト機能を有効にして、単一の巨大なポリゴンとしてモデル化された壁にスポットライトを当てたいと思うことがよくあります。残念ながら、初心者が意図したように鋭いスポットライトパターンは表示されません。おそらく、スポットライトの影響はまったく見られないでしょう。問題は、スポットライトのカットオフは、頂点が指定されている壁の極端なコーナーがスポットライトからの寄与を受けず、壁にある唯一の頂点であるため、壁にスポットライトパターンがないことを意味します。

于 2010-01-24T17:27:14.473 に答える
3

GL_POSITIONは同次座標で指定されます。つまり、3 つではなく 4 つの値が必要です。光源にw = 1.0を指定する必要がありますが、代わりにwコンポーネントは、メモリ内で偶然隣にあるものから来てlight0Positionいます。

(同次座標にある理由の 1つは、 w = 0.0GL_POSITIONで位置を設定することによって指向性ライトを定義できるようにするためです。)

于 2010-01-24T20:01:34.517 に答える