ПрограммированиеФорумГрафика

Тени, frustum culling, octree/quad-tree... (2 стр)

Страницы: 1 2 3 Следующая »
#15
0:44, 23 авг 2009

@!!ex
> Т.к. для направленного источника тень имеет тотже размер, что и сам объект
> От направленного источника света тень всегда будет одного размера, на любом расстоянии.
Чушь какая-то...

#16
0:47, 23 авг 2009

Elec3C
> Чушь какая-то...
Почему чушь?
Если тень без разноса по дальности, то всё верно.

#17
3:44, 23 авг 2009

@!!ex
Вообще, я понял так (правда я не понял, как строить бокс):
Скрин: Бокс (OBB) тени строить так?
shadow_3 | Тени, frustum culling, octree/quad-tree...

Скрин: Или так?
shadow_4 | Тени, frustum culling, octree/quad-tree...

Или вообще как-то по-другому строить? OBB или AABB бокс? Привёл бы чтоли картинки, как строить и что?

SNVampyre
См. скрины этого поста

#18
11:53, 23 авг 2009

ну тебе уже сказали 5 раз - строишь фрустум от источника, прицеливаясь на ресиверов в кадре. выбираешь им кастеров из сг и их рисуеж
З.Ы. для общего развития можно было бы хотябы одну бумагу про тени прочитать ну или дему пасмареть

#19
16:06, 23 авг 2009

kas
... или даже обратить внимание на скриншот...

#20
16:24, 23 авг 2009

Z
это слишком сложно!

#21
17:43, 23 авг 2009

kas
Ты читать умеешь или нет? Я у @!!ex спрашиваю, что он предлагал боксы строить, а не фрустумы, разъяснения его предложения насчёт боксов.

#22
17:51, 23 авг 2009

Elec3C
извини, я думал ты спрашываешь про то как делать правильно. нет так нет

#23
18:09, 23 авг 2009

Кстати, реально, достаточно построить несколько плоскостей на основе фрустума и его граней в сторону источника света.
Если объект будет лежать внутри всех этих плоскостей (а их может быть 4 или 5), то он отбрасывает тень во фрустум.

#24
19:13, 23 авг 2009

А как вычислять длину тени, чтобы правильно построить бокс/фрустум?

Скрин (в данном случае - бокс):
shadow_5 | Тени, frustum culling, octree/quad-tree...

#25
19:25, 23 авг 2009

Раз не надо как павильно, а просто для фана посчитать какие-то страннъе боксъ - можно заюзать marching cubes, оценивая тень в углах куба и разбивая его, если разнъе углъ не одинакого в/вне тени. Получится даже точнее бокса - сурфейс тени!

#26
20:39, 23 авг 2009

Накидал примерный код.

class vec3  // класс вектора
{
public:
  float x, y, z;
  inline vec3 (float X, float Y, float Z)
  {
    x = X, y = Y, z = Z;
  }
  inline vec3 Sub (vec3 &v)
  {
    return vec3 (x - v.x, y - v.y, z - v.z);
  }
  // скалярное произведение
  inline float Dot (vec3 &v)
  {
    return x*x + y*y + z*z;
  }
  // векторное произведение
  inline float Cross (vec3 &v)
  {
    return  vec3 (v.z*y - v.y*z, v.x*z - v.z*x, v.y*x - v.x*y);
  }
};

class plane  // класс плоскости
{
public:
  float x, y, z, d;
  // проверка, лежит ли точка внутри плоскости
  bool Slice (vec3 &p)
  {
    return  x*p.x + y*p.y + z*p.z > d;
  }
  // установка плоскости по нормали и одной из точек в этой плоскости
  void Set (vec3 &nrm, vec3 &pos)
  {
    x = nrm.x, y = nrm.y, z = nrm.z, d = pos.Dot (nrm);
  }
};

class frustum  // класс фрустума
{
public:
  plane clips[4];  // плоскости фрустума
  vec3 look[4];  // направления по углам фрустума
  vec3 center;  // вершина фрустума
};

class lightClips
{
public:
  plane clips[6];  // плоскости отсечения
  int count;  // количество плоскостей отсечения
  vec3 lPos;  // позиция источника света
  // построение плоскостей отсечения, определяющих видимость теней от объектов
  void Compute (frustum &fr)
  {
    count = 0;
    int first = 4, last = 0;
    // с начала добавим плоскости фрустума, внутри которых лежит источник света
    for(int i = 0; i < 4; i++)
      if(!fr.clips[i].Slice (lPos))
        first = min (first, i),
        last = max (last, i),
        clips[count++] = fr.clips[i];


    // теперь достроим наш набор плоскостей на основе оставшихся граней
    if((count < 4)&&(count > 0))
    {
        if((last == 3)&&(first == 0))
          first = 3, last = 0;
        vec3 lVec = lPos.Sub (fr.center);
        vec3 cr1 = lVec.Cross (fr.look[first]);
        vec3 cr2 = fr.look[(last + 1)%4].Cross (lVec);

        // cr1 и cr2 можно нормализовать, но не обязательно
        clips[count++].Set (cr1, fr.center);
        clips[count++].Set (cr2, fr.center); 
    }   

    // если источник света стоит за камерой
    if(count == 0)
    {
      // строим фрустум по источнику света и точкам полученным от
      // center + look*бесконечность
      // в лом расписывать
    }
  }
  //  теперь в clips записаны необходимые нам плоскости
};

Могут быть ошибки, но идея должна быть правильной :-)
Суть такова, что лежащее внутри полученных плоскостей будет отбрасывать тень во фрустум, а то что лежит вне - не даёт никак.


Правка:
Обнаружил пару ошибок.

#27
0:37, 24 авг 2009

Z
Если честно, я не совсем понял твой метод (да и скрин слишком нагружен для понимания) :)

SNVampyre
Надо попробовать реализовать :)

#28
1:59, 24 авг 2009

Elec3C
В ближайшем будущем тоже попробую :-)
А главное преимущество в том, что для теста не надо строить шапку от каждого объекта.
Строим плоскости только для источника, в дальнейшем тест ничем не отличается от простого фрустум-куллинга.
То есть можно использовать всю иерархию объектов на сцене, которая используется для других тестов.
Лучше всего конечно же брать сферы, они по плоскостям рубятся самым лучшим образом.

Там кстати "vec3 Cross" должно быть.
И плоскости лучше всё же нормализовать.

#29
9:23, 24 авг 2009

Elec3C
У направленного источника света все лучи параллельные.
Значит размер тени будет такой же как и сам объект, на любом расстоянии, т.к. в любой точке между параллельными линиями одно и тоже расстояние.
Именно поэтому от направленного источника света нужно строить бокс, а не пирамиду.

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.