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

Решение проблемы разрывов при визуализации ландшафтов с LOD - уровнями (комментарии) (2 стр)

Страницы: 1 2 3 410 Следующая »
#15
13:11, 14 окт. 2009

в общем случае

идёт линейная интерполяция вдоль :) ребра с меньшим разбиением

A0 * ( 1 - a ) + AN ( a )

где a от 0 до 1, с шагом 1 / ( N - 1 )


#16
13:12, 14 окт. 2009

fanat

А какой порядка значения вершин ? ну x, y, z

я делал - проблем с точностью не было

#17
13:25, 14 окт. 2009

innuendo
порядок здесь ни при чем.
Я там с масштабом перемудрил в свое время. Far плоскость в районе 100к.
А сетка 8*8к.

Вот и что там от float точности осталось.
Кстати, пробовал прямо сейчас уменьшит масштаб - артефакты почти исчезли.

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

#18
13:40, 14 окт. 2009

бррр  ещё раз и по-медленней!

чтобы устреднить высоту вершин, нужно физически их "подвинуть".. нужно лочить буферы это РАЗ.
далее для каждого лода нудно держать хренову тучу вершинных буферов? (буфер для каждого ЛОД-а + такой же но с усреднёнными высотами для соединения с чанком с более низким уровнем детализации)  тогда например если ландшафт 1024*1024 , чанки размером 64 и 4 уровня детализации то:

это  256 чанков.  Каждый чанк держит 4 вершинных буфера (ЛОД-ы) + все вариации этих ЛОД-ов с устреднёнными вершинами.. на каждый ЛОД таких вариаций:8 (например усреднено только сверху или снизу или угол сверху и справа)
тоесть воробщем в чанке 8*4 + 4 = 36 вершинных буферов! а на весь террайн состоит из 9216 вершинных буферов  (страшно говорить про 4096*4096 террайн!!)

мож я просто чегото не понял..  мосх сегодня спит : )

я к тому, что...  ну ЗАЧЕМэти шаманства?  лочить буферы, менять вершины или держать туеву хучу маленьких буферов.
Можно ж просто индексный буфер так сформировать, то он будет "прореживать" нужную границу чанка в 2/4/8/16 и т.д. раз... (как это я себе сделал)
тупо ставим нужный индексный буфер и рисуем : )

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

террайн | Решение проблемы разрывов при визуализации ландшафтов с LOD - уровнями (комментарии)

#19
13:57, 14 окт. 2009

 L 
> чтобы устреднить высоту вершин, нужно физически их "подвинуть".. нужно лочить
> буферы это РАЗ.

обновляешь VB ( и не весь а только границы ) не каждый кадр ( реально lod сменяется раз в 5 - 10 в среднем )... и один буфер, текущий, хранится на GPU


#20
13:59, 14 окт. 2009

 L 
> (как это я себе сделал)

А за сколько DIPS рисуешь chunk ?

#21
14:00, 14 окт. 2009

fanat
> Если точночти вычислений не хватает - то пиксель выпадает(

не знаю, сколько я мудрил - ничего не выпадало :)

#22
14:08, 14 окт. 2009

innuendo
> А за сколько DIPS рисуешь chunk ?
эмм.. за один о_О

innuendo
> обновляешь VB ( и не весь а только границы ) не каждый кадр ( реально lod
> сменяется раз в 5 - 10 в среднем )... и один буфер, текущий, хранится на GPU
это для ландшафта 1024*1024  будет 256  SetStreamSource???  ппц

#23
14:12, 14 окт. 2009

 L 
> > А за сколько DIPS рисуешь chunk ?
> эмм.. за один о_О

тут что-то не то :) 

 L 
> будет 256 SetStreamSource??? ппц

зачем ?

#24
14:13, 14 окт. 2009

 L 

не чанк, а пачт ( лод ) - извини

за сколько лод рисуешь ?

#25
14:23, 14 окт. 2009

в том примере , что  я выложил, сетка 64к,а в все лоды содержат 9раз по 1024 вершины.

В кадре - не более половины (~40%).
Поэтому нет здесь вбо. Вершин совсем мало, вся нагрузка на филрейт)

#26
14:37, 14 окт. 2009

innuendo
ну сколько видно, столько и рисую.

тоесть:

1. куллим ландшафт и далее работаем только с видимыми чанками!!
2. если камера (игрок) передвинулся на другой чанк (отличной от того, что был в предыдущем кадре) -  у чанков меняем типы индексных буферов и LOD (тупо номер записываем)
3. выставляем вершинный фуфер  (SetStreamSource)
4. группируем чанки по их типу (уровень детализации и т.д.)
5. для каждой группы чанков:
    а. выставляем один раз индексный буфер этой группы
    б. рисуем все чанки из этой группы (DrawIndexedPrimitive с оффсетом)

6. смотрим на  ЪЪЪ картинку и радуемся высокому фпс и качеству ландшафта : )

#27
14:45, 14 окт. 2009

 L 
> чанков меняем типы индексных буферов и LOD (тупо номер записываем)

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


итого 1 чанки ланшафта - 1 DIP ?

#28
14:47, 14 окт. 2009

если кому интересно то вот моя функция - генерирует индексный буфер с LOD-ом и прореживает указанные стороны!
ох и намучался я с ней когдато.. нигде небыло исходников (даже теории не нашёл : (  )  пришлось исписать и исчетрить листов 15 принтерных  гыг

private IndexBuffer GenerateLOD(int chunkLength, Device device, int lodNumber, bool trimTop, bool trimBottom, bool trimLeft, bool trimRight)
        {
            int mNum = 1, Counter = 0;
            switch (lodNumber)
            {
                case 1:
                    mNum = 1;
                    break;
                case 2:
                    mNum = 2;
                    break;
                case 3:
                    mNum = 4;
                    break;
                case 4:
                    mNum = 8;
                    break;
            }
            IndexBuffer _ib = new IndexBuffer(device, (chunkLength / mNum) * (chunkLength / mNum) * 6 * sizeof(int), Usage.WriteOnly, Pool.Default, false);
            int[] Indices = new int[(chunkLength / mNum) * (chunkLength / mNum) * 6];
            for (int i = 0; i < chunkLength / mNum; i++)
            {
                for (int j = 0; j < chunkLength / mNum; j++)
                {
                    Indices[Counter] = Convert.ToInt32((i + 1) * (TerrainWidth + 1) * mNum + j * mNum);
                    Counter += 1;
                    Indices[Counter] = Convert.ToInt32(i * (TerrainWidth + 1) * mNum + j * mNum);
                    Counter += 1;

                    Indices[Counter] = Convert.ToInt32(i * (TerrainWidth + 1) * mNum + (j + 1) * mNum);
                    Counter += 1;


                    Indices[Counter] = Convert.ToInt32((i + 1) * (TerrainWidth + 1) * mNum + j * mNum);
                    Counter += 1;
                    Indices[Counter] = Convert.ToInt32(i * (TerrainWidth + 1) * mNum + (j + 1) * mNum);
                    Counter += 1;

                    Indices[Counter] = Convert.ToInt32((i + 1) * (TerrainWidth + 1) * mNum + (j + 1) * mNum);
                    Counter += 1;

                }
            }

            //-----------------LOD trimmers----------------------------

            //trim top corner
            if (trimTop)
            {
                for (int i = 0; i < (chunkLength / mNum); i++)
                {
                    if ((int)((float)((i + 1) / 2f)) == (float)((i + 1) / 2f))
                    {
                        //чётная
                        Indices[i * chunkLength / mNum * 6 + 0] = 0;
                        Indices[i * chunkLength / mNum * 6 + 1] = 0;
                        Indices[i * chunkLength / mNum * 6 + 2] = 0;
                    }
                    else
                    {
                        Indices[i * chunkLength / mNum * 6 + 3] = Indices[(i + 1) * chunkLength / mNum * 6 + 3];
                        if (trimLeft == true)
                        {
                            if (i != 0)
                                Indices[i * chunkLength / mNum * 6 + 4] -= (short)(mNum);
                            else
                                Indices[i * chunkLength / mNum * 6 + 0] -= (short)(mNum);
                        }
                        else
                        {
                            Indices[i * chunkLength / mNum * 6 + 4] -= (short)(mNum);
                        }
                        Indices[i * chunkLength / mNum * 6 + 0] += (short)(mNum);
                    }
                }
            }

            //trim bottom corner
            if (trimBottom)
            {
                for (int i = 0; i < (chunkLength / mNum); i++)
                {
                    if ((int)((float)((i + 1) / 2f)) == (float)((i + 1) / 2f))
                    {
                        //чётная
                        Indices[(i + 1) * (chunkLength / mNum) * 6 - 6 + 0] = 0;
                        Indices[(i + 1) * (chunkLength / mNum) * 6 - 6 + 1] = 0;
                        Indices[(i + 1) * (chunkLength / mNum) * 6 - 6 + 2] = 0;
                        Indices[(i + 1) * (chunkLength / mNum) * 6 - 6 + 4] -= (short)mNum;
                    }
                    else
                    {
                        Indices[(i + 1) * (chunkLength / mNum) * 6 - 6 + 5] = Indices[(i + 2) * (chunkLength / mNum) * 6 - 6 + 5];
                    }
                }

            }
            int offset = (chunkLength / mNum) * ((chunkLength / mNum) - 1) * 6;
            if (trimRight)
            {
                //Trim right corner
                
                for (int i = 1; i < (chunkLength / mNum) + 1; i++)
                {
                    if ((int)((float)i / 2f) == (float)i / 2f)
                    {
                        //чётная
                        Indices[offset + (i - 1) * 6 + 0] += (short)(mNum);
                        Indices[offset + (i - 1) * 6 + 3] = 0;
                        Indices[offset + (i - 1) * 6 + 4] = 0;
                        Indices[offset + (i - 1) * 6 + 5] = 0;
                    }
                    else
                    {
                        Indices[offset + (i - 1) * 6 + 5] += (short)(mNum);
                    }
                }
            }
            if (trimLeft)
            {
                //Trim left corner
                offset = (chunkLength / mNum) * 6;
                for (int i = 1; i < (chunkLength / mNum) + 1; i++)
                {
                    if ((int)((float)i / 2f) == (float)i / 2f)
                    {
                        Indices[(i - 1) * 6 + 0] = 0;
                        Indices[(i - 1) * 6 + 1] = 0;
                        Indices[(i - 1) * 6 + 2] = 0;
                    }
                    else
                    {
                        Indices[(i - 1) * 6 + 0] += (short)(mNum);
                        Indices[(i - 1) * 6 + 2] += (short)(mNum);
                        Indices[(i - 1) * 6 + 4] -= (short)(mNum);
                    }

                }
            }
            //_ib.SetData(Indices, 0, LockFlags.None);
            _ib.Lock(0, Indices.Length * sizeof(int), LockFlags.None).WriteRange<int>(Indices);
            _ib.Unlock();
            return _ib;
           
        }

#29
14:49, 14 окт. 2009

innuendo
> итого 1 чанки ланшафта - 1 DIP ?
так и естьinnuendo
> а вот эти типы индексных буферов как считаешь, сколько там комбинаций ?
на 1 LOD - 9 комбинаций!  тоесть или нормальный или с прорежеными сторонами.

innuendo
> а случай, когда камера как бы падает строго по направлению Z ( смотрит строго
> вниз и вниз перемещается ) работает ?
ну да, конечно : )

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

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