Необходимо создать класс для применения размытия с...

Erstellt am: 20. Februar 2025

Beantwortet mit O1 von Chat01

Frage

Необходимо создать класс для применения размытия с использованием предоставленных шейдеров. В качестве примера, я предоставлю класс KawaseBlur, чтобы вы лучше поняли структуру проекта.

Создайте новый класс для размытия, используя предоставленные шейдеры.

Убедитесь, что новый класс соответствует структуре проекта.

Используйте класс KawaseBlur в качестве примера для создания нового класса. вот шейдеры package cc.luminous.utils.shader.shaders;

import cc.luminous.utils.shader.IShader;

public class BlurUp implements IShader {

text
@Override public String glsl() { return """ #version 120 uniform sampler2D image; uniform float offset; uniform vec2 resolution; void main() { vec2 uv = gl_TexCoord[0].xy / 2.0; vec2 halfpixel = resolution / 2.0; vec3 sum = texture2D(image, uv + vec2(-halfpixel.x * 2.0, 0.0) * offset).rgb; sum += texture2D(image, uv + vec2(-halfpixel.x, halfpixel.y) * offset).rgb * 2.0; sum += texture2D(image, uv + vec2(0.0, halfpixel.y * 2.0) * offset).rgb; sum += texture2D(image, uv + vec2(halfpixel.x, halfpixel.y) * offset).rgb * 2.0; sum += texture2D(image, uv + vec2(halfpixel.x * 2.0, 0.0) * offset).rgb; sum += texture2D(image, uv + vec2(halfpixel.x, -halfpixel.y) * offset).rgb * 2.0; sum += texture2D(image, uv + vec2(0.0, -halfpixel.y * 2.0) * offset).rgb; sum += texture2D(image, uv + vec2(-halfpixel.x, -halfpixel.y) * offset).rgb * 2.0; gl_FragColor = vec4(sum / 12.0, 1); } """; }

}
package cc.luminous.utils.shader.shaders;

import cc.luminous.utils.shader.IShader;

public class BlurDown implements IShader {

text
@Override public String glsl() { return """ #version 120 uniform sampler2D image; uniform float offset; uniform vec2 resolution; void main() { vec2 uv = gl_TexCoord[0].xy * 2.0; vec2 halfpixel = resolution * 2.0; vec3 sum = texture2D(image, uv).rgb * 4.0; sum += texture2D(image, uv - halfpixel.xy * offset).rgb; sum += texture2D(image, uv + halfpixel.xy * offset).rgb; sum += texture2D(image, uv + vec2(halfpixel.x, -halfpixel.y) * offset).rgb; sum += texture2D(image, uv - vec2(halfpixel.x, -halfpixel.y) * offset).rgb; gl_FragColor = vec4(sum / 8.0, 1); } """; }

}
и класс kawase как пример package cc.luminous.utils.render;

import cc.luminous.utils.CustomFramebuffer;
import cc.luminous.utils.shader.ShaderUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.client.shader.Framebuffer;

public class KawaseBlur {

text
public static KawaseBlur blur = new KawaseBlur(); public final CustomFramebuffer BLURRED; public final CustomFramebuffer ADDITIONAL; CustomFramebuffer blurTarget = new CustomFramebuffer(false).setLinear(); public KawaseBlur() { BLURRED = new CustomFramebuffer(false).setLinear(); ADDITIONAL = new CustomFramebuffer(false).setLinear(); } public void render(Runnable run) { Stencil.initStencilToWrite(); run.run(); Stencil.readStencilBuffer(1); BLURRED.draw(); Stencil.uninitStencilBuffer(); } public void updateBlur(float offset, int steps) { Minecraft mc = Minecraft.getInstance(); Framebuffer mcFramebuffer = mc.getFramebuffer(); ADDITIONAL.setup(); mcFramebuffer.bindFramebufferTexture(); ShaderUtil.kawaseDown.attach(); ShaderUtil.kawaseDown.setUniform("offset", offset); ShaderUtil.kawaseDown.setUniformf("resolution", 1f / mc.getMainWindow().getWidth(), 1f / mc.getMainWindow().getHeight()); CustomFramebuffer.drawTexture(); CustomFramebuffer[] buffers = {this.ADDITIONAL, this.BLURRED }; for (int i = 1; i < steps; ++i) { int step = i % 2; buffers[step].setup(); buffers[(step + 1) % 2].draw(); } ShaderUtil.kawaseUp.attach(); ShaderUtil.kawaseUp.setUniform("offset", offset); ShaderUtil.kawaseUp.setUniformf("resolution", 1f / mc.getMainWindow().getWidth(), 1f / mc.getMainWindow().getHeight()); for (int i = 0; i < steps; ++i) { int step = i % 2; buffers[(step + 1) % 2].setup(); buffers[step].draw(); } ShaderUtil.kawaseUp.detach(); mcFramebuffer.bindFramebuffer(false); }

}
пиши полный код без примеров напиши шедевр

Gedanke

Crafting a blur effect

I’m pulling together a new blur effect class, using shaders like blurDown and blurUp. Drawing from KawaseBlur's approach, the class may be called DoubleBlur or CustomBlur.

Crafting blur effects

I’m forming a blur class similar to KawaseBlur, using blurDown and blurUp shaders. Dual custom framebuffers manage blurring steps efficiently.

Formulating blur effects

I'm aligning the blur class to use blurDown and blurUp shaders, mirroring KawaseBlur's logic. This includes defining an instance, custom framebuffers, and methods for rendering and updating blur.

Crafting blur effects

I’m working through using "ShaderUtil.blurDown" and "ShaderUtil.blurUp" to replicate KawaseBlur's approach, tweaking a class name this time to "BlurEffect" for clarity.

Integrating blur effects

I’m finalizing "BlurEffect" by connecting shaders like "ShaderUtil.blurDown" and "ShaderUtil.blurUp," adding doc comments in Russian, and constructing the "render" and "updateBlur" methods to complete the code.

Reasoned for 14 seconds

Antwort

java
package cc.luminous.utils.render; import cc.luminous.utils.CustomFramebuffer; import cc.luminous.utils.shader.ShaderUtil; import net.minecraft.client.Minecraft; import net.minecraft.client.shader.Framebuffer; import org.lwjgl.opengl.GL11; /** * Мастер-класс размытия на основе BlurDown и BlurUp шейдеров. * Структура повторяет KawaseBlur, но использует предоставленные шейдеры BlurUp и BlurDown. */ public class BlurShaderMaster { /** Единственный экземпляр (Singleton), позволяющий обращаться к BlurShaderMaster напрямую. */ public static final BlurShaderMaster INSTANCE = new BlurShaderMaster(); /** * Основной фреймбуфер, в котором хранится результат (размытие). * Может использоваться при отрисовке и наложении размытого изображения. */ private final CustomFramebuffer blurredFramebuffer; /** * Дополнительный фреймбуфер, используемый для промежуточных вычислений. */ private final CustomFramebuffer additionalFramebuffer; /** * Ещё один вспомогательный фреймбуфер (по аналогии с KawaseBlur). * Позволяет переключаться между несколькими буферами по очереди * и получать более гибкие варианты размытия. */ private final CustomFramebuffer blurTarget; /** * Конструктор, инициализирующий фреймбуферы для размытия. * Устанавливается линейная фильтрация (setLinear()), чтобы сгладить результат. */ public BlurShaderMaster() { this.blurredFramebuffer = new CustomFramebuffer(false).setLinear(); this.additionalFramebuffer = new CustomFramebuffer(false).setLinear(); this.blurTarget = new CustomFramebuffer(false).setLinear(); } /** * Метод для рендера с использованием трафарета (Stencil), * чтобы затем применить размытие только к нужной области. * * @param drawTarget код отрисовки фигур/элементов, которые нужно размыть. */ public void render(Runnable drawTarget) { // Инициализация буфера трафарета (Stencil) для записи. Stencil.initStencilToWrite(); // Выполняем пользовательскую отрисовку (ту, что хотим размыть). drawTarget.run(); // Переключаемся на чтение из буфера трафарета. Stencil.readStencilBuffer(1); // Рисуем результат (из последнего активного фреймбуфера) на экран. blurredFramebuffer.draw(); // Отключаем использование трафарета. Stencil.uninitStencilBuffer(); } /** * Основной метод для пошагового расчёта размытия. * Схож с KawaseBlur, но использует шейдеры BlurDown и BlurUp. * * @param offset Насколько сильно "разносится" размытие. * @param steps Количество шагов (итераций) размытия. */ public void updateBlur(float offset, int steps) { Minecraft mc = Minecraft.getInstance(); Framebuffer mcFramebuffer = mc.getFramebuffer(); // Получаем разрешение окна, чтобы корректно вычислять uniform-параметры. float width = mc.getMainWindow().getWidth(); float height = mc.getMainWindow().getHeight(); // Подготавливаем дополнительный фреймбуфер и рендерим в него содержимое экрана. additionalFramebuffer.setup(); mcFramebuffer.bindFramebufferTexture(); // Запускаем шейдер BlurDown. ShaderUtil.blurDown.attach(); ShaderUtil.blurDown.setUniform("offset", offset); ShaderUtil.blurDown.setUniformf("resolution", 1f / width, 1f / height); // Рисуем текстуру (с экрана) в additionalFramebuffer с учётом BlurDown. CustomFramebuffer.drawTexture(); // Готовим массив для переключения между двумя буферами по аналогии с KawaseBlur. CustomFramebuffer[] buffers = { additionalFramebuffer, blurredFramebuffer }; // Делаем несколько проходов (steps - 1 раз BlurDown). for (int i = 1; i < steps; i++) { int step = i % 2; buffers[step].setup(); buffers[(step + 1) % 2].draw(); } // После проходов BlurDown — переключаемся на BlurUp. ShaderUtil.blurUp.attach(); ShaderUtil.blurUp.setUniform("offset", offset); ShaderUtil.blurUp.setUniformf("resolution", 1f / width, 1f / height); // Проходим столько же раз шейдером BlurUp. for (int i = 0; i < steps; i++) { int step = i % 2; buffers[(step + 1) % 2].setup(); buffers[step].draw(); } // Отключаем шейдер и возвращаем рендер в основной буфер. ShaderUtil.blurUp.detach(); mcFramebuffer.bindFramebuffer(false); } /** * Возвращает фреймбуфер с итоговым размытием. Можно дополнительно * использовать его для наложения на интерфейс или игровую сцену. */ public CustomFramebuffer getBlurredFramebuffer() { return blurredFramebuffer; } /** * Возвращает дополнительный фреймбуфер, в котором происходит часть промежуточных вычислений. */ public CustomFramebuffer getAdditionalFramebuffer() { return additionalFramebuffer; } /** * Возвращает ещё один вспомогательный фреймбуфер (используется при необходимости). */ public CustomFramebuffer getBlurTarget() { return blurTarget; } }

Краткое описание работы класса:

  1. Конструктор создаёт три объекта CustomFramebuffer:

    • blurredFramebuffer — для итогового размытого изображения,
    • additionalFramebuffer — для промежуточных вычислений,
    • blurTarget — дополнительный буфер (по аналогии с KawaseBlur).
  2. Метод render:

    • Включает трафарет (Stencil) для записи,
    • Выполняет отрисовку объектов, которые нужно размыть,
    • Переключается на чтение из трафарета,
    • Рисует содержимое blurredFramebuffer,
    • Отключает трафарет.
  3. Метод updateBlur:

    • Забирает основной фреймбуфер игры (mcFramebuffer),
    • Рисует его содержимое в additionalFramebuffer через шейдер BlurDown,
    • Делает несколько проходов (зависящих от steps), переключаясь между blurredFramebuffer и additionalFramebuffer,
    • Затем выполняет нужное количество проходов шейдером BlurUp, снова переключаясь между буферами,
    • Выключает шейдер и возвращает нас к рендеру в основной буфер.

Таким образом, вы получаете мощное размытие, используя отдельные шейдеры BlurDown и BlurUp. Код организован аналогично KawaseBlur, но заменяет логику на новые шейдеры, которые вы предоставили.

Frage

сделай чтобы под белым прямоугольником был блюр используя наш класс void renderBackground(MatrixStack matrixStack, float x, float y, float width, float height, int mouseX, int mouseY) {
DisplayUtils.drawRoundedRect(x, y, width, height, new Vector4f(4, 4, 4, 4), new Color(18, 16, 14).getRGB());

text
DisplayUtils.drawRoundedRect(x, y, width, 64 / 2f, new Vector4f(6, 0, 6, 0), new Color(255, 255, 255,150).getRGB()); }

Gedanke

Defining the approach

I’m noting the user's requirement to blur behind a white rectangle and suggesting conducting a blur pass or specifying the region to be blurred within the rendering method.

Implementing blur

I'm thinking of implementing a blur effect behind the white rectangle using BlurShaderMaster.INSTANCE.render() or Stencil.initStencilToWrite() to shape the blur area, aligning with the user's request to only blur the region behind the rectangle.

Crafting the blur and rectangle

First, I apply a blur using BlurShaderMaster.INSTANCE.render() for the area behind the rectangle. Then, I draw a semi-transparent white rectangle on top.

Formulating the approach

I’m refining the user's needs by intricate blur layering with BlurShaderMaster.INSTANCE.render() for the rectangle's shape and BlurShaderMaster.INSTANCE.updateBlur(3.0f, 4) to ensure the blur effect is precisely achieved.

Integrating blur and stencil

I’m combining BlurShaderMaster.INSTANCE.render() to shape the blur area, refining it with BlurShaderMaster.INSTANCE.updateBlur(), and then overlaying a semi-transparent rectangle, potentially using 'Stencil' for intricate detailing.

Building upon the design

First, I draw the black rectangle to cover the entire area. Then, focusing on the white rectangle session, I blur behind it using BlurShaderMaster.INSTANCE.render() and BlurShaderMaster.INSTANCE.updateBlur().

Confirming integration

It's interesting to see that 'Stencil' or similar might be in BlurShaderMaster.INSTANCE.render(). A Java code snippet will be provided, showcasing complete logic as needed.

Reasoned for 17 seconds

Antwort

Ниже приведён пример того, как можно нарисовать белый полупрозрачный прямоугольник, под которым будет применяться размытие (используя ваш новый класс для Blur). Идея в том, что мы:

  1. Сначала отрисовываем фоновую часть (тёмный прямоугольник).
  2. Затем вызываем метод BlurShaderMaster#render, в который в виде Runnable передаём отрисовку области, где хотим размыть фон.
  3. После этого вызываем BlurShaderMaster#updateBlur, чтобы "применить" размытие.
  4. И в конце уже рисуем белый прямоугольник поверх.

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

java
public void renderBackground(MatrixStack matrixStack, float x, float y, float width, float height, int mouseX, int mouseY) { // 1. Рисуем тёмный фон (или любую сцену, которую хотим размывать). DisplayUtils.drawRoundedRect(x, y, width, height, new Vector4f(4, 4, 4, 4), new Color(18, 16, 14).getRGB()); // 2. Запускаем запись в буфер размытия. // Всё, что будет нарисовано внутри лямбды (Runnable), попадает в область, которая размоется. BlurShaderMaster.INSTANCE.render(() -> { // Здесь задаём форму, которая должна размазывать фон. // Проще говоря, рисуем "трафарет" размытия. // Цвет можно сделать полным белым или любым другим: DisplayUtils.drawRoundedRect(x, y, width, 64 / 2f, // высота нашего белого прямоугольника new Vector4f(6, 0, 6, 0), 0xFFFFFFFF); // полностью белый (для стэнсила) }); // 3. Теперь проводим реальное размытие (количество шагов и сила задаются параметрами). BlurShaderMaster.INSTANCE.updateBlur(3.0f, 4); // 4. Рисуем сам белый прямоугольник с нужным альфа-значением (прозрачностью). // Этот прямоугольник будет "сверху", а под ним уже будет видно размытое изображение. DisplayUtils.drawRoundedRect(x, y, width, 64 / 2f, new Vector4f(6, 0, 6, 0), new Color(255, 255, 255, 150).getRGB()); }

Принцип работы кода:

  1. Фоновая сцена. Всё, что нарисовано до момента вызова BlurShaderMaster.INSTANCE.render(...), будет потенциально видно на экране и может участвовать в размытии.

  2. render(Runnable). Этот вызов включает использование трафарета (Stencil) внутри, куда записывается форма, по которой потом применяется размытие. В нашем случае это прямоугольник с закруглёнными углами.

  3. updateBlur(offset, steps). После записи формы в трафарет идёт серия проходов шейдеров BlurDown и BlurUp. Чем больше steps и offset, тем сильнее визуально размытие.

  4. Прямоугольник поверх. Завершающий шаг — рисуем сам белый полупрозрачный прямоугольник (с использованием альфа-канала, например 150 из 255), под которым уже окажется размытый фон.

Таким образом, вы получаете красивый размазанный задник (фон) только в области белого прямоугольника.

Frage

а сделай так чтобы панель на кототорой блюр рендерилась не на черном прямоугольнике короче просто отдели ее @Override
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
super.render(matrixStack, mouseX, mouseY, partialTicks);
this.minecraft.keyboardListener.enableRepeatEvents(true);
float scale = 2f;
float width = 900 / scale;
float height = 650 / scale;
float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width);
float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height);
xPanel = x;
yPanel = y;
animation = MathUtil.lerp(animation, 0, 5);

text
Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY); mouseX = fixed.getX(); mouseY = fixed.getY(); int finalMouseX = mouseX; int finalMouseY = mouseY; mc.gameRenderer.setupOverlayRendering(2); renderBackground(matrixStack, x, y, width, height, finalMouseX, finalMouseY);

// renderCategories(matrixStack, x, y, width, height, finalMouseX, finalMouseY);
// renderComponents(matrixStack, x, y, width, height, finalMouseX, finalMouseY);
// renderColorPicker(matrixStack, x, y, width, height, finalMouseX, finalMouseY);
// renderSearchBar(matrixStack, x, y, width, height, finalMouseX, finalMouseY);
mc.gameRenderer.setupOverlayRendering();

text
} void renderColorPicker(MatrixStack matrixStack, float x, float y, float width, float height, int mouseX, int mouseY) { if (ColorComponent.opened != null) { ColorComponent.opened.draw(matrixStack, mouseX, mouseY); } if (ThemeComponent.selected != null) { ThemeComponent.selected.draw(matrixStack, mouseX, mouseY); } } public void renderBackground(MatrixStack matrixStack, float x, float y, float width, float height, int mouseX, int mouseY) { // 1. Рисуем тёмный фон (или любую сцену, которую хотим размывать).

// DisplayUtils.drawRoundedRect(x, y, width, height,
// new Vector4f(4, 4, 4, 4),
// new Color(18, 16, 14).getRGB());

text
// 2. Запускаем запись в буфер размытия. // Всё, что будет нарисовано внутри лямбды (Runnable), попадает в область, которая размоется. BlurShaderMaster.INSTANCE.render(() -> { // Здесь задаём форму, которая должна размазывать фон. // Проще говоря, рисуем "трафарет" размытия. // Цвет можно сделать полным белым или любым другим: DisplayUtils.drawRoundedRect(x, y, width, 64 / 2f, // высота нашего белого прямоугольника new Vector4f(6, 0, 6, 0), 0xFFFFFFFF); // полностью белый (для стэнсила) }); // 3. Теперь проводим реальное размытие (количество шагов и сила задаются параметрами). BlurShaderMaster.INSTANCE.updateBlur(0.0f, 3); // 4. Рисуем сам белый прямоугольник с нужным альфа-значением (прозрачностью). // Этот прямоугольник будет "сверху", а под ним уже будет видно размытое изображение. DisplayUtils.drawRoundedRect(x, y, width, 64 / 2f, new Vector4f(6, 0, 6, 0), new Color(255, 0, 0, 0).getRGB()); }

Gedanke

Creating a class to apply blur using provided shaders.

Designing a class for applying blur using specific shaders. Ensuring clarity and precision throughout the process.

Designing a class for applying blur using specific shaders, ensuring efficient rendering and image clarity.

Designing a class for blur application, ensuring rendering efficiency, clarity, and keyboard accessibility. This involves crafting user-friendly configurations and managing memory effectively.

Designing a blur application class using shaders, focusing on clarity and effective memory management for optimal performance.

Designing a class for blur application using shaders, focusing on efficient pixel rendering, alpha blending, and enhancing clarity and smoothness.

Reasoned for a few seconds

Antwort

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

Вот обновлённый код:

java
@Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { super.render(matrixStack, mouseX, mouseY, partialTicks); this.minecraft.keyboardListener.enableRepeatEvents(true); // Параметры для панели float scale = 2f; float width = 900 / scale; float height = 650 / scale; float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, width); float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, height); xPanel = x; yPanel = y; animation = MathUtil.lerp(animation, 0, 5); Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY); mouseX = fixed.getX(); mouseY = fixed.getY(); int finalMouseX = mouseX; int finalMouseY = mouseY; mc.gameRenderer.setupOverlayRendering(2); renderBackground(matrixStack, x, y, width, height, finalMouseX, finalMouseY); mc.gameRenderer.setupOverlayRendering(); } public void renderBackground(MatrixStack matrixStack, float x, float y, float width, float height, int mouseX, int mouseY) { // 1. Сначала рисуем саму панель с блюром (не фон). BlurShaderMaster.INSTANCE.render(() -> { // Здесь рисуем панель, которая будет размыта. DisplayUtils.drawRoundedRect(x, y, width, height, new Vector4f(6, 6, 6, 6), // скругление new Color(255, 255, 255, 100).getRGB()); // полупрозрачная белая панель }); // 2. Запускаем размытие с заданным параметром. BlurShaderMaster.INSTANCE.updateBlur(2.0f, 4); // 3. Рисуем саму панель поверх размытия. // Это будет полупрозрачная белая панель с нужной альфой. DisplayUtils.drawRoundedRect(x, y, width, height, new Vector4f(6, 6, 6, 6), // скругление new Color(255, 255, 255, 150).getRGB()); // более высокая альфа для панели }

Что изменено:

  1. Удаление фона. Теперь в renderBackground не рисуется тёмный прямоугольник, который был в предыдущем примере. Мы делаем панель с блюром отдельно.

  2. Размытие только для панели. В блоке кода, который отвечает за размытие, вызывается BlurShaderMaster.INSTANCE.render, где рисуется только панель (не фон).

  3. Меньше "перекрытия". Белый прямоугольник, на котором будет отображаться размытие, рисуется с прозрачностью, что позволяет видеть размытие за ним. Оставляем панель как полупрозрачную и даём её рисование поверх размытия.

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

Frage

надо чтобы панель на которой был блюр просто рендерилась не на прямоугольнике а отдельно чтобы черный прямоугольник не перекрывал блюр

Gedanke

Sorting the layout

I’m thinking through whether the black rectangle should sit behind or over the blur panel, or if it’s even needed.

Organizing the layout

I’m laying out the blur panel away from the black rectangle so it doesn’t overlap. Now, I’ll sequence the code to ensure they render separately.

Tweaking the layout

OK, let me see: I’m removing the black rectangle or placing it behind all other elements so the blur panel renders correctly in front.

Rethinking the layout

I’m leaning towards removing the black rectangle so the blur panel can appear separately. This makes me think the design should be simple and streamlined.

Reasoned for 11 seconds

Antwort

Ниже приведён пример кода, в котором нет чёрного прямоугольника, а «панель с блюром» рендерится самостоятельно. Таким образом, чёрный прямоугольник не будет перекрывать размытие.

Основная идея:

  1. Убираем код отрисовки чёрного прямоугольника (или переносим его в другое место, если он нужен для чего-то ещё).
  2. Рисуем только панель, на которой будет виден блюр.
  3. При необходимости меняем параметры (offset, steps) в updateBlur, чтобы получить желаемую степень размытия.

Пример кода

java
@Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { super.render(matrixStack, mouseX, mouseY, partialTicks); this.minecraft.keyboardListener.enableRepeatEvents(true); // Параметры для размытой панели float scale = 2f; float panelWidth = 900 / scale; float panelHeight = 650 / scale; float x = MathUtil.calculateXPosition(mc.getMainWindow().scaledWidth() / 2f, panelWidth); float y = MathUtil.calculateXPosition(mc.getMainWindow().scaledHeight() / 2f, panelHeight); xPanel = x; yPanel = y; animation = MathUtil.lerp(animation, 0, 5); // Приведение координат мыши (если нужно) Vec2i fixed = ClientUtil.getMouse(mouseX, mouseY); mouseX = fixed.getX(); mouseY = fixed.getY(); // Отрисовываем нашу размытую панель mc.gameRenderer.setupOverlayRendering(2); renderBlurPanel(matrixStack, x, y, panelWidth, panelHeight); mc.gameRenderer.setupOverlayRendering(); } /** * Рендерим отдельную панель с блюром — без чёрного прямоугольника. */ public void renderBlurPanel(MatrixStack matrixStack, float x, float y, float width, float height) { // 1. Сначала вызываем render(...) из BlurShaderMaster, // чтобы записать форму (трафарет), по которой будет размытие. BlurShaderMaster.INSTANCE.render(() -> { // Здесь рисуем тот самый &laquo;трафарет&raquo; размытия // (в данном случае — белый прямоугольник с закруглёнными углами). DisplayUtils.drawRoundedRect(x, y, width, height, new Vector4f(8, 8, 8, 8), // угол скругления 0xFFFFFFFF); // полностью белый для стэнсила }); // 2. Запускаем размытие. Параметры offset и steps можно настроить по вкусу. BlurShaderMaster.INSTANCE.updateBlur(2.0f, 4); // 3. Рисуем полупрозрачную белую панель поверх размытия, // чтобы создать эффект &laquo;стекла&raquo; или &laquo;прозрачного пластика&raquo;. DisplayUtils.drawRoundedRect(x, y, width, height, new Vector4f(8, 8, 8, 8), new Color(255, 255, 255, 100).getRGB()); }

Пояснения по коду

  • Render без чёрного прямоугольника:
    Мы не рисуем DisplayUtils.drawRoundedRect(...) с тёмным цветом (или убрали этот блок из метода).
    Таким образом, за нашей размытой панелью теперь будет «проглядывать» либо фон игры, либо любой другой элемент, что рендерится до неё.

  • BlurShaderMaster#render(...):

    • Внутри лямбды, которую вы передаёте, рисуется фигура (в данном случае, скруглённый прямоугольник).
    • По этой области (трафарету) шейдеры затем «выберут», что размывать.
  • BlurShaderMaster#updateBlur(...):

    • Непосредственно применяется размытие шейдерами BlurDown и BlurUp.
    • Параметры:
      • offset (например, 2.0f) — степень смещения пикселей при размытии,
      • steps (например, 4) — количество проходов размытия.
  • Прозрачная панель:

    • После того, как размытие рассчитано, рисуется полупрозрачный белый прямоугольник (альфа ~ 100), чтобы визуально было похоже на «стекло».
    • Можно менять прозрачность (альфа-канал) по вкусу.

Что, если нужен чёрный фон, но не под панелью?

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

Таким образом, панель с блюром будет «отдельной» и не будет перекрываться чёрным прямоугольником.

Diesen Q&A teilen