Pergunta

Sou novo no OpenGL ES e estou desenvolvendo no Objective-C para iPhone.

O que estou tentando entender é como a luz está posicionada no meu frustum. É assim que eu faço:

Crio um quadrado e o coloco como "piso" no meu frustum. Estou colocando a luz, logo acima, no meio do chão e aponte a direção da luz para baixo. Agora, espero que o círculo leve no chão esteja no meio. Mas não é, é mais para as costas (fugir). Por quê?

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},

Isso juntos não deveria fazer o círculo de luz estar no meio do chão e não se posicionar um pouco para trás?

Aqui está meu código significativo:

Configurando a exibição:

 -(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); 

    }

E desenho:

     -(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); }

Além disso, eu reconava a alteração do

static const Vertex3D light0Position[] = {{0.0, 0.473, -10.0}};

para

static const Vertex3D light0Position[] = {{0.0, 0.473, -8.0}}; 

A Bord fica escura, nenhuma luz brilha nela. Por que, eu só movi a luz dois passos para mais perto ...? As mesmas coisas acontecem se eu mover dois passos mais longe assim:

static const Vertex3D light0Position[] = {{0.0, 0.473, -12.0}};

Qualquer ajuda para "lançar a luz da luz" do meu problema é muito apreciada! (Não pude evitar ...;)))

Desde já, obrigado!

Foi útil?

Solução

Sugiro que você faça uma grade maior com mais vértices, de preferência n por n quadrados. Tente não ter triângulos finos muito longos. Isso tornará mais fácil ver onde a luz parece estar, pois a luz é calculada para cada vértice e não por pixel para a superfície.

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

2. Pobre piedade do dólar prejudica a iluminação

Os cálculos de iluminação do OpenGL são feitos por vertex. Isso significa que os cálculos de sombreamento devido a fontes de luz interagindo com o material da superfície de um objeto 3D são calculados apenas nos vértices do objeto. Normalmente, o OpenGL apenas interpola ou lisa tons entre as cores dos vértices. A iluminação per-vertex do OpenGL funciona muito bem, exceto quando um efeito de iluminação, como um destaque especular ou um holofote, é perdido ou borrado, porque o efeito não é suficientemente amostrado pelos vértices de um objeto. Esse sub-amostragem de efeitos de iluminação ocorre quando os objetos são modelados grosseiramente para usar um número mínimo de vértices.

:

Os programadores iniciantes do OpenGL são frequentemente tentados a permitir a funcionalidade de destaque do OpenGL e destacar um holofote em uma parede modelada como um único polígono enorme. Infelizmente, nenhum padrão de destaque nítido aparecerá como o novato pretendido; Você provavelmente não verá nenhum efeito de destaque. O problema é que o corte dos holofotes significa que os cantos extremos da parede onde os vértices são especificados não têm contribuição dos holofotes e, como esses são os únicos vértices que a parede possui, não haverá padrão de destaque na parede.

Outras dicas

GL_POSITION é especificado em coordenadas homogêneas, o que significa que requer quatro valores, não três. Você precisa especificar W = 1.0 para sua fonte de luz, mas seu W O componente está vindo do que quer que aconteça ao lado de light0Position em memória.

(Parte da razão pela qual GL_POSITION está em coordenadas homogêneas é permitir que você defina luzes direcionais, definindo uma posição com W = 0.0.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top