- Статус
- Оффлайн
- Регистрация
- 5 Июн 2025
- Сообщения
- 555
- Реакции
- 30
Это не то что-бы гайд, но не вешать тег совсем - нельзя.
Конструктивная критика - приветствуется и вообще супер, а пустой гундёж по возможности оставляйте при себе.
У меня в башке уже какое-то время висит мысля связанная и тем а как-же епт можно было бы оптимизировать рендеринг заблюренных квадратов в кубаче избегая прогонки шейдеров множество раз за кадр, и идея таки пришла
Нам понадобятся:
В куче слитых читов на форуме используется одна и та-же тема - рендеринг каждого отдельного квадратика с блюром бэкграунда прям при рендере каждого отдельного квадратика. Не, это прикольно, только давайте рассмотрим пример такого шейдера:
Дополнительно вкинул пару комментов на счет ранней оптимизации вроде использования UBO/SSBO для жирнющих объектов и экономии на кастах.
В общем что можно заметить, это всё происходит при рендере каждого прямоугольника, докинуть до кучи абсолютно всратый код рендеринга прямоугольников реализованный в чите который я взял за пример - получаем ужасный перформанс при рендеринге.
Здесь шикарно просто всё, начиная от того что нет отступов между методами, в 2 методах статик импорты методов LWJGL, в 1 из них они не используются, по какой-то причине текстурные координаты раньше вызываются чем вершинные(просто выглядит проклято), и самое сладенькое - использование легаси функционала в виде
)
Я это всё расписываю чисто что-б предложить попробовать реализовать альтернативный вариант рендеринга блюренных прямоугольников с 1 драв-коллом для блюра на фрейм (ого! бывает же!). Как-же это можно реализовать?
А вот теперь, самый подходящий(нет) момент для минусов такого подхода, а я вижу такой один - поскольку элементы отрендеренные таким образом не будут подвергаться блюру и рендеру в наш Blur FBO, пересечения будут выглядеть странно... Элемент сзади не будет виден на пересечении вообще (из-за рендеринга куска картинки из Blur FBO как основной слой без прозрачности, где заднего элемента из пересечения собсна нет).
С одной стороны это трагедия, и вот уже слышен вопли и возгласы сверепых пастеров о том что это решение - полная хуйня, однако есть 2 штуки: В некоторых моментах это можно обыграть спокойно и без особой мозгоёбки на манер того что элементы находятся на одном уровне и спокойно могут наезжать друг на друга полностью перекрывая друг друга.
Есть и альтернативное решение - рендерить объекты вроде всплывающих окон как и раньше, это всё еще будет плюсом из-за знатной экономии на том, что часть элементов не подвергается блюру напрямую, как-то так. (Есть и плюс, некоторые элементы вроде кнопок на заблюренных элементах трафаретным методом можно вообще не блюррить, т.к. у них в фоне уже находится элемент с блюром.
Вот как-то так, хуярьте свои мысли касательно такого подхода в комменты, может чего-то еще не учел.
P.S. В голове крутил вариант с использованием MRT-ФБО и до-записью новых элементов в этот фбо, но выглядеть оно будет странно, т.к. на пересечениях элементы прост не будут заблюренны, и выглядеть это будет - ИМХО, еще страннее
Конструктивная критика - приветствуется и вообще супер, а пустой гундёж по возможности оставляйте при себе.
У меня в башке уже какое-то время висит мысля связанная и тем а как-же епт можно было бы оптимизировать рендеринг заблюренных квадратов в кубаче избегая прогонки шейдеров множество раз за кадр, и идея таки пришла
Нам понадобятся:
- Прямые руки
- Хоть какое-то более менее здоровое знание OpenGL (Фреймбуфферы)
- Умение писать шейдеры - здорово (но если совсем туго, пиздить шейдеры тоже сойдёт)
Проблема
Перед рассмотрением решения давайте посмотрим саму проблему:В куче слитых читов на форуме используется одна и та-же тема - рендеринг каждого отдельного квадратика с блюром бэкграунда прям при рендере каждого отдельного квадратика. Не, это прикольно, только давайте рассмотрим пример такого шейдера:
GLSL Blur Шейдер:
#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);
В общем что можно заметить, это всё происходит при рендере каждого прямоугольника, докинуть до кучи абсолютно всратый код рендеринга прямоугольников реализованный в чите который я взял за пример - получаем ужасный перформанс при рендеринге.
Absolute cinema рендеринг прямоугольников:
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 как 
Решение
Покушавши какашек в исходниках какого-то непонятно чего на основе чита Expensive, можно наконец-то перейти к решению!Я это всё расписываю чисто что-б предложить попробовать реализовать альтернативный вариант рендеринга блюренных прямоугольников с 1 драв-коллом для блюра на фрейм (ого! бывает же!). Как-же это можно реализовать?
- Для начала, можно написать метод рендеринга прямоугольников на встроенных ресурсах майнкрафта (Tessellator, VertexBuilder, что там еще есть такое), либо свой метод с VBO/VAO (лишь бы легаси кода не было).
- Далее - наш первый свой фрейм буффер, назовём его Blur FBO, этот Blur FBO будет содержать заблюренную картинку экрана с 1 текстурой, из опыта формат текстуры скорее всего сойдёт за BGRA8 (но может быть и RGBA8), трафаретный буффер и буффер глубины нас не особо интересуют, но если вдруг с какой-то хуятины будет Z-Fighting при перезаписи ФБО, то лучше буффер глубины так-же добавить :0
- Далее, в какой-то момент (обычно нужный вам, это может быть post-world либо post-gui рендеринг, зависит от того хотите ли вы блюррить и гуишки тоже) нужно взять наш созданный Blur FBO, сделать его рендер таргетом (проще говоря - тупо применить как актуальный ФБО в который будет вестись запись), и нарисовать один прямоугольник размером с весь экран и текстурой ФБО майнкрафта где уже есть гуишки и прочая шляпа (и не забываем рендерить прямоугольник вверх-ногами, т.к. ФБО записываются вверх-ногами!
)
- На этом моменте не выдыхаем и пишем новый шейдер со специфической логикой и (несколькими) текстурой(-ами), в первый слот пихаем нашу текстуру из Blur FBO, во вторую - нужную вам текстуру, а может и вообще не нужно второй текстуры если квадрат - цветной. Изначально собираем цвет с заблюренной картинки, а после рисуем то что нам нужно с необходимой прозрачностью. Получается что-то вроде stencil-шейдера который вырезает кусок из уже существующего заблюренного экрана, вот и усё.
А вот теперь, самый подходящий(нет) момент для минусов такого подхода, а я вижу такой один - поскольку элементы отрендеренные таким образом не будут подвергаться блюру и рендеру в наш Blur FBO, пересечения будут выглядеть странно... Элемент сзади не будет виден на пересечении вообще (из-за рендеринга куска картинки из Blur FBO как основной слой без прозрачности, где заднего элемента из пересечения собсна нет).
С одной стороны это трагедия, и вот уже слышен вопли и возгласы сверепых пастеров о том что это решение - полная хуйня, однако есть 2 штуки: В некоторых моментах это можно обыграть спокойно и без особой мозгоёбки на манер того что элементы находятся на одном уровне и спокойно могут наезжать друг на друга полностью перекрывая друг друга.
Есть и альтернативное решение - рендерить объекты вроде всплывающих окон как и раньше, это всё еще будет плюсом из-за знатной экономии на том, что часть элементов не подвергается блюру напрямую, как-то так. (Есть и плюс, некоторые элементы вроде кнопок на заблюренных элементах трафаретным методом можно вообще не блюррить, т.к. у них в фоне уже находится элемент с блюром.
Вот как-то так, хуярьте свои мысли касательно такого подхода в комменты, может чего-то еще не учел.
P.S. В голове крутил вариант с использованием MRT-ФБО и до-записью новых элементов в этот фбо, но выглядеть оно будет странно, т.к. на пересечениях элементы прост не будут заблюренны, и выглядеть это будет - ИМХО, еще страннее
Последнее редактирование: