Сфера Затенение OpenGL - PullRequest
       8

Сфера Затенение OpenGL

0 голосов
/ 09 ноября 2011

Я пытаюсь затенить сферу. Я понятия не имею, с чего начать.Я вычислил вершины и соединил их с помощью GL_TRIANGLE_FAN, а также нарисовал нормали к каждой вершине.Проблема в том, что я понятия не имею, как вообще начать делать затенение / освещение.Я использую OpeGL 3+.Вот некоторые из моего кода:

Расчеты вершин сферы (я нашел в сети и реализовал):

void CreateUnitSphere(int dtheta,int dphi) //dtheta, dphi angle
{

    GLdouble x,y,z;
    GLdouble magnitude=0;
    int no_vertice=-1;
    int n;
    int k;
    int theta,phi;
    const double PI = 3.1415926535897;
    GLdouble DTOR = (PI/180);//degrees to radians


    //setting the color to white
    for (k=0; k<10296*3; k+=1)
    {
        sphere_vertices[k].color[0] = 1.0f;
        sphere_vertices[k].color[1] = 1.0f;
        sphere_vertices[k].color[2] = 1.0f;
    }


   for (theta=-90;theta<=90-dtheta;theta+=dtheta) {
      for (phi=0;phi<=360-dphi;phi+=dphi) {


     x = cos(theta*DTOR) * cos(phi*DTOR);
     y = cos(theta*DTOR) * sin(phi*DTOR);
         z = sin(theta*DTOR);

    //calculating Vertex 1
    no_vertice+=1;
    sphere_vertices[no_vertice].position[0] = x;
    sphere_vertices[no_vertice].position[1] = y;
    sphere_vertices[no_vertice].position[2] = z;

         x = cos((theta+dtheta)*DTOR) * cos(phi*DTOR);
         y = cos((theta+dtheta)*DTOR) * sin(phi*DTOR);
         z = sin((theta+dtheta)*DTOR);

    //calculating Vertex 2
    no_vertice+=1;
    sphere_vertices[no_vertice].position[0] = x;
    sphere_vertices[no_vertice].position[1] = y;
    sphere_vertices[no_vertice].position[2] = z;

    x = cos((theta+dtheta)*DTOR) * cos((phi+dphi)*DTOR);
        y = cos((theta+dtheta)*DTOR) * sin((phi+dphi)*DTOR);
        z = sin((theta+dtheta)*DTOR);

    //calculating Vertex 3
    no_vertice+=1;
    sphere_vertices[no_vertice].position[0] = x;
    sphere_vertices[no_vertice].position[1] = y;
    sphere_vertices[no_vertice].position[2] = z;

        if (theta > -90 && theta < 90) {

            x = cos(theta*DTOR) * cos((phi+dphi)*DTOR);
            y = cos(theta*DTOR) * sin((phi+dphi)*DTOR);
            z = sin(theta*DTOR);

    //calculating Vertex 4
    no_vertice+=1;
    sphere_vertices[no_vertice].position[0] = x;
    sphere_vertices[no_vertice].position[1] = y;
    sphere_vertices[no_vertice].position[2] = z;

         }

    }

   }

no_vertice = -1;
int no_index=10296; 

//calculate normals and add them to the array of vertices
   for (no_vertice=0; no_vertice<=10296; no_vertice+=1) {

    no_index+=1;

    //getting the sphere's vertices
    x=sphere_vertices[no_vertice].position[0];
    y=sphere_vertices[no_vertice].position[1];
    z=sphere_vertices[no_vertice].position[2];

    //normalising vector "norm(Vertex - Center)"
    magnitude = sqrt((x*x) + (y*y) + (z*z));

    //adding the new vector (the one divided by the magnitude
    sphere_vertices[no_index].position[0] = (x/magnitude)/0.8;
    sphere_vertices[no_index].position[1] = (y/magnitude)/0.8;
    sphere_vertices[no_index].position[2] = (z/magnitude)/0.8;

    ///adding the vertex's normal (line drawing issue)
    no_index+=1;
    sphere_vertices[no_index].position[0] = sphere_vertices[no_vertice].position[0];
    sphere_vertices[no_index].position[1] = sphere_vertices[no_vertice].position[1];
    sphere_vertices[no_index].position[2] = sphere_vertices[no_vertice].position[2];

    }

}

Here is my Sphere without the

Вот моя сфера без "GL_TRIANGLE_FAN", Просто" GL_LINE_STRIP "и вот как я использую" glDrawArrays ":

glDrawArrays(GL_LINE_STRIP, 0, 10296);
glDrawArrays(GL_LINES, 10297, 30888);

От 0-10296 - вершины сферы.Из 10297-30888 - нормальные вершины сферы.

Вот мой файл вершин:

precision highp float;

in vec3 in_Position; //declare position
in vec3 in_Color;

// mvpmatrix is the result of multiplying the model, view, and projection matrices */
uniform mat4 mvpmatrix;
out vec3 ex_Color;

void main(void) {

// Multiply the mvp matrix by the vertex to obtain our final vertex position (mvp was created in *.cpp)

gl_Position = mvpmatrix * vec4(in_Position, 1.0);

ex_Color = in_Color;

}

и мой файл фрагментов

#version 330
precision highp float;

in vec3 ex_Color;
out vec4 gl_FragColor;

void main(void) {

gl_FragColor = vec4(ex_Color,1.0);

}

Теперь я знаю, что мне нужнопередать нормали в вершинный и фрагментный шейдеры, но как мне это сделать и как / где я могу реализовать вычисления света, линейную интерполяцию ??Спасибо

1 Ответ

1 голос
/ 09 ноября 2011

В основном вам нужно рассчитать освещение в вершинном шейдере и передать цвет вершины фрагментному шейдеру, если вы хотите освещение на каждую вершину или передать направление света и нормали в качестве переменных переменных и рассчитать все там для каждого пикселя осветительные приборы.

Основной трюк здесь заключается в том, что когда вы передаете нормаль к фрагментному шейдеру, он интерполируется между вершинами для каждого фрагмента, и в результате затенение становится очень плавным, но также и более медленным.

Вот очень хорошая статья для начала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...