Должны ли мои нормали к вершинам быть такими? - PullRequest
1 голос
/ 12 ноября 2011

Я рисую сферу с помощью четырехугольников. Я строю лишнюю вершину, чтобы разделить четырехугольник на 2 треугольника. Так это выглядит так:

1 ----> 2
|       |
|       |
4 ----> 3

но после 3 я снова строю 1. Итак, представьте дополнительную строку от 3 -> 1.

Я сейчас пытаюсь вычислить каждую вершину как нормальную. Вот мой код:

//calculate normals
   for (no_vertice=0; no_vertice<12887; no_vertice+=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));

    sphere_vertices[no_vertice].normal[0] = (x/magnitude);
    sphere_vertices[no_vertice].normal[1] = (y/magnitude);
    sphere_vertices[no_vertice].normal[2] = (z/magnitude);

    printf("Normal at vertice %d = X:%f, Y:%f, Z:%f. \n", no_vertice, sphere_vertices[no_vertice].normal[0], sphere_vertices[no_vertice].normal[1], sphere_vertices[no_vertice].normal[2]);

    }

Я рассчитываю величину для каждой вершины, а затем делю каждый компонент этой вершины на величину, чтобы получить единичный вектор. Проблема в том, что я получаю много нулевых векторов. то есть вершины с x = 0, y = 0, z = 0 ... Когда я передаю нормаль к вершинному шейдеру,

//my vertex structure
struct Vertex {

    GLdouble position[3];
    GLfloat color[3];
    GLdouble normal[3];
};

....
..
.

/* Enable attribute index 2 as being used */
    glEnableVertexAttribArray ( 2 );
    glVertexAttribPointer ( ( GLuint ) 2, 3, GL_FLOAT, GL_FALSE, sizeof ( struct Vertex ), ( const GLvoid* )
    offsetof(struct Vertex, normal) );

...
..
.

    //pass the normal to vertex shader  
    glBindAttribLocation(shaderprogram, 2, "in_Normal");

и сделаю мой легкий расчет, я получу все странные эффекты.

Я что-то не так делаю?

Самая запутанная часть - меня просят сделать это:

"Для сферы определите нормальное направление поверхности и увеличьте каркас Рисование с короткими линиями, представляющими нормальное направление каждой вершины. Сфера теперь должен казаться хедж-свиньей. "

"Примечание. Нормаль поверхности - это единичный вектор, перпендикулярный поверхности, при условии, что он плоский."

Так это в основном нормаль к вершине или к поверхности квадратора, которую я должен нарисовать? Я в замешательстве, потому что он говорит,

"Отработка поверхности в нормальном направлении"

, а затем

«Рисование с короткими линиями, представляющими нормальное направление каждой вершины»

Так где должны быть нарисованы линии ??? на вершине? или в середине четверки? Спасибо

РЕДАКТИРОВАТЬ: Расчет вершин

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


    //calculating Vertex 1
     x = cos(theta*DTOR) * cos(phi*DTOR);
     y = cos(theta*DTOR) * sin(phi*DTOR);
     z = sin(theta*DTOR);

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

    //calculating Vertex 2
    x = cos((theta+dtheta)*DTOR) * cos(phi*DTOR);
    y = cos((theta+dtheta)*DTOR) * sin(phi*DTOR);
    z = sin((theta+dtheta)*DTOR);

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

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

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

    //adding Vertex_1 again to divide the Quad into 2 triangles 
    //calculating Vertex 1
     x = cos(theta*DTOR) * cos(phi*DTOR);
     y = cos(theta*DTOR) * sin(phi*DTOR);
     z = sin(theta*DTOR);

    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) {

            //calculating Vertex 4
            x = cos(theta*DTOR) * cos((phi+dphi)*DTOR);
            y = cos(theta*DTOR) * sin((phi+dphi)*DTOR);
            z = sin(theta*DTOR);

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


             }
        }
   }

Ответы [ 3 ]

2 голосов
/ 12 ноября 2011

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

Прежде всего, вы получили порядок вершин, ну, не так, но несчастен. OpenGL предполагает правосторонность в векторных вычислениях (если только вы не поменяете местами одну ось в конце конвейера преобразования). Это означает, что вершины должны быть посчитаны против часовой стрелки. Вы можете сделать это по часовой стрелке, но все наоборот. Затем вы должны начать считать с 0, по крайней мере, если вы на языке, подобном C, который обращается к массивам по индексу смещения, то есть первый элемент имеет индекс 0.

3--2
| /|
|/ |
0--1

Нормы сферы, центрированной по происхождению, являются чем-то особенным, поскольку они нормализованы (не путайте «нормальное» с нормальным с нормальным размером, это разные вещи !) векторы положения вершины являются нормалью рассматриваемой вершины.

В общем случае нормаль можно оценить, взяв перекрестное произведение касательного пространства вершины, т. Е. Для треугольника перекрестное произведение векторов ребер в углу. В случае вашей четверки нормальное значение [0] будет

normalize( ([1]-[0]) × ([2]-[0]) )

для треугольника 0,1,2 и

normalize( ([2]-[0]) × ([3]-[0]) )

Обратите внимание, что это перекрестное произведение частных производных аналитического представления поверхности. Вы уже знаете аналитическое представление поверхности сферы (см. Учебное пособие Пола Бурка). В качестве упражнения я рекомендую проверить это, то есть доказать, что для сферы единичного радиуса вокруг начала координат положение точки поверхности равно нормали поверхности в этой точке.

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

Похоже, вы должны нарисовать сферу, составленную из квадратов, представьте апельсин с нарисованной на нем связкой квадратов.

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

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

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

С риском повторения :

Для заданной векторной позиции P на сфере, центр которой - C, нормаль - норма (P - C), гденорма нормализует вектор.

Я не вижу, чтобы ваш код делал это.Если вы не знаете, что позиции сосредоточены на происхождении, что не является предположением, которое вы высказали.

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