Войти
ФлеймФорумПрограммирование

Software rendering (6 стр)

Страницы: 15 6 7 8 9 Следующая »
#75
17:28, 10 апр. 2019

Не гнаться за универсальностью. Для каждого набора эффектов лучшее решение может вообще иметь принципиально другую архитектуру.


#76
19:55, 10 апр. 2019

FordPerfect
> Возникает мысль, что сами барицентрические координаты нам, обычно, не особо нужны.
Тут у тебя либо 3 интерполятора и 2 + 2N MAD в шейдере, либо N + 1 интерполятор и N умножений в шейдере.
В общем, если MAD доступен, то примерно одинаково по скорости, а если нет, то барицентрические координаты сливают.

На мой взгляд, тебе надо пилить универсальный интерполятор, который берет пачку троек и интерполирует. А в шейдер уже идет результат. Т. е. вызов растеризатора, затем цикл по интерполяторам, затем вызов шейдера от квадрата пикселей. И квадрат сделай побольше, x4 — это ниочем.

#77
21:54, 10 апр. 2019

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

#78
21:54, 10 апр. 2019

Предыдущая демка была больше про картинку и fillrate.
Вот эта о зависимости от числа треугольников и пикселей.
Просмотрщик .obj (только геометрия, без текстур):
viewobj
Понимает drag-n-drop (.obj файлов).
Управление по F1.

Можете дать ему .obj пожирнее (спонзу там, или Stanford dragon) и запостить скриншот, сколько показывает?
В SIMD и без. И как зависит от расстояния (площади пикселей).
Ну и вообще зависимость от количества треугольников.

Это однопоток.
В Triangle setup пишет 0, потому что он сейчас объединён с Rasterization+shading.

#79
22:57, 10 апр. 2019

1 frag / 2 deaths
> Для каждого набора эффектов лучшее решение может вообще иметь принципиально другую архитектуру.
Так-то да. Для некоторых вещей вообще формулировать их в терминах треугольников - не лучшее решение.
Но вообще, такая растеризация треугольников, ИМХО, покрывает большой набор полезной функциональности. Так что, почему бы и нет?
Общность не факт, что мешает. Раз у нас всё-равно треугольники - так определить, какие пиксели покрыты всё-равно в каком-то виде надо. Отдельная функция, которая не интересуется, что с этими пикселями будут дальше делать - вполне себе решение.

}:+()___ [Smile]
> Тут у тебя либо 3 интерполятора и 2 + 2N MAD в шейдере, либо N + 1 интерполятор и N умножений в шейдере.
Там ещё размер данных. Сейчас 16 байт на пиксель, а с (x,y,mask) можно в 4 байта ужать.
> На мой взгляд, тебе надо пилить универсальный интерполятор, который берет пачку троек и интерполирует.
Интегрировано с растеризатором - стрёмно. Т. к. опять теряем единую точку входа, плюс регистров нерезиново (особенно на 32-битном x86, and yes, I care).
> Т. е. вызов растеризатора, затем цикл по интерполяторам, затем вызов шейдера от квадрата пикселей.
Гм, так после растеризатора там же прошедшие пиксели неподряд, и интерполятор перестаёт быть тупо инкрементом.

> И квадрат сделай побольше, x4 — это ниочем.
Это же тупо размер SSE регистра? AVX прикрутить? Можно, но обкатать охота на SSE.
Или ты предлагаешь большой квадрат делать, больше регистра? А поинт?
Хотя, к слову, забавное: я когда сделал SSE версию rasterize_x4, решил для общности сделать и скалярную её реализацию (на FPU). Тупо обрабатывая по 4 пикселя по-очереди. Так вот она оказалась чуть быстрее попиксельной версии (rasterize). На какие-то единицы процентов, но - быстрее.

#80
23:00, 10 апр. 2019

Vlad2001_MFS
Написать ассемблероподобный язык и его компилятор (JIT?) - прикольное (и полезное в учебных целях) дело.
Но польза в контексте именно софтрендера неочевидна - шейдеры же можно прямо на том же C++ и писать.

#81
(Правка: 23:22) 23:19, 10 апр. 2019

FordPerfect
Ну так я и не расчитываю на пользу. Все ради интереса, но, к сожалению, не сейчас.
Появилась небольшая идея для игры - пробую воплотить в жизнь. Правда, 2D софтрендером все равно занимаюсь, так как это часть движка.

Как делать JIT'ы, оптимизации я не в курсе. А вот простейший ассемблероподобный язык с виртуальной малиной и компилятором в байткод я писал как-то. Потом даже начал писать простой вычислительный язык на основе этого ассемблера.

#82
23:33, 10 апр. 2019

FordPerfect
> Там ещё размер данных. Сейчас 16 байт на пиксель, а с (x,y,mask) можно в 4 байта ужать.
Это разве критично? Надо просто чтобы per triangle данные + данные для одного квадрата пикселей влезали в L1.

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

> Это же тупо размер SSE регистра? AVX прикрутить? Можно, но обкатать охота на SSE.
Это безотносительно SSE. Просто гранулярность работы, которая делается за раз, без лишних бранчей и прочего геморроя. Лично я, например, в своем растеризаторе шрифтов работал квадратами 8х8, что с SSE, что с AVX. Фиксированный размер пачки пикселей, например, позволяет четко подобрать требуемую точность интерполятора, предрассчитать параллельный инкремент на весь квадрат и т. п.

#83
0:30, 11 апр. 2019

}:+()___ [Smile]
> Это разве критично?
Depends. Если генерировать покрытие целиком для треугольника (как у меня) - да. Ну, впрочем, если работать тайлово (например, 64x64), там размер ограничен сверху.

> Это безотносительно SSE. Просто гранулярность работы
А, так-то у меня тоже работа с блоками 8x8, для больших треугольников. Для мелких (а их может быть дофига), оно, вроде, не стоит overhead'а.
Но выдаю на-гора я coverage для всего треугольника, а потом обрабатываю.

Ты предлагаешь для каждого квадрата 8x8 вызввать растеризатор->интерполятор->шейдер. Тоже подход, да.
Но 8x8, походу мелкая гранулярность, для такого подхода. Это всего 16 SSE-блоков (и 8 AVX).

Ну и, повторю, есть мелкие треугольники. Вот можешь демку выше запустить, и скормить ей Stanford dragon (или что-то ещё объёмное из https://casual-effects.com/data/ ). Такое чувство, что для мелких треугольников попиксельная версия заруливает.

Можешь всё-таки кодом набросать свой подход, примерно?

#84
0:35, 11 апр. 2019

> Можешь всё-таки кодом набросать свой подход, примерно?
Мой растеризатор выглядит так:
rasterize

#85
1:18, 11 апр. 2019

FordPerfect
> Для мелких (а их может быть дофига), оно, вроде, не стоит overhead'а.
Надо подобрать размер блоков так, чтобы было примерно одинаково.
Еще можно несколько гранулярностей ввести: например, 16х16 для растеризатора и 4х4 для шейдера.

> Но выдаю на-гора я coverage для всего треугольника, а потом обрабатываю.
Ну вот сразу рискуешь кешем для больших треугольников.

> Но 8x8, походу мелкая гранулярность, для такого подхода.
Тут надо экспериментировать, это да.
У меня было два размера: 8х8 и 16х16, но на втором происходила деградация точности интерполятора.

> Ну и, повторю, есть мелкие треугольники.
Мелкие треугольники — это удар по производительности даже на GPU.
Можно, конечно, попробовать делать компрессию списка пикселей после стадии интерполяции.
Но думаю, это будет иметь смысл только для тяжелых шейдеров, которые не для софтварного рендера, а для простых будет проще шпарить не глядя. Да и не должно быть слишком много мелких треугольников в правильно сделанной сцене.

> Вот можешь демку выше запустить
На моем линуксе не пойдет :)

> Можешь всё-таки кодом набросать свой подход, примерно?
Это когда будет свободное время.

#86
12:12, 11 апр. 2019

}:+()___ [Smile]
> но на втором происходила деградация точности интерполятора.
Если у тебя есть FMA (она вроде в ту же скорость, что и сложение), так вроде можно заметно точнее.
Вместо

simd8f A,DX,DY;
int id=0;
for(int y=0;y<16;y+=2)
{
    simd8f T=A;
    for(int x=0;x<16;x+=4)
    {
        output[id++]=T;
        T+=DX;
    }
    A+=DY;
}
пишем
simd8f A,DX,DY;
int id=0;
for(int y=0;y<16;y+=2)
{
    simd8f B=FMA(DY,LUTy[y/2],A);
    for(int x=0;x<16;x+=4)
    {
        simd8f C=FMA(DX,LUTx[x/4],B);
        output[id++]=C;
    }
}
где LUT это тупо [0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f], [1.f,1.f,1.f,1.f,1.f,1.f,1.f,1.f] и т. д..
Можно unroll.

Хз, будет ли оно в ту же скорость, но вроде возможно?

#87
14:20, 11 апр. 2019

FordPerfect
У меня другой интерполятор был, не стандартный.

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

В общем, мой псевдокод для растеризации треугольников:

+ Псевдокод

#88
8:47, 12 апр. 2019

FordPerfect

вот так у меня рендерится.
Изображение

1) у тебя неправильно считаются нормали для модели
2) если нужны модели для тестов - обращайся, есть как супер хайполи сканы так и сделанные мною лополи
3) ты можешь в двух словах обьяснить зачем софтварный рендер может быть нужен с практической точки зрения? Я вижу только одно применение - использовать его в cad пакетах или в софте для моделирования\анимации . Я так понимаю , при софтварном рендере можно честно и правильно рендерить полупрозрачную геометрию? ( без багов с сортировкой)

#89
(Правка: 8:55) 8:55, 12 апр. 2019

на больших обжах фпс драматически падает.
Изображение

Страницы: 15 6 7 8 9 Следующая »
ФлеймФорумПрограммирование