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

::3D Software rendering contest [finished]:: (6 стр)

Advanced: Тема повышенной сложности или важная.

Страницы: 15 6 7 866 Следующая »
#75
12:24, 6 дек. 2009

Mikle
Уже готово, в понедельник выложу, а пока gprs не позволяет( Ты пока делай на Dx  новое задание.
А ты фильтрацию сделал?
Давно хотел спросить, а ты полность на барсике делаешь или все же с примесью асма? А то скорость уж больно высокая.

#76
12:45, 6 дек. 2009

Igor'
> не я щас решил сделать через Edge & Span,через этот метод который ты описал
> очень затратно(у меня так раньше и было),так что не советую...
нуу. мне больше нравится так ; )  + я за мего скоротью не гонюсь!

Vinil
> какой баундинг-бокс ? т.е, зачем он вообще при рендеринге ?
> барицентрические координаты и есть нормальный способ проверки. только зачем в
> данном случае проверять принадлежность точек треугольнику ???
лол  ты вообще такими координатами пользовался? xD  чтобы узнать, принадлежит ли точка к треугольнику, сначала нужно иметь саму точку!!  Вот я и нахожу BBox для трансформированного в экранные координаты триангла и сканирую каждую его точку, рассчитываю барицентрические координаты и через них проверяю, лежит ли точка в треугольнике.

просто очень много лишних рассчётов в местах бокса, где нету  треугольника : \

#77
12:47, 6 дек. 2009

Rean
> Давно хотел спросить, а ты полность на барсике делаешь или все же с примесью
> асма? А то скорость уж больно высокая.
предположу с вероятностью 99.999% что там ни какого асма.  Скорость вполне адекватная ИМХО.

#78
13:33, 6 дек. 2009

> Скорость вполне адекватная ИМХО
не, не, он определенно чего-то там намутил ) VB медленный как черепаха

#79
13:41, 6 дек. 2009

Mikle
> Fenix_alpha
> У тебя включение фильтрации сильно смещает текстурные координаты.
Возможно, хотя мне кажется что это из-за низкого разрешения текстуры. Хотелось бы увидеть демку с возможность переключения фильтрации текстур где не будет такого глюка.

#80
13:43, 6 дек. 2009

Fenix_alpha
А ты как фильтрацию делаешь?

У меня:

Function BiLinearColorInterpolation(lt,rt,lb,rb:TColor; cx,cy:single):TColor;
begin
  Result[0]:=trunc(lt[0]*(1-cx)*(1-cy)+rt[0]*cx*(1-cy) + lb[0]*(1-cx)*cy + rb[0]*cx*cy);
  Result[1]:=trunc(lt[1]*(1-cx)*(1-cy)+rt[1]*cx*(1-cy) + lb[1]*(1-cx)*cy + rb[1]*cx*cy);
  Result[2]:=trunc(lt[2]*(1-cx)*(1-cy)+rt[2]*cx*(1-cy) + lb[2]*(1-cx)*cy + rb[2]*cx*cy);
  Result[3]:=trunc(lt[3]*(1-cx)*(1-cy)+rt[3]*cx*(1-cy) + lb[3]*(1-cx)*cy + rb[3]*cx*cy);
end;

Function TTexture.GetColor(u, v: single):TColor;
var
  tx,ty:single;
begin
  tx:=frac(u)*FWidth-1;
  ty:=frac(v)*FHeight-1;
  case FFilter of
    TF_NEAREST:begin
      Result:=FColorBuffer[round(tx)+round(ty)*FWidth];
    end;
    TF_LINEAR:begin
      Result:=BiLinearColorInterpolation(FColorBuffer[trunc(tx)+trunc(ty)*FWidth],
                                         FColorBuffer[trunc(tx+1)+trunc(ty)*FWidth],
                                         FColorBuffer[trunc(tx)+trunc(ty+1)*FWidth],
                                         FColorBuffer[trunc(tx+1)+trunc(ty+1)*FWidth],
                                         frac(tx),frac(ty));
    end;
  end;
end;

#81
13:46, 6 дек. 2009

@!!ex
> А ты как фильтрацию делаешь?
Примерно так: http://ru.wikipedia.org/wiki/Билинейная_фильтрация

Я не вникал в твою процедуру, но мне кажется она не сильно оптимальна, учитывая что для каждого канала цвета происходит вычисление (1-cx)*(1-cy) - можно было посчитать один раз на тексель или хотя б (1-су) вынести за скобки. И switch в текстурной выборке в зависимости от типа фильтрации не есть гуд.

#82
13:54, 6 дек. 2009

@!!ex
>> буффер вывода делится на 4 части. Для каждоый части свой поток.
>> треугольник делится соотвественно тоже на 4 части.
>> каждый поток считает только ту часть треугольника, которая попадает в его зону
Я это и имел в виду. только у тебя CPU, поэтому "магическая константа" 4 может быть заменена на произвольную величину N. Конечно, если у тебя только один треугольник сейчас рендерится (в смысле, в как такового списка обработанных и отсечённых треугольников для растеризации нету), то сказанное мной не применимо.


L
>> лол ты вообще такими координатами пользовался? xD
Пользовался и даже в размерностях, выше чем 3 :)

>> чтобы узнать, принадлежит ли точка к треугольнику, сначала нужно иметь саму точку!!

>> Вот я и нахожу BBox для трансформированного в экранные координаты триангла и сканирую каждую его точку, рассчитываю барицентрические координаты и через них проверяю, лежит ли точка в треугольнике.
Я про это и подумал, что ты так делаешь. Только почему просто не побить спроецированный треугольник на скан-лайны, как делается всюду ? Ты же, как я понял, рендеришь 2D-квад (BBox), тратя кучу времени на обработку "пустых" точек этого квада.

>> просто очень много лишних рассчётов в местах бокса, где нету треугольника : \
Повторю - рендери треугольник, а не квад, чтобы все твои точки ему принадлежали.

Вот старое, но проверенное и простое объяснение  http://faqs.org.ru/progr/graph/dd3d.htm  Пункт 2.4  (или тут исходная html-версия  http://www.enlight.ru/faq3d/content.htm)

#83
14:16, 6 дек. 2009

Asteraceae
> не, не, он определенно чего-то там намутил )
ды может он просто юзает метод растеризации, более быстрый, чем у тебя ; )
AFAIK у него метод, когда треугольник делится на 2 горизонтально (верхний и нижний).и растеризуются..  там есть свои фишки. Эт самый быстрый AFAIK способ.

Fenix_alpha
> Хотелось бы увидеть демку с возможность переключения фильтрации текстур где не
> будет такого глюка.
моя демка на предыдущей странице с ландшафтом которая, в ней самый что ни на есть честный bilinear фильтр. Текстура тоже съезжает : )

Vinil
лол.  в моих демках в нулевом посте всё сделано сканлайнами.  И все предыдущие тоже.
Барицентрическими координатами я начал делать позавчера ; )  Мне так надо.

#84
14:20, 6 дек. 2009

 L 
> AFAIK у него метод, когда треугольник делится на 2 горизонтально (верхний и
> нижний).и растеризуются.. там есть свои фишки. Эт самый быстрый AFAIK способ.
Хм, а кто-то вообще делает по другому?

 L 
> Барицентрическими координатами я начал делать позавчера ; ) Мне так надо.
Если не секрет зачем? Быстрее или удобнее делать "шэйдеры"?

#85
14:22, 6 дек. 2009

Vinil
> Я про это и подумал, что ты так делаешь. Только почему просто не побить
> спроецированный треугольник на скан-лайны, как делается всюду ? Ты же, как я
> понял, рендеришь 2D-квад (BBox)
ну я не совсем прям так рендерю : \

сначала нахожу бокс

minX = (int)x1;
            if (x2 < minX) minX = (int)x2;
            if (x3 < minX) minX = (int)x3;

            maxX = (int)x1;
            if (x2 > maxX) maxX = (int)x2;
            if (x3 > maxX) maxX = (int)x3;

            minY = (int)y1;
            if (y2 < minY) minY = (int)y2;
            if (y3 < minY) minY = (int)y3;

            maxY = (int)y1;
            if (y2 > maxY) maxY = (int)y2;
            if (y3 > maxY) maxY = (int)y3;

            if (maxX < 0) return;
            if (maxY < 0) return;
            if (minX >= SCR_WIDTH) return;
            if (minY >= SCR_HEIGHT) return;
            if (minX < 0) minX = 0;
            if (maxX >= SCR_WIDTH) maxX = SCR_WIDTH - 1;
            if (minY < 0) minY = 0;
            if (maxY >= SCR_HEIGHT) maxY = SCR_HEIGHT - 1;
            
            Vector3 bary = new Vector3();

            float detA = 1.0f / ((x1 * y2) - (x1 * y3) - (x2 * y1) + (x2 * y3) + (x3 * y1) - (x3 * y2));

потом для каждой точки бокса проверяю

 for (int x = minX; x <= maxX; x++)
            {
                for (int y = minY; y <= maxY; y++)
                {
                    bary.X = (( x * y2) -  (x * y3) - (x2 * y)  + (x2 * y3) + (x3 * y) - (x3 * y2)) * detA;
                    bary.Y = ((x1 * y)  - (x1 * y3) -  (x * y1) +  (x * y3) + (x3 * y1) - (x3 * y)) * detA;
                    bary.Z = ((x1 * y2) - (x1 * y) -  (x2 * y1) + (x2 * y)  +  (x * y1) - (x * y2)) * detA;
                    
                    if (bary.X >= 0 && bary.Y >= 0 && bary.Z >= 0)
                    {
                            //тут выполняется интерполяция регистров типа:
                            for (int i = 1; i < 8; i++)
                                {

                                    ElementType type = vOutput.e1[i].Type;
                                    switch (type)
                                    {
                                        case ElementType.Float1:
                                            psinput[i].Type = type;
                                            psinput[i].x = vOutput.e1[i].x * bary.X + vOutput.e2[i].x * bary.Y + vOutput.e3[i].x * bary.Z;
                                            break;
                                        case ElementType.Float2:
                                            psinput[i].Type = type;
                                            psinput[i].x = vOutput.e1[i].x * bary.X + vOutput.e2[i].x * bary.Y + vOutput.e3[i].x * bary.Z;
                                            psinput[i].y = vOutput.e1[i].y * bary.X + vOutput.e2[i].y * bary.Y + vOutput.e3[i].y * bary.Z;
                                            break;
                                        case ElementType.Float3:
                                            psinput[i].Type = type;
                                            psinput[i].x = vOutput.e1[i].x * bary.X + vOutput.e2[i].x * bary.Y + vOutput.e3[i].x * bary.Z;
                                            psinput[i].y = vOutput.e1[i].y * bary.X + vOutput.e2[i].y * bary.Y + vOutput.e3[i].y * bary.Z;
                                            psinput[i].z = vOutput.e1[i].z * bary.X + vOutput.e2[i].z * bary.Y + vOutput.e3[i].z * bary.Z;
                                            break;
                                        case ElementType.Float4:
                                            psinput[i].Type = type;
                                            psinput[i].x = vOutput.e1[i].x * bary.X + vOutput.e2[i].x * bary.Y + vOutput.e3[i].x * bary.Z;
                                            psinput[i].y = vOutput.e1[i].y * bary.X + vOutput.e2[i].y * bary.Y + vOutput.e3[i].y * bary.Z;
                                            psinput[i].z = vOutput.e1[i].z * bary.X + vOutput.e2[i].z * bary.Y + vOutput.e3[i].z * bary.Z;
                                            psinput[i].w = vOutput.e1[i].w * bary.X + vOutput.e2[i].w * bary.Y + vOutput.e3[i].w * bary.Z;
                                            break;

                                    }
                                }
                    }
                    // а дальше выполняется фрагментный шейдер
}
}

#86
14:24, 6 дек. 2009

Fenix_alpha
> Хм, а кто-то вообще делает по другому?
Мона не бить на 2 а просто растеризовать 1 треугольник, что тоже самое, только медленней.  Я так изначально делал : )

Fenix_alpha
> Если не секрет зачем? Быстрее или удобнее делать "шэйдеры"?
это немного медленней. И да, 1 из факторов - что шейдеры делать удобнее  :  )  кста, по секрету, сча делаю ShadowMapping.

#87
14:39, 6 дек. 2009

L
>> ну я не совсем прям так рендерю : \
По ходу, ты совсем прям так и рендеришь :)  Всё, что тебе надо тут сделать - это перебор y от minY до maxY и вычисление minX и maxX на каждой линии, а не использование глобальных minX/maxX.

Первое, что бросилось в глаза (спасибо за код) - цикл сначала по x, потом по y. Значит, смотри. Ты посчитал psinput, выполнил фраг. шейдер, потом записываешь результат в точку фрейм-буфера (x,y). И тут тоже теряешь такты из-за лишних вычислений смещения (y*SCR_WIDTH + x). При переборе сначала по y ты можешь вычислить только одно смещение в начале каждого скан-лайна, которое потом (в цикле по x) просто инкрементировать.

#88
14:56, 6 дек. 2009

Rean
> а ты полность на барсике делаешь или все же с примесью асма? А то скорость уж
> больно высокая.
Чистый VB6, если не считать копирования памяти с помощью API (ну нет в VB6 memcpy). А скорость - алгоритмы рулят.
Asteraceae
> не, не, он определенно чего-то там намутил ) VB медленный как черепаха
Ошибаешься, примерно такой же, как vb.net, шарп или дельфи. Плюса, конечно, быстрее.
Fenix_alpha
> Хотелось бы увидеть демку с возможность переключения фильтрации текстур где не
> будет такого глюка.
У меня нет глюка, качай новую демку.

#89
18:13, 6 дек. 2009

@!!ex

> Function BiLinearColorInterpolation(lt,rt,lb,rb:TColor; cx,cy:single):TColor;
> begin
>   Result[0]:=trunc(lt[0]*(1-cx)*(1-cy)+rt[0]*cx*(1-cy) + lb[0]*(1-cx)*cy +
> rb[0]*cx*cy);
>   Result[1]:=trunc(lt[1]*(1-cx)*(1-cy)+rt[1]*cx*(1-cy) + lb[1]*(1-cx)*cy +
> rb[1]*cx*cy);
>   Result[2]:=trunc(lt[2]*(1-cx)*(1-cy)+rt[2]*cx*(1-cy) + lb[2]*(1-cx)*cy +
> rb[2]*cx*cy);
>   Result[3]:=trunc(lt[3]*(1-cx)*(1-cy)+rt[3]*cx*(1-cy) + lb[3]*(1-cx)*cy +
> rb[3]*cx*cy);
> end;

о жесть какая :) SSE явно плачет, что его тут не применяют :)

Страницы: 15 6 7 866 Следующая »
ПрограммированиеФорумГрафика

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