From 01113f98b8697bb422ced122d519327ebd0efad4 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Wed, 17 Jun 2026 02:30:08 +0800 Subject: [PATCH 1/2] add glitch effect --- .../lib/v2/rendering/ALRPipelines.java | 6 + .../lib/v2/rendering/ALRPostEffects.java | 5 + .../v2/rendering/bloom/BloomPostEffect.java | 8 +- .../rendering/glitch/GlitchParametersUbo.java | 32 +++++ .../v2/rendering/glitch/GlitchPostEffect.java | 133 ++++++++++++++++++ .../lib/v2/rendering/gui/GuiRenderExtras.java | 35 +++-- .../gui/renderer/StructurePipRenderer.java | 81 ++++++++++- .../gui/state/StructurePipRenderingState.java | 39 ++--- .../shaders/core/glitch.fsh | 51 +++++++ .../v2/test/client/screen/GuiTestScreen.java | 1 + 10 files changed, 347 insertions(+), 44 deletions(-) create mode 100644 module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/glitch/GlitchParametersUbo.java create mode 100644 module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/glitch/GlitchPostEffect.java create mode 100644 module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/glitch.fsh diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPipelines.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPipelines.java index 3ce2c3fe..9861309c 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPipelines.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPipelines.java @@ -22,6 +22,12 @@ public class ALRPipelines { .withCull(false) .buildSnippet(); + public static final RenderPipeline GLITCH = RenderPipeline.builder(POST_PASS) + .withLocation(AnvilLibRendering.location("glitch")) + .withFragmentShader(AnvilLibRendering.location("core/glitch")) + .withUniform("GlitchParameters", UniformType.UNIFORM_BUFFER) + .build(); + public static final RenderPipeline BLUR = RenderPipeline.builder(POST_PASS) .withLocation(AnvilLibRendering.location("blur")) .withFragmentShader(AnvilLibRendering.location("core/blur")) diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java index 414db1e2..02a2f536 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java @@ -2,6 +2,8 @@ import dev.anvilcraft.lib.v2.rendering.bloom.BloomPostEffect; import dev.anvilcraft.lib.v2.rendering.event.MainTargetResizeEvent; +import dev.anvilcraft.lib.v2.rendering.glitch.GlitchParametersUbo; +import dev.anvilcraft.lib.v2.rendering.glitch.GlitchPostEffect; import lombok.Getter; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderBuffers; @@ -14,9 +16,12 @@ public class ALRPostEffects { @Getter private static BloomPostEffect bloomPostEffect; + @Getter + private static GlitchPostEffect glitchPostEffect; public static void createPostEffects() { bloomPostEffect = new BloomPostEffect(); + glitchPostEffect = new GlitchPostEffect(); } public static void runBloomDraws(Matrix4fc mvMat) { diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/bloom/BloomPostEffect.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/bloom/BloomPostEffect.java index 98749f8b..fb5814e1 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/bloom/BloomPostEffect.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/bloom/BloomPostEffect.java @@ -62,25 +62,25 @@ public class BloomPostEffect implements DirtyTracked { private final GpuDevice device = RenderSystem.getDevice(); private final GpuBuffer transformUBO = device.createBuffer( - () -> "BloomPostEffect->TransformUBO", + () -> "BloomPostEffect TransformUBO", GpuBuffer.USAGE_COPY_DST | GpuBuffer.USAGE_UNIFORM, UNIFORM_TRANSFORM_SIZE ); private final GpuBuffer bloomUBO = device.createBuffer( - () -> "BloomPostEffect->BloomApplyUBO", + () -> "BloomPostEffect BloomApplyUBO", GpuBuffer.USAGE_COPY_DST | GpuBuffer.USAGE_UNIFORM, UNIFORM_BLOOM_SIZE ); private final GpuBuffer enhancedBloomParametersUBO = device.createBuffer( - () -> "BloomPostEffect->BloomParametersUBO", + () -> "BloomPostEffect BloomParametersUBO", GpuBuffer.USAGE_COPY_DST | GpuBuffer.USAGE_UNIFORM, UNIFORM_ENHANCED_BLOOM_SIZE ); private final GpuBuffer vertexBuffer = device.createBuffer( - () -> "BloomPostEffect->VertexBuffer", + () -> "BloomPostEffect VertexBuffer", GpuBuffer.USAGE_COPY_DST | GpuBuffer.USAGE_VERTEX, 1024 ); diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/glitch/GlitchParametersUbo.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/glitch/GlitchParametersUbo.java new file mode 100644 index 00000000..b991a51b --- /dev/null +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/glitch/GlitchParametersUbo.java @@ -0,0 +1,32 @@ +package dev.anvilcraft.lib.v2.rendering.glitch; + +import dev.anvilcraft.lib.v2.rendering.foundation.buffers.layout.BufferLayout; +import dev.anvilcraft.lib.v2.rendering.foundation.buffers.object.BufferObject; +import dev.anvilcraft.lib.v2.rendering.foundation.buffers.object.BufferObjectLayoutDefinition; +import dev.anvilcraft.lib.v2.rendering.foundation.buffers.object.BufferObjectLayoutEntry; +import dev.anvilcraft.lib.v2.rendering.foundation.buffers.object.ShaderBufferObjectUsage; +import lombok.Getter; +import lombok.Setter; +import org.joml.Vector2f; + +@Getter +@Setter +public class GlitchParametersUbo extends BufferObject { + + public static final BufferObjectLayoutDefinition DEFINITION = BufferObjectLayoutDefinition.create( + BufferObjectLayoutEntry.ofVec2f().forGetter(GlitchParametersUbo::getInSize).build(), + BufferObjectLayoutEntry.ofFloat().forGetter(GlitchParametersUbo::getGameTime).build() + ); + + private Vector2f inSize = new Vector2f(); + private float gameTime = 0; + + protected GlitchParametersUbo() { + super(BufferLayout.STD140, ShaderBufferObjectUsage.UBO); + } + + @Override + protected BufferObjectLayoutDefinition getDefinition() { + return DEFINITION; + } +} diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/glitch/GlitchPostEffect.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/glitch/GlitchPostEffect.java new file mode 100644 index 00000000..fa79dcf8 --- /dev/null +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/glitch/GlitchPostEffect.java @@ -0,0 +1,133 @@ +package dev.anvilcraft.lib.v2.rendering.glitch; + +import com.mojang.blaze3d.buffers.GpuBuffer; +import com.mojang.blaze3d.pipeline.RenderTarget; +import com.mojang.blaze3d.pipeline.TextureTarget; +import com.mojang.blaze3d.systems.CommandEncoder; +import com.mojang.blaze3d.systems.GpuDevice; +import com.mojang.blaze3d.systems.RenderPass; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.AddressMode; +import com.mojang.blaze3d.textures.FilterMode; +import com.mojang.blaze3d.textures.GpuSampler; +import com.mojang.blaze3d.textures.GpuTextureView; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.MeshData; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; +import dev.anvilcraft.lib.v2.rendering.ALRPipelines; +import dev.anvilcraft.lib.v2.rendering.bloom.TransformsUbo; +import dev.anvilcraft.lib.v2.rendering.foundation.buffers.layout.BufferLayout; +import lombok.Getter; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.Minecraft; +import org.joml.Matrix4f; + +import java.util.OptionalDouble; +import java.util.OptionalInt; + +public class GlitchPostEffect { + public static final int UNIFORM_GLITCH_SIZE = GlitchParametersUbo.DEFINITION.size(BufferLayout.STD140); + public static final int UNIFORM_TRANSFORM_SIZE = TransformsUbo.DEFINITION.size(BufferLayout.STD140); + + @Getter + private final RenderTarget glitchOutputTarget = new TextureTarget("Glitch Result", 854, 480, false); + + private final GpuDevice device = RenderSystem.getDevice(); + + private final GpuBuffer transformUBO = device.createBuffer( + () -> "GlitchPostEffect TransformUBO", + GpuBuffer.USAGE_COPY_DST | GpuBuffer.USAGE_UNIFORM, + UNIFORM_TRANSFORM_SIZE + ); + + private final GpuBuffer glitchParameterUBO = device.createBuffer( + () -> "GlitchPostEffect TransformUBO", + GpuBuffer.USAGE_COPY_DST | GpuBuffer.USAGE_UNIFORM, + UNIFORM_GLITCH_SIZE + ); + + private final GpuBuffer vertexBuffer = device.createBuffer( + () -> "GlitchPostEffect VertexBuffer", + GpuBuffer.USAGE_COPY_DST | GpuBuffer.USAGE_VERTEX, + 1024 + ); + + @Getter + private final GpuSampler sampler = device.createSampler( + AddressMode.CLAMP_TO_EDGE, + AddressMode.CLAMP_TO_EDGE, + FilterMode.LINEAR, + FilterMode.LINEAR, + 1, + OptionalDouble.empty() + ); + + private final TransformsUbo transform = new TransformsUbo(new Matrix4f()); + private final GlitchParametersUbo glitchParameters = new GlitchParametersUbo(); + private int lastWidth = 0; + private int lastHeight = 0; + private int indexCount = 0; + + public GpuTextureView process(GpuTextureView input, int width, int height) { + CommandEncoder commandEncoder = device.createCommandEncoder(); + + if (glitchOutputTarget.width < width || glitchOutputTarget.height < height) { + glitchOutputTarget.resize(width, height); + } + + Minecraft minecraft = Minecraft.getInstance(); + long gameTime = minecraft.level.getGameTime(); + DeltaTracker deltaTracker = minecraft.getDeltaTracker(); + + if (lastHeight != height || lastWidth != width) { + this.lastWidth = width; + this.lastHeight = height; + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + + builder.addVertex(0, 0, 100).setUv(0, 1); + builder.addVertex(0, height, 100).setUv(0, 0); + builder.addVertex(width, height, 100).setUv(1, 0); + builder.addVertex(width, 0, 100).setUv(1, 1); + + MeshData data = builder.buildOrThrow(); + commandEncoder.writeToBuffer(vertexBuffer.slice(), data.vertexBuffer()); + this.indexCount = data.drawState().indexCount(); + data.close(); + } + + transform.getProjMat().setOrtho( + 0, + glitchOutputTarget.width, + 0, + glitchOutputTarget.height, + -10000, + 10000 + ); + glitchParameters.getInSize().set(width, height); + float uGameTime = (float) (gameTime % 24000L) + deltaTracker.getGameTimeDeltaPartialTick(false); + uGameTime /= 10f; + glitchParameters.setGameTime(uGameTime); + + transform.upload(commandEncoder, transformUBO.slice()); + glitchParameters.upload(commandEncoder, glitchParameterUBO.slice()); + RenderSystem.AutoStorageIndexBuffer buffer = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS); + GpuBuffer indexBuffer = buffer.getBuffer(indexCount); + try (RenderPass pass = commandEncoder.createRenderPass( + () -> "Glitch Post Pass", + glitchOutputTarget.getColorTextureView(), + OptionalInt.of(0) + )) { + pass.setPipeline(ALRPipelines.GLITCH); + pass.setUniform("Transforms", transformUBO); + pass.setUniform("GlitchParameters", glitchParameterUBO); + pass.bindTexture("DiffuseSampler", input, sampler); + pass.setVertexBuffer(0, vertexBuffer); + pass.setIndexBuffer(indexBuffer, buffer.type()); + pass.drawIndexed(0, 0, indexCount, 1); + } + return glitchOutputTarget.getColorTextureView(); + } +} diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/GuiRenderExtras.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/GuiRenderExtras.java index f255eec9..3461047b 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/GuiRenderExtras.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/GuiRenderExtras.java @@ -279,6 +279,7 @@ public static void submitStructure( float y1, float scale, boolean ambientOcclusion, + boolean glitched, PoseStack poseStack ) { guiGraphicsExtractor.submitPictureInPictureRenderState( @@ -286,12 +287,13 @@ public static void submitStructure( structureAccess, startPos, endPos, - x0, - y0, - x1, - y1, + (int) x0, + (int) y0, + (int) x1, + (int) y1, scale, ambientOcclusion, + glitched, poseStack.last().copy(), guiGraphicsExtractor.pose().get(new Matrix3x2f()), guiGraphicsExtractor.peekScissorStack() @@ -310,6 +312,7 @@ public static void submitStructure( float y1, float scale, boolean ambientOcclusion, + boolean glitched, PoseStack.Pose pose3D ) { guiGraphicsExtractor.submitPictureInPictureRenderState( @@ -317,12 +320,13 @@ public static void submitStructure( structureAccess, startPos, endPos, - x0, - y0, - x1, - y1, + (int) x0, + (int) y0, + (int) x1, + (int) y1, scale, ambientOcclusion, + glitched, pose3D, guiGraphicsExtractor.pose().get(new Matrix3x2f()), guiGraphicsExtractor.peekScissorStack() @@ -341,6 +345,19 @@ public static void submitStructure( float y1, PoseStack.Pose pose3D ) { - submitStructure(guiGraphicsExtractor, structureAccess, startPos, endPos, x0, y0, x1, y1, 32.0f, false, pose3D); + submitStructure( + guiGraphicsExtractor, + structureAccess, + startPos, + endPos, + x0, + y0, + x1, + y1, + 32.0f, + false, + false, + pose3D + ); } } diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/renderer/StructurePipRenderer.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/renderer/StructurePipRenderer.java index d5022327..5268cbce 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/renderer/StructurePipRenderer.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/renderer/StructurePipRenderer.java @@ -1,9 +1,22 @@ package dev.anvilcraft.lib.v2.rendering.gui.renderer; +import com.mojang.blaze3d.buffers.GpuBuffer; +import com.mojang.blaze3d.buffers.GpuBufferSlice; +import com.mojang.blaze3d.systems.CommandEncoder; +import com.mojang.blaze3d.systems.RenderPass; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.GpuTextureView; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.blaze3d.vertex.VertexFormat; +import dev.anvilcraft.lib.v2.rendering.ALRPostEffects; import dev.anvilcraft.lib.v2.rendering.foundation.buffers.TransformingVertexConsumerWrapper; import dev.anvilcraft.lib.v2.rendering.foundation.fakeworld.SimpleTintedEmptyLevelAccess; +import dev.anvilcraft.lib.v2.rendering.glitch.GlitchPostEffect; import dev.anvilcraft.lib.v2.rendering.gui.state.StructurePipRenderingState; import dev.anvilcraft.lib.v2.rendering.util.Timer; import net.minecraft.client.Minecraft; @@ -11,6 +24,7 @@ import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderBuffers; +import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.client.renderer.Sheets; import net.minecraft.client.renderer.SubmitNodeStorage; import net.minecraft.client.renderer.block.BlockAndTintGetter; @@ -26,9 +40,13 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.phys.Vec3; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.joml.Vector4f; import java.util.HashMap; import java.util.Map; +import java.util.OptionalInt; public class StructurePipRenderer extends PictureInPictureRenderer { @@ -49,12 +67,16 @@ public Class getRenderStateClass() { protected void renderToTexture(StructurePipRenderingState renderState, PoseStack poseStack) { Minecraft minecraft = Minecraft.getInstance(); int guiScale = minecraft.gameRenderer.getGameRenderState().windowRenderState.guiScale; - float width = (renderState.fx1() - renderState.fx0()) * guiScale; - float height = (renderState.fy1() - renderState.fy0()) * guiScale; + int width = (renderState.x1() - renderState.x0()) * guiScale; + int height = (renderState.y1() - renderState.y0()) * guiScale; float scale = guiScale * renderState.scale(); BlockAndTintGetter level = renderState.structureAccess(); - ModelBlockRenderer blockRenderer = new ModelBlockRenderer(renderState.ambientOcclusion(), true, minecraft.getBlockColors()); + ModelBlockRenderer blockRenderer = new ModelBlockRenderer( + renderState.ambientOcclusion(), + true, + minecraft.getBlockColors() + ); FluidRenderer fluidRenderer = new FluidRenderer(minecraft.getModelManager().getFluidStateModelSet()); poseStack.pushPose(); @@ -166,6 +188,59 @@ protected void renderToTexture(StructurePipRenderingState renderState, PoseStack poseStack.popPose(); poseStack.popPose(); + if (renderState.glitched()) { + applyGlitchEffect(width, height); + } + } + + public void applyGlitchEffect(int width, int height) { + GlitchPostEffect glitchPostEffect = ALRPostEffects.getGlitchPostEffect(); + GpuTextureView processed = glitchPostEffect.process( + RenderSystem.outputColorTextureOverride, + width, + height + ); + float u1 = width / (glitchPostEffect.getGlitchOutputTarget().width * 1.0f); + float v1 = height / (glitchPostEffect.getGlitchOutputTarget().height * 1.0f); + Tesselator tesselator = Tesselator.getInstance(); + VertexFormat format = DefaultVertexFormat.POSITION_TEX_COLOR; + BufferBuilder builder = tesselator.begin(VertexFormat.Mode.QUADS, format); + + builder.addVertex(0, 0, 100).setUv(0, 0).setColor(-1); + builder.addVertex(0, height, 100).setUv(0, v1).setColor(-1); + builder.addVertex(width, height, 100).setUv(u1, v1).setColor(-1); + builder.addVertex(width, 0, 100).setUv(u1, 0).setColor(-1); + + MeshData data = builder.buildOrThrow(); + GpuBuffer buffer = format.uploadImmediateVertexBuffer(data.vertexBuffer()); + int indexCount = data.drawState().indexCount(); + data.close(); + RenderSystem.AutoStorageIndexBuffer sequentialBuffer = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS); + GpuBuffer indexBuffer = sequentialBuffer.getBuffer(indexCount); + + CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder(); + + GpuBufferSlice dynamicTransforms = RenderSystem.getDynamicUniforms() + .writeTransform( + new Matrix4f(), + new Vector4f(1.0F, 1.0F, 1.0F, 1.0F), + new Vector3f(), + new Matrix4f() + ); + + try (RenderPass renderPass = commandEncoder.createRenderPass( + () -> "Immediate draw for blitGlitchEffect", + RenderSystem.outputColorTextureOverride, + OptionalInt.of(0) + )) { + renderPass.setPipeline(RenderPipelines.GUI_TEXTURED); + renderPass.bindTexture("Sampler0", processed, glitchPostEffect.getSampler()); + renderPass.setVertexBuffer(0, buffer); + renderPass.setIndexBuffer(indexBuffer, sequentialBuffer.type()); + renderPass.setUniform("DynamicTransforms", dynamicTransforms); + RenderSystem.bindDefaultUniforms(renderPass); + renderPass.drawIndexed(0, 0, indexCount, 1); + } } public VertexConsumer createChunkSectionLayer(ChunkSectionLayer layer, PoseStack poseStack) { diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/state/StructurePipRenderingState.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/state/StructurePipRenderingState.java index 67fe2110..d7c6b38a 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/state/StructurePipRenderingState.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/state/StructurePipRenderingState.java @@ -13,12 +13,13 @@ public record StructurePipRenderingState ( BlockAndTintGetter structureAccess, BlockPos startPos, BlockPos endPos, - float fx0, - float fy0, - float fx1, - float fy1, + int x0, + int y0, + int x1, + int y1, float scale, boolean ambientOcclusion, + boolean glitched, PoseStack.Pose pose3D, Matrix3x2f pose, @Nullable ScreenRectangle scissorArea, @@ -29,12 +30,13 @@ public StructurePipRenderingState( BlockAndTintGetter structureAccess, BlockPos startPos, BlockPos endPos, - float x0, - float y0, - float x1, - float y1, + int x0, + int y0, + int x1, + int y1, float scale, boolean ambientOcclusion, + boolean glitched, PoseStack.Pose pose3D, Matrix3x2f pose, @Nullable ScreenRectangle scissorArea @@ -49,30 +51,11 @@ public StructurePipRenderingState( y1, scale, ambientOcclusion, + glitched, pose3D, pose, scissorArea, PictureInPictureRenderState.getBounds(Mth.floor(x0), Mth.floor(y0), Mth.floor(x1), Mth.floor(y1), scissorArea) ); } - - @Override - public int x0() { - return Mth.floor(fx0); - } - - @Override - public int y0() { - return Mth.floor(fy0); - } - - @Override - public int x1() { - return Mth.floor(fx1); - } - - @Override - public int y1() { - return Mth.floor(fy1); - } } diff --git a/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/glitch.fsh b/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/glitch.fsh new file mode 100644 index 00000000..3deee49a --- /dev/null +++ b/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/glitch.fsh @@ -0,0 +1,51 @@ +#version 330 + +uniform sampler2D DiffuseSampler; + +layout(std140) uniform GlitchParameters { + vec2 InSize; + float GameTime; +}; + +in vec2 texCoord; +out vec4 fragColor; + +float hash(vec2 p) { + return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); +} + +void main() { + vec4 color = texture(DiffuseSampler, texCoord); + + // 亮度提取 — 用于蓝色染色混合 + float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114)); + + // 扫描线间距与行号 + float lineSpacing = 4.0; + float lineY = floor((texCoord.y * InSize.y) / lineSpacing); + + // 基于行号和时间变化的随机值 + float lineHash = hash(vec2(lineY, floor(GameTime * 3.0))); + + // 扫描线亮度变化 (0.7 ~ 1.0) + float scanBrightness = 0.7 + 0.3 * lineHash; + + // 约30%的扫描线有水平抖动 + float jitterStrength = 2.0; + float jitter = (lineHash - 0.5) * 2.0 * jitterStrength / InSize.x; + float shouldJitter = step(0.7, hash(vec2(lineY, 42.0))); + + // 带水平偏移的采样 + vec2 jitteredCoord = texCoord + vec2(jitter * shouldJitter, 0.0); + vec4 jitteredColor = texture(DiffuseSampler, jitteredCoord); + + // 蓝色染色 + vec3 blueTint = vec3(0.2, 0.45, 1.0); + float jitteredLum = dot(jitteredColor.rgb, vec3(0.299, 0.587, 0.114)); + vec3 finalColor = mix(jitteredColor.rgb, blueTint * jitteredLum, 0.75); + + // 应用扫描线亮度 + finalColor *= scanBrightness; + + fragColor = vec4(finalColor, 0.85 * color.a); +} \ No newline at end of file diff --git a/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java b/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java index 1be49ede..34b1dad9 100644 --- a/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java +++ b/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java @@ -199,6 +199,7 @@ public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mo startY + 16 * 4 + 144, 18, true, + true, poseStack ); graphics.pose().popMatrix(); From ba48c687b8912b3796d0a1fcb41d9b213891fbbf Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Wed, 17 Jun 2026 03:20:46 +0800 Subject: [PATCH 2/2] code cleanup --- .../java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java | 1 - .../dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java index 02a2f536..373ac61a 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/ALRPostEffects.java @@ -2,7 +2,6 @@ import dev.anvilcraft.lib.v2.rendering.bloom.BloomPostEffect; import dev.anvilcraft.lib.v2.rendering.event.MainTargetResizeEvent; -import dev.anvilcraft.lib.v2.rendering.glitch.GlitchParametersUbo; import dev.anvilcraft.lib.v2.rendering.glitch.GlitchPostEffect; import lombok.Getter; import net.minecraft.client.Minecraft; diff --git a/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java b/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java index 34b1dad9..f3993c6a 100644 --- a/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java +++ b/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/screen/GuiTestScreen.java @@ -2,8 +2,6 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.textures.GpuSampler; -import com.mojang.blaze3d.textures.GpuTexture; -import com.mojang.blaze3d.textures.GpuTextureView; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; import dev.anvilcraft.lib.v2.rendering.extension.blaze3d.ALRCommandEncoderExtension;