Начинающий
Начинающий
- Статус
- Оффлайн
- Регистрация
- 16 Июл 2024
- Сообщения
- 54
- Реакции
- 0
Пытаюсь написать деф блюрчек на 1.21.11, но какие-то магичемкие баги меня уже ебут сотый час
Как это дело выглядит:
Как это дело выглядит:
Пожалуйста, авторизуйтесь для просмотра ссылки.
Kawase.java:
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Kawase implements IPostEffect {
private static final int RENDER_EVENT_PRIORITY = -200;
private static final MinecraftClient mc = MinecraftClient.getInstance();
@Getter
GpuTextureView texture;
@Getter
int downsampleLevels = 4;
@Getter
float samplePosMultiplier = 3.0f, bloomStrength = 1.0f;
boolean uniformsDirty;
GpuTextureView[] fbos;
GpuBufferSlice[] slices;
MeshBuilder mesh;
public Kawase() {
mesh = new MeshBuilder(VertexFormats.POSITION_TEXTURE_COLOR, VertexFormat.DrawMode.TRIANGLES);
Xera.INSTANCE.getEventBus().subscribe(this);
initFBOs();
}
@EventHandler
private void onResolutionChanged(EventResolutionChanged e) {
initFBOs();
initSlices();
}
@EventHandler(priority = RENDER_EVENT_PRIORITY)
private void onGui(EventRender.Gui e) {
render();
}
public void render() {
if (uniformsDirty || slices == null || slices.length != downsampleLevels) {
initSlices();
}
RenderSystem.getDevice().createCommandEncoder().clearColorTexture(texture.texture(), 0);
// Downsample
GpuTextureView src = mc.getFramebuffer().getColorAttachmentView();
for (int i = 0; i < downsampleLevels; i++) {
draw(fbos[i], src, slices[i], true);
src = fbos[i];
}
// Upsample
for (int i = downsampleLevels - 2; i >= 0; i--) {
draw(fbos[i], fbos[i + 1], slices[i], false);
}
// Render
quad();
MeshRenderer.begin()
.attachments(texture, null)
.pipeline(XeraRenderPipelines.UI_TEXTURED)
.sampler("u_Texture", fbos[0], RenderSystem.getSamplerCache().get(FilterMode.LINEAR))
.mesh(mesh)
.end();
}
private void initFBOs() {
texture = createFbo(1);
fbos = new GpuTextureView[downsampleLevels];
double scale = 0.5;
for (int i = 0; i < downsampleLevels; i++) {
fbos[i] = createFbo(scale);
scale *= 0.5;
}
}
private void initSlices() {
KawaseDataUBO.STORAGE.clear();
KawaseDataUBO.Data[] data = new KawaseDataUBO.Data[downsampleLevels];
for (int i = 0; i < downsampleLevels; i++) {
GpuTextureView fbo = fbos[i];
float offset = samplePosMultiplier * (i + 1);
data[i] = new KawaseDataUBO.Data(
1f / fbo.getWidth(0),
1f / fbo.getHeight(0),
offset,
bloomStrength
);
}
slices = KawaseDataUBO.STORAGE.writeAll(data);
uniformsDirty = false;
}
private void draw(GpuTextureView target, GpuTextureView src, GpuBufferSlice ubo, boolean down) {
quad();
MeshRenderer.begin()
.attachments(target, null)
.mesh(mesh)
.pipeline(down ? XeraRenderPipelines.UI_KAWASE_DOWN : XeraRenderPipelines.UI_KAWASE_UP)
.uniform("KUpData", ubo)
.sampler("u_Texture", src, RenderSystem.getSamplerCache().get(FilterMode.LINEAR))
.end();
}
private void quad() {
float w = mc.getFramebuffer().textureWidth;
float h = mc.getFramebuffer().textureHeight;
mesh.begin();
mesh.ensureQuadCapacity();
mesh.quad(
mesh.vec2(0, 0).vec2(0, 0).color(-1).next(),
mesh.vec2(0, h).vec2(0, 1).color(-1).next(),
mesh.vec2(w, h).vec2(1, 1).color(-1).next(),
mesh.vec2(w, 0).vec2(1, 0).color(-1).next()
);
}
private static GpuTextureView createFbo(double scale) {
int width = (int) (mc.getWindow().getFramebufferWidth() * scale);
int height = (int) (mc.getWindow().getFramebufferHeight() * scale);
return RenderSystem.getDevice().createTextureView(
RenderSystem.getDevice().createTexture(
"Xera Dual Kawase - " + scale,
15,
TextureFormat.RGBA8,
width,
height,
1,
1
)
);
}
public void setDownsampleLevels(int levels) {
if (levels != this.downsampleLevels) {
initFBOs();
uniformsDirty = true;
}
this.downsampleLevels = levels;
}
public void setSamplePosMultiplier(float multiplier) {
if (multiplier != this.samplePosMultiplier) {
uniformsDirty = true;
}
this.samplePosMultiplier = multiplier;
}
public void setBloomStrength(float strength) {
if (strength != this.bloomStrength) {
uniformsDirty = true;
}
this.bloomStrength = strength;
}
}
SquircleDrawer.java:
public final class SquircleDrawer implements IDrawer, Shortcuts {
private final MeshBuilder triangles;
private Float lastWidth, lastHeight, lastRadius, lastSmoothness;
private Matrix4f lastMatrix;
public SquircleDrawer() {
triangles = new MeshBuilder(XeraRenderPipelines.UI_SQUIRCLE_MASK);
}
public void squircle(float x, float y, float width, float height, float radius, float smoothness, Vector4i colors, Matrix4f matrix) {
boolean significantChange = checkSignificantChange(width, height, radius, smoothness, matrix);
if (significantChange) {
render();
}
if (!triangles.isBuilding()) triangles.begin();
triangles.ensureQuadCapacity();
GpuTextureView ff = mc.getFramebuffer().getColorAttachmentView();
float x1 = x, x2 = x + width;
float y1 = y, y2 = y + height;
float wWidth = ff.getWidth(0), wHeight = ff.getHeight(0);
float u1, u2;
float v1, v2;
u1 = x1 / wWidth;
u2 = x2 / wWidth;
v1 = y2 / wHeight;
v2 = y1 / wHeight;
v1 = 1 - v1;
v2 = 1 - v2;
triangles.quad(
triangles.vec2(x, y).vec2(u1, v1).color(colors.x()).next(),
triangles.vec2(x, y + height).vec2(u1, v2).color(colors.y()).next(),
triangles.vec2(x + width, y + height).vec2(u2, v2).color(colors.z()).next(),
triangles.vec2(x + width, y).vec2(u2, v1).color(colors.w()).next()
);
lastWidth = width;
lastHeight = height;
lastRadius = radius;
lastSmoothness = smoothness;
lastMatrix = new Matrix4f(matrix);
}
private boolean checkSignificantChange(float width, float height, float radius, float smoothness, Matrix4f matrix) {
if (lastWidth == null) return false;
if (!lastWidth.equals(width)) return true;
if (!lastHeight.equals(height)) return true;
if (!lastRadius.equals(radius)) return true;
if (!lastSmoothness.equals(smoothness)) return true;
if (!lastMatrix.equals(matrix)) return true;
return false;
}
@Override
public void render() {
if (!triangles.isBuilding()) return;
triangles.end();
MeshRenderer.begin()
.attachments(mc.getFramebuffer().getColorAttachmentView(), null)
.pipeline(XeraRenderPipelines.UI_SQUIRCLE_MASK)
.uniform("SquircleData", anus(new SquircleDataUBO.Data(lastWidth, lastHeight, lastRadius, lastSmoothness)))
.sampler("u_Texture", PostEffectsManager.KAWASE().getTexture(), RenderSystem.getSamplerCache().get(FilterMode.LINEAR))
.mesh(triangles)
.transform(lastMatrix)
.end();
nullify();
}
@Override
public void flipFrame() {
// render();
SquircleDataUBO.STORAGE.clear();
nullify();
}
private void nullify() {
lastWidth = null;
lastHeight = null;
lastRadius = null;
lastSmoothness = null;
lastMatrix = null;
}
private GpuBufferSlice anus(SquircleDataUBO.Data data) {
return SquircleDataUBO.STORAGE.write(data);
}
}