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

OpenGL Вопросы (4 стр)

Страницы: 13 4 5 697 Следующая »
#45
9:53, 10 ноя 2014

MrShoor
Там по ссылкам приведены формулы, они работают вне зависимости от d3dx.

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

И учи матчасть. Что такое кеш процессора и чем опасен кеш мисс.
Ты лишними проверками можешь создать нагрузку больше чем убрав их.

innuendo
Я же говорю это сложная тема, к ней нельзя подходить топорно. Там нужно весь код смотреть. По коду автора скорее всего его проверка действительно даст прирост поскольку у него довольно тяжелый апдейт

#46
10:11, 10 ноя 2014

Стас
> Там по ссылкам приведены формулы, они работают вне зависимости от d3dx.
> И открой уже для себя wvp преобразование. То, что ты можешь работать в каком то пространстве это не значит что его нельзя изменить.
Еще раз. В DX захардкожен клипспейс XY ∈ [-1;1] и Z ∈ [0;1]. Изменить ты его не можешь (Scissor не в счет, т.к. он не изменяет, а дополнительно клипает). Ты сейчас утверждаешь, что это не так?

> И учи матчасть. Что такое кеш процессора и чем опасен кеш мисс.
> Ты лишними проверками можешь создать нагрузку больше чем убрав их.
glMatrixLoad/glUniform/IDirect3DDevice9::SetTransform будет на порядки ( это *10^k ) дороже проверки флага с кешмиссом.

#47
10:13, 10 ноя 2014

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

#48
10:20, 10 ноя 2014

Стас
Да с чего ты взял, что у меня апдейт тяжелый? Это ТОЛЬКО пересчет матрицы на основе позиции, вращения и размера. Там больше ничего нет. Весь код Update() я выложил в первопосте, причем в самом тяжелом варианте - когда запрашивается инверсная матрица. Запрос матрицы идет каждый кадр, после чего она перемножается с матрицами камеры и передается в юниформ. Что еще такого может быть в моем коде особенного, что повлияет на способность dirty ускорить/замедлить выполнение?
bazhenovc
Это как, матрица в константы?

#49
11:13, 10 ноя 2014

bazhenovc
> Мы сейчас спорим о двух совершенно разных вещах. Автор уже сказал, что матрица
> сразу в константы не устанавливается, так что ты ошибся.
Ну да, я же уже посоветовал автору не пихать стейты если матрица не поменялась.

Dampire
> Это как, матрица в константы?
Это когда ты делаешь:
> Матрицу передаю в шейдер.

#50
11:17, 10 ноя 2014

MrShoor
> Еще раз. В DX захардкожен клипспейс XY ∈ [-1;1] и Z ∈ [0;1]. Изменить ты его не
> можешь (Scissor не в счет, т.к. он не изменяет, а дополнительно клипает). Ты
> сейчас утверждаешь, что это не так?

Мы говорим об одном и том же походу, после wvp преобразования, координаты как раз и будут в этой системе,
но до этого преобразования они могут быть в какой угодно.

MrShoor
> glMatrixLoad/glUniform/IDirect3DDevice9::SetTransform будет на порядки ( это
> *10^k ) дороже проверки флага с кешмиссом.
У тебя все объекты находятся в одних и тех же координатах? Если нет, то эта проверка не имеет абсолютно ни какого смысла.
Поскольку она только проверяет что матрица не была изменена, но не проверяет необходимость, выставить новую матрицу,
если ты рисуешь хотя бы 2 объекта с разными матрицами, то ты безусловно будешь выставлять новую матрицу, для каждого объекта
вне зависимости изменилась она или нет.

Dampire
> Да с чего ты взял, что у меня апдейт тяжелый?
В смысле тяжелый чтобы не грузиться кеш миссом. В тех оптимизациях о которых говорил bazhenovc убрать иф дает прирост только, если
время затраченное на работу с кешем будет больше выполнения самой операции. В твоем случае у тебя в апдейте выполняется
несколько умножений + инверсия, + еще проверка. Это довольно тяжелые операции, и суммарно, они скорее всего обойдутся дороже перегрузки кеша.

#51
11:32, 10 ноя 2014

Стас
> если ты рисуешь хотя бы 2 объекта с разными матрицами, то ты безусловно будешь
> выставлять новую матрицу, для каждого объекта
> вне зависимости изменилась она или нет.
Совсем не обязательно. Это может быть например общая трансформация для группы объектов. А если даже и нет - то для всех объектов я могу складывать матрицы в один буфер. Тогда перед отрисовкой объекта надо будет выставить этот буфер, и брать матрицы из него. В DX11 например уже есть оффсеты по константным буферам.

#52
11:55, 10 ноя 2014

MrShoor
Я вообще не вкурил. Что и куда я не должен пихать?

void MeshRenderer::Render(Camera *camera)
{
    glUseProgram(shader->program);
    glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
    glBindTexture(GL_TEXTURE_2D, texture->GetID());

    glEnableVertexAttribArray(shader->aPosition);
    glVertexAttribPointer(shader->aPosition, 3, GL_FLOAT, 0, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position));
    glEnableVertexAttribArray(shader->aUV);
    glVertexAttribPointer(shader->aUV, 2, GL_FLOAT, 0, sizeof(Vertex), (GLvoid*)offsetof(Vertex, uv));
    glm::mat4 tr = camera->GetProjection()  * camera->GetView() * _transform->GetWorldMatrix();
    glUniformMatrix4fv(shader->uTransform, 1, false, glm::value_ptr(tr));
    glUniform1i(shader->uTexture, 0);

    glDrawElements(GL_TRIANGLES, mesh->indices.size(), GL_UNSIGNED_INT, 0);

    glDisableVertexAttribArray(shader->aPosition);
    glDisableVertexAttribArray(shader->aUV);

    glUseProgram(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
}
#53
11:59, 10 ноя 2014

В GL есть UBO. На его основе я планирую инстансинг. Биндинг UBO как-бэ тоже стоит времени, причем поболе простого юниформа. И размеры UBO не бесконечны, навечно туда все статические юниформы не зальешь. Поправьте если не так.
Upd.
У меня не будет объектов с общим трансформом. Просто не будет. Я вообще не представляю как это возможно, и главное зачем. Мешпарты это один MeshRenderer, соответственно там вообще не надо повторно вызывать GetMatrix.

#54
12:06, 10 ноя 2014

Dampire
> camera->GetProjection() * camera->GetView()
А заранее это посчитать не судьба?
-1 умножение на отрисовке каждого объекта.

#55
12:17, 10 ноя 2014

Стас
Можно. Еще надо glUseProgram вынести за пределы рендерера и сортировать объекты по шейдеру. Тут еще можно кучу оптимизаций провести. Суть пока в Transform.

#56
12:22, 10 ноя 2014

Dampire
Попробуй удалить весь рендеринг, оставить только апдейт сущностей. Дальше померяй, сколько времени занимает апдейт 10 тысяч объектов. И вот от этого момента уже можно начинать плясать.

#57
12:55, 10 ноя 2014

10k маловато. Сделал 1kk

С dirty inverse матрица
4.410925
4.377917
4.373969

Без dirty inverse матрица
13.032024
12.884807
12.974728

С dirty прямая матрица
2.112842
2.124213
2.116378

Без dirty прямая матрица
6.287452
6.326793
6.163499

Интереса ради сделал UpdateMatrix не inline, и оно почему-то оказалось быстрее. Проверял дважды. Забавно.
6.179623
6.079405
6.072957

А вот что экономит убирание проверки на парента
5.957463
5.954906
5.958094

Код теста

    
    std::vector<Transform> trs;
    for(int i = 0; i < 1000000; i++)
    {
        trs.push_back(Transform());
    }
    double time = glfwGetTime();
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 1000000; j++)
        {
            trs[j].GetWorldMatrix();
        }
    }
    double tmp = glfwGetTime() - time;

    Debug->Log(std::to_string(tmp));
    return 0;
#58
13:01, 10 ноя 2014

Dampire
> Я вообще не вкурил. Что и куда я не должен пихать?
На свалку этот код. Ну я думаю ты понимаешь. Если десяток батчей рисовать - то покатит еще. Если надо максимум выжать, то:
1. glUseProgram вынести (ну ты знаешь уже)

2.

glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
    glEnableVertexAttribArray(shader->aPosition);
    glVertexAttribPointer(shader->aPosition, 3, GL_FLOAT, 0, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position));
    glEnableVertexAttribArray(shader->aUV);
    glVertexAttribPointer(shader->aUV, 2, GL_FLOAT, 0, sizeof(Vertex), (GLvoid*)offsetof(Vertex, uv));

объединить в VAO

3.

glUniformMatrix4fv(shader->uTransform, 1, false, glm::value_ptr(tr));
    glUniform1i(shader->uTexture, 0);

вынести в UBO, ну и перезаливать данные если они реально поменялись.
> Биндинг UBO как-бэ тоже стоит времени, причем поболе простого юниформа.
    glBindBufferRange тебе в помощь. Не хватает размера UBO, можно менеджить их, либо сложить все в обычный VBO и через glDrawElementsInstancedBaseVertexBaseInstance фигачить смещения.

4. Объединить все меши с одинаковым форматом вершин в один большой VBO, и биндить его вначале, а дальше через BaseVertex рисовать каждый меш.

#59
13:02, 10 ноя 2014

Ну и в догонку презентация вот: http://on-demand.gputechconf.com/gtc/2014/presentations/S4379-ope… echniques.pdf

Страницы: 13 4 5 697 Следующая »
ПрограммированиеФорумГрафика