Перейти на главную   
  helloworld.ru - документация и книги по программированию  
helloworld.ru - документация и книги по программированию
    главная     хостинг    
Поиск по сайту:  
Смотрите также
Языки программирования
C#
MS Visual C++
Borland C++
C++ Builder
Visual Basic
Quick Basic
Turbo Pascal
Delphi
JavaScript
Java
PHP
Perl
Assembler
AutoLisp
Fortran
Python
1C

Интернет-технологии
HTML
VRML
HTTP
CGI
FTP
Proxy
DNS
протоколы TCP/IP
Apache

Web-дизайн
HTML
Дизайн
VRML
PhotoShop
Cookie
CGI
SSI
CSS
ASP
PHP
Perl

Программирование игр
DirectDraw
DirectSound
Direct3D
OpenGL
3D-графика
Графика под DOS

Алгоритмы
Численные методы
Обработка данных

Сис. программирование
Драйверы

Базы данных
MySQL
SQL

Другое

Хостинг


Друзья
demaker.ru
Реклама

Лучший хостинг. Аренда серверов




helloworld.ru





 в самое начало


demo.design
3D programming FAQ



ОСВЕЩЕНИЕ
5.2. Расчет нормали к объекту

Во всех формулах для освещенности у нас так или иначе будет фигурировать вектор N - нормаль к объекту в точке P. Сразу возникает вопрос, а как же этот вектор считать.

Обычно придерживаются такой логики. Модель у нас состоит из плоских граней, но эта сетка плоских граней приближает какой-то искривленный объект. Нормаль к этому искривленному объекту меняется в каждой точке, а для плоских граней она постоянна для всех точек грани, и резко меняется при переходе на другую грань. Поэтому нормаль к объекту обычно приближают следующим образом: считают нормали в вершинах, а нормаль в какой-то точке грани линейно интерполируют между вершинами; то есть линейно интерполируют по грани все три координаты нормали.

Нормаль в вершине рассчитываются как сумма приведенных к длине 1 нормалей ко всем граням, к которым принадлежит эта вершина. То есть. Сначала считаем нормали ко всем граням и приводим их к длине 1. Далее, для каждой вершины надо перебрать все грани, и если очередная грань содержит эту вершину, то к нормали в вершине прибавляется нормаль к этой грани. Первоначально все нормали к вершинам полагаются равными нулю. Для больших моделей этот процесс может быть довольно долгим, но достаточно провести его заранее один раз и сохранить все посчитанные нормали к вершинам.

Для вящей понятности приведу кусок кода:

// ...
for (i = 0; i < numberOfVertics; i++) {
  vertexNormal[i].x = 0;
  vertexNormal[i].y = 0;
  vertexNormal[i].z = 0;
}
for (i = 0; i < numberOfVertics; i++) {
  for (j = 0; j < numberOfFaces; j++) {
    if (face[j].vertex0 == i ||
        face[j].vertex1 == i ||
        face[j].vertex2 == i)
    {
      vertexNormal[i].x += faceNormal[j].x;
      vertexNormal[i].y += faceNormal[j].y;
      vertexNormal[i].z += faceNormal[j].z;
    }
  }
}
// ...

Но это метод даже слишком лобовой, и поэтому медленный. Можно сделать все проще и быстрее: перебираем все грани, и к нормалям всех принадлежащих грани вершин добавляем нормаль грани. После этого приводим все нормали к длине 1, причем эта фаза даже не обязательна, а лишь удобна для дальнейших расчетов. Соответствующий кусочек кода:

// ...
for (i = 0; i < numberOfVertics; i++) {
  vertexNormal[i].x = 0;
  vertexNormal[i].y = 0;
  vertexNormal[i].z = 0;
}
for (i = 0; i < numberOfFaces; i++) {
  vertexNormal[face[i].vertex0].x += faceNormal[j].x;
  vertexNormal[face[i].vertex1].y += faceNormal[j].y;
  vertexNormal[face[i].vertex2].z += faceNormal[j].z;
}
// ...


 в самое начало


demo.design
3D programming FAQ














helloworld.ru © 2001-2021
Все права защищены