Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / OpenGL Вопросы (4 стр)

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

Поделиться

Страницы: 1 2 3 4 5 6 ... 13 ... 21 22 23 Следующая

СтасПостоялецwww10 ноя. 20149:53#45
MrShoor
Там по ссылкам приведены формулы, они работают вне зависимости от d3dx.

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

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

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

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

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

Правка: 10 ноя. 2014 10:11

bazhenovcУдалёнwww10 ноя. 201410:13#47
MrShoor
> Да хоть 8 кешмиссов, главное, чтобы этот флаг позволил мне избежать установки
> на конвеер.
Мы сейчас спорим о двух совершенно разных вещах. Автор уже сказал, что матрица сразу в константы не устанавливается, так что ты ошибся.
DampireПостоялецwww10 ноя. 201410:20#48
Стас
Да с чего ты взял, что у меня апдейт тяжелый? Это ТОЛЬКО пересчет матрицы на основе позиции, вращения и размера. Там больше ничего нет. Весь код Update() я выложил в первопосте, причем в самом тяжелом варианте - когда запрашивается инверсная матрица. Запрос матрицы идет каждый кадр, после чего она перемножается с матрицами камеры и передается в юниформ. Что еще такого может быть в моем коде особенного, что повлияет на способность dirty ускорить/замедлить выполнение?
bazhenovc
Это как, матрица в константы?

Правка: 10 ноя. 2014 10:21

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

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

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

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

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

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

Правка: 10 ноя. 2014 11:41

MrShoorУчастникwww10 ноя. 201411:32#51
Стас
> если ты рисуешь хотя бы 2 объекта с разными матрицами, то ты безусловно будешь
> выставлять новую матрицу, для каждого объекта
> вне зависимости изменилась она или нет.
Совсем не обязательно. Это может быть например общая трансформация для группы объектов. А если даже и нет - то для всех объектов я могу складывать матрицы в один буфер. Тогда перед отрисовкой объекта надо будет выставить этот буфер, и брать матрицы из него. В DX11 например уже есть оффсеты по константным буферам.
DampireПостоялецwww10 ноя. 201411:55#52
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);
}
DampireПостоялецwww10 ноя. 201411:59#53
В GL есть UBO. На его основе я планирую инстансинг. Биндинг UBO как-бэ тоже стоит времени, причем поболе простого юниформа. И размеры UBO не бесконечны, навечно туда все статические юниформы не зальешь. Поправьте если не так.
Upd.
У меня не будет объектов с общим трансформом. Просто не будет. Я вообще не представляю как это возможно, и главное зачем. Мешпарты это один MeshRenderer, соответственно там вообще не надо повторно вызывать GetMatrix.

Правка: 10 ноя. 2014 12:03

СтасПостоялецwww10 ноя. 201412:06#54
Dampire
> camera->GetProjection() * camera->GetView()
А заранее это посчитать не судьба?
-1 умножение на отрисовке каждого объекта.
DampireПостоялецwww10 ноя. 201412:17#55
Стас
Можно. Еще надо glUseProgram вынести за пределы рендерера и сортировать объекты по шейдеру. Тут еще можно кучу оптимизаций провести. Суть пока в Transform.
bazhenovcУдалёнwww10 ноя. 201412:22#56
Dampire
Попробуй удалить весь рендеринг, оставить только апдейт сущностей. Дальше померяй, сколько времени занимает апдейт 10 тысяч объектов. И вот от этого момента уже можно начинать плясать.
DampireПостоялецwww10 ноя. 201412:55#57
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;

MrShoorУчастникwww10 ноя. 201413:01#58
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 рисовать каждый меш.

MrShoorУчастникwww10 ноя. 201413:02#59
Ну и в догонку презентация вот: http://on-demand.gputechconf.com/gtc/2014/presentations/S4379-ope… echniques.pdf

Страницы: 1 2 3 4 5 6 ... 13 ... 21 22 23 Следующая

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

2001—2017 © GameDev.ru — Разработка игр