Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос Текстурные координаты порождают демонические баги | 1.21.11

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
16 Июл 2024
Сообщения
54
Реакции
0
Пытаюсь написать деф блюрчек на 1.21.11, но какие-то магичемкие баги меня уже ебут сотый час

Как это дело выглядит:
Пожалуйста, авторизуйтесь для просмотра ссылки.


Kawase.java:
Expand Collapse Copy
@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:
Expand Collapse Copy
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);
    }

}
 
Назад
Сверху Снизу