• Я зарабатываю 100 000 RUB / месяц на этом сайте!

    А знаешь как? Я всего-лишь публикую (создаю темы), а админ мне платит. Трачу деньги на мороженое, робуксы и сервера в Minecraft. А ещё на паль из Китая. 

    Хочешь так же? Пиши и узнавай условия: https://t.me/alex_redact
    Реклама: https://t.me/yougame_official

Гайд Мысль - Оптимизация рендеринга заблюренных прямоугольников

Модератор раздела «Создание читов Minecraft»
Модератор
Модератор
Статус
Оффлайн
Регистрация
5 Июн 2025
Сообщения
555
Реакции
30
Это не то что-бы гайд, но не вешать тег совсем - нельзя.
Конструктивная критика - приветствуется и вообще супер, а пустой гундёж по возможности оставляйте при себе.

У меня в башке уже какое-то время висит мысля связанная и тем а как-же епт можно было бы оптимизировать рендеринг заблюренных квадратов в кубаче избегая прогонки шейдеров множество раз за кадр, и идея таки пришла
Нам понадобятся:
  • Прямые руки
  • Хоть какое-то более менее здоровое знание OpenGL (Фреймбуфферы)
  • Умение писать шейдеры - здорово (но если совсем туго, пиздить шейдеры тоже сойдёт)
На этом моменте детишки, пастеры и прочие гении мысли не попадающие под критерии выше могут расходится, т.к. дальше будет сложно, и настоящего кода НЕ БУДЕТ!

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

GLSL Blur Шейдер:
Expand Collapse Copy
#version 120
                                                       
uniform sampler2D textureIn;
uniform sampler2D textureOut;
uniform vec2 texelSize, direction;
// Крайне сомневаюсь что этот массив из 256 объектов передается через UBO/SSBO
// В общем ну такое
uniform float radius, weights[256];
                       
#define offset texelSize * direction
                       
void main() {
    vec2 uv = gl_TexCoord[0].st;
    uv.y = 1.0f - uv.y;
 
    float alpha = texture2D(textureOut, uv).a;
    if (direction.x == 0.0 && alpha == 0.0) {
        discard;
    }

    vec3 color = texture2D(textureIn, gl_TexCoord[0].st).rgb * weights[0];
    float totalWeight = weights[0];
 
    for (float f = 1.0; f <= radius; f++) {
        // `(weights[int(abs(f))` можно выполнять всего раз
        color += texture2D(textureIn, gl_TexCoord[0].st + f * offset).rgb * (weights[int(abs(f))]);
        color += texture2D(textureIn, gl_TexCoord[0].st - f * offset).rgb * (weights[int(abs(f))]);
                       
        totalWeight += (weights[int(abs(f))]) * 2.0;
    }
                       
    gl_FragColor = vec4(color / totalWeight, 1.0);
Дополнительно вкинул пару комментов на счет ранней оптимизации вроде использования UBO/SSBO для жирнющих объектов и экономии на кастах.

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

Absolute cinema рендеринг прямоугольников:
Expand Collapse Copy
public static void drawQuads(float x, float y, float width, float height) {
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);
    glVertex2f(x, y);
    glTexCoord2f(0, 1);
    glVertex2f(x, y + height);
    glTexCoord2f(1, 1);
    glVertex2f(x + width, y + height);
    glTexCoord2f(1, 0);
    glVertex2f(x + width, y);
    glEnd();
}
public static void drawQuadsBlur() {
    GL11.glBegin(GL11.GL_QUADS);
    GL11.glTexCoord2f(0, 1);
    GL11.glVertex2f(0, 0);
    GL11.glTexCoord2f(0, 0);
    GL11.glVertex2f(0, Math.max(window.getScaledHeight(), 1));
    GL11.glTexCoord2f(1, 0);
    GL11.glVertex2f(Math.max(window.getScaledWidth(), 1), Math.max(window.getScaledHeight(), 1));
    GL11.glTexCoord2f(1, 1);
    GL11.glVertex2f(Math.max(window.getScaledWidth(), 1), 0);
    GL11.glEnd();
}
public static void drawQuads() {
    float width =  mc.getMainWindow().getScaledWidth();
    float height =  mc.getMainWindow().getScaledHeight();
    glBegin(GL_QUADS);
    glTexCoord2f(0, 1);
    glVertex2f(0, 0);
    glTexCoord2f(0, 0);
    glVertex2f(0, height);
    glTexCoord2f(1, 0);
    glVertex2f(width, height);
    glTexCoord2f(1, 1);
    glVertex2f(width, 0);
    glEnd();
}

Здесь шикарно просто всё, начиная от того что нет отступов между методами, в 2 методах статик импорты методов LWJGL, в 1 из них они не используются, по какой-то причине текстурные координаты раньше вызываются чем вершинные(просто выглядит проклято), и самое сладенькое - использование легаси функционала в виде glBegin(...); glVertex(...); glTexCoord(...); glEnd()
Пожалуйста, авторизуйтесь для просмотра ссылки.
, и использование GL_QUADS
Пожалуйста, авторизуйтесь для просмотра ссылки.
Пожалуйста, авторизуйтесь для просмотра ссылки.
типа примитивов (Да, прямоугольники уже вроде как давно не в моде, примерно лет 20 как :goplol:)

Решение
Покушавши какашек в исходниках какого-то непонятно чего на основе чита Expensive, можно наконец-то перейти к решению!

Я это всё расписываю чисто что-б предложить попробовать реализовать альтернативный вариант рендеринга блюренных прямоугольников с 1 драв-коллом для блюра на фрейм (ого! бывает же!). Как-же это можно реализовать?
  1. Для начала, можно написать метод рендеринга прямоугольников на встроенных ресурсах майнкрафта (Tessellator, VertexBuilder, что там еще есть такое), либо свой метод с VBO/VAO (лишь бы легаси кода не было).
  2. Далее - наш первый свой фрейм буффер, назовём его Blur FBO, этот Blur FBO будет содержать заблюренную картинку экрана с 1 текстурой, из опыта формат текстуры скорее всего сойдёт за BGRA8 (но может быть и RGBA8), трафаретный буффер и буффер глубины нас не особо интересуют, но если вдруг с какой-то хуятины будет Z-Fighting при перезаписи ФБО, то лучше буффер глубины так-же добавить :0
  3. Далее, в какой-то момент (обычно нужный вам, это может быть post-world либо post-gui рендеринг, зависит от того хотите ли вы блюррить и гуишки тоже) нужно взять наш созданный Blur FBO, сделать его рендер таргетом (проще говоря - тупо применить как актуальный ФБО в который будет вестись запись), и нарисовать один прямоугольник размером с весь экран и текстурой ФБО майнкрафта где уже есть гуишки и прочая шляпа (и не забываем рендерить прямоугольник вверх-ногами, т.к. ФБО записываются вверх-ногами! :goplol:)
  4. На этом моменте не выдыхаем и пишем новый шейдер со специфической логикой и (несколькими) текстурой(-ами), в первый слот пихаем нашу текстуру из Blur FBO, во вторую - нужную вам текстуру, а может и вообще не нужно второй текстуры если квадрат - цветной. Изначально собираем цвет с заблюренной картинки, а после рисуем то что нам нужно с необходимой прозрачностью. Получается что-то вроде stencil-шейдера который вырезает кусок из уже существующего заблюренного экрана, вот и усё.

А вот теперь, самый подходящий(нет) момент для минусов такого подхода, а я вижу такой один - поскольку элементы отрендеренные таким образом не будут подвергаться блюру и рендеру в наш Blur FBO, пересечения будут выглядеть странно... Элемент сзади не будет виден на пересечении вообще (из-за рендеринга куска картинки из Blur FBO как основной слой без прозрачности, где заднего элемента из пересечения собсна нет).

С одной стороны это трагедия, и вот уже слышен вопли и возгласы сверепых пастеров о том что это решение - полная хуйня, однако есть 2 штуки: В некоторых моментах это можно обыграть спокойно и без особой мозгоёбки на манер того что элементы находятся на одном уровне и спокойно могут наезжать друг на друга полностью перекрывая друг друга.

Есть и альтернативное решение - рендерить объекты вроде всплывающих окон как и раньше, это всё еще будет плюсом из-за знатной экономии на том, что часть элементов не подвергается блюру напрямую, как-то так. (Есть и плюс, некоторые элементы вроде кнопок на заблюренных элементах трафаретным методом можно вообще не блюррить, т.к. у них в фоне уже находится элемент с блюром.

Вот как-то так, хуярьте свои мысли касательно такого подхода в комменты, может чего-то еще не учел.

P.S. В голове крутил вариант с использованием MRT-ФБО и до-записью новых элементов в этот фбо, но выглядеть оно будет странно, т.к. на пересечениях элементы прост не будут заблюренны, и выглядеть это будет - ИМХО, еще страннее
 
Последнее редактирование:
Назад
Сверху Снизу