From d7609de711c10850fd1e4f1a91f27dfd13e45ab0 Mon Sep 17 00:00:00 2001 From: ZhuRuoLing Date: Fri, 20 Dec 2024 23:22:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BF=80=E5=85=89=E5=88=86=E5=8C=BA=E5=9D=97?= =?UTF-8?q?=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/renderer/laser/LaserRenderer.java | 189 +++++++++++------- .../anvilcraft/mixin/LevelRendererMixin.java | 4 +- 2 files changed, 118 insertions(+), 75 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java index 0b93784e3..f250f0c24 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/renderer/laser/LaserRenderer.java @@ -4,15 +4,12 @@ import com.mojang.blaze3d.shaders.Uniform; import com.mojang.blaze3d.systems.RenderSystem; 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.VertexBuffer; import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.blaze3d.vertex.VertexSorting; import dev.dubhe.anvilcraft.api.LaserStateAccess; -import dev.dubhe.anvilcraft.client.init.ModRenderTargets; import dev.dubhe.anvilcraft.client.init.ModRenderTypes; import dev.dubhe.anvilcraft.client.renderer.RenderState; import lombok.EqualsAndHashCode; @@ -22,7 +19,9 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderInstance; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.phys.Vec3; +import org.apache.commons.compress.utils.Lists; import org.joml.Matrix4f; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15C; @@ -32,6 +31,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; @@ -54,13 +54,9 @@ public class LaserRenderer { private final Queue compileQueue = new ConcurrentLinkedDeque<>(); @Getter private static LaserRenderer instance; - private final Map buffers = Arrays.stream(SUPPORTED_RENDERTYPES) - .collect(Collectors.toMap( - Function.identity(), - it -> new VertexBuffer(VertexBuffer.Usage.STATIC) - )); - private Map compileResultMap = new HashMap<>(); + private final Map> buffers = new HashMap<>(); + private Map> compileResultMap = new HashMap<>(); @SuppressWarnings("unused") private final ClientLevel level; @@ -90,9 +86,22 @@ public void runTasks() { } } + private Map getBufferForChunk(ChunkPos chunkPos) { + if (buffers.containsKey(chunkPos)) { + return buffers.get(chunkPos); + } + Map vb = Arrays.stream(SUPPORTED_RENDERTYPES) + .collect(Collectors.toMap( + Function.identity(), + it -> new VertexBuffer(VertexBuffer.Usage.STATIC) + )); + buffers.put(chunkPos, vb); + return vb; + } + public void releaseBuffers() { - buffers.values().forEach(VertexBuffer::close); - compileResultMap.values().forEach(CompileResult::free); + buffers.values().forEach(it -> it.values().forEach(VertexBuffer::close)); + compileResultMap.values().forEach(it -> it.values().forEach(CompileResult::free)); valid = false; } @@ -123,10 +132,20 @@ public void renderBloomed(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { if (isEmpty) return; Window window = Minecraft.getInstance().getWindow(); Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); - for (RenderType bloomRendertype : BLOOM_RENDERTYPES) { - VertexBuffer vb = buffers.get(bloomRendertype); - RenderState.bloomStage(); - renderLayer(bloomRendertype, vb, frustumMatrix, projectionMatrix, cameraPosition, window); + for (Map.Entry> chunkPosMapEntry : buffers.entrySet()) { + ChunkPos chunkPos = chunkPosMapEntry.getKey(); + int renderDistance = Minecraft.getInstance().options.getEffectiveRenderDistance() * 16; + if (cameraPosition.distanceTo(new Vec3(chunkPos.x * 16, cameraPosition.y, chunkPos.z * 16)) > renderDistance) { + continue; + } + Map bufferMap = chunkPosMapEntry.getValue(); + Map compileResultMap = this.compileResultMap.get(chunkPos); + if (compileResultMap == null) continue; + for (RenderType bloomRendertype : BLOOM_RENDERTYPES) { + VertexBuffer vb = bufferMap.get(bloomRendertype); + RenderState.bloomStage(); + renderLayer(bloomRendertype, vb, frustumMatrix, projectionMatrix, cameraPosition, window, compileResultMap); + } } } @@ -135,10 +154,20 @@ public void render(Matrix4f frustumMatrix, Matrix4f projectionMatrix) { if (isEmpty) return; Window window = Minecraft.getInstance().getWindow(); Vec3 cameraPosition = minecraft.gameRenderer.getMainCamera().getPosition(); - for (RenderType renderType : SUPPORTED_RENDERTYPES) { - VertexBuffer vb = buffers.get(renderType); - RenderState.levelStage(); - renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window); + for (Map.Entry> chunkPosMapEntry : buffers.entrySet()) { + ChunkPos chunkPos = chunkPosMapEntry.getKey(); + int renderDistance = Minecraft.getInstance().options.getEffectiveRenderDistance() * 16; + if (cameraPosition.distanceTo(new Vec3(chunkPos.x * 16, cameraPosition.y, chunkPos.z * 16)) > renderDistance) { + continue; + } + Map bufferMap = chunkPosMapEntry.getValue(); + Map compileResultMap = this.compileResultMap.get(chunkPos); + if (compileResultMap == null) continue; + for (RenderType renderType : SUPPORTED_RENDERTYPES) { + VertexBuffer vb = bufferMap.get(renderType); + RenderState.levelStage(); + renderLayer(renderType, vb, frustumMatrix, projectionMatrix, cameraPosition, window, compileResultMap); + } } } @@ -148,7 +177,8 @@ private void renderLayer( Matrix4f frustumMatrix, Matrix4f projectionMatrix, Vec3 cameraPosition, - Window window + Window window, + Map compileResultMap ) { CompileResult compileResult = compileResultMap.get(renderType); renderType.setupRenderState(); @@ -173,11 +203,6 @@ private void renderLayer( renderType.clearRenderState(); } - private VertexSorting createVertexSorting() { - Vec3 cameraPos = minecraft.gameRenderer.getMainCamera().getPosition(); - return VertexSorting.byDistance(cameraPos.toVector3f()); - } - public void clear() { } @@ -187,63 +212,79 @@ private class RebuildTask implements Runnable { @Override public void run() { lastRebuildTask = this; - Map compileResultMap = new HashMap<>(); + Map> compileResultMap = new HashMap<>(); PoseStack poseStack = new PoseStack(); LaserRenderer.this.isEmpty = true; - for (RenderType renderType : SUPPORTED_RENDERTYPES) { - if (cancelled) return; - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder bufferBuilder = tesselator.begin(renderType.mode, renderType.format); - long ptr = tesselator.buffer.pointer; - int offsetBeforeCompile = tesselator.buffer.writeOffset; - for (LaserStateAccess laserBlockEntity : new ArrayList<>(laserBlockEntities)) { + Map> groupedLaserStates = new HashMap<>(); + for (LaserStateAccess laserBlockEntity : laserBlockEntities) { + groupedLaserStates.computeIfAbsent(new ChunkPos(laserBlockEntity.getBlockPos()), it -> Lists.newArrayList()) + .add(laserBlockEntity); + } + for (Map.Entry> chunkPosListEntry : groupedLaserStates.entrySet()) { + ChunkPos chunkPos = chunkPosListEntry.getKey(); + List group = chunkPosListEntry.getValue(); + for (RenderType renderType : SUPPORTED_RENDERTYPES) { if (cancelled) return; - poseStack.pushPose(); - BlockPos pos = laserBlockEntity.getBlockPos(); - poseStack.translate( - pos.getX(), - pos.getY(), - pos.getZ() - ); - LaserState laserState = LaserState.create(laserBlockEntity, poseStack); - if (laserState != null && laserState.laserLevel() > 0) { - float width = LaserCompiler.laserWidth(laserState); - LaserCompiler.compileStage( - laserState, - bufferBuilder, - renderType, - width + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder bufferBuilder = tesselator.begin(renderType.mode, renderType.format); + long ptr = tesselator.buffer.pointer; + int offsetBeforeCompile = tesselator.buffer.writeOffset; + for (LaserStateAccess laserBlockEntity : new ArrayList<>(group)) { + if (cancelled) return; + poseStack.pushPose(); + BlockPos pos = laserBlockEntity.getBlockPos(); + poseStack.translate( + pos.getX(), + pos.getY(), + pos.getZ() ); + LaserState laserState = LaserState.create(laserBlockEntity, poseStack); + if (laserState != null && laserState.laserLevel() > 0) { + float width = LaserCompiler.laserWidth(laserState); + LaserCompiler.compileStage( + laserState, + bufferBuilder, + renderType, + width + ); + } + poseStack.popPose(); } - poseStack.popPose(); - } - if (bufferBuilder.vertices > 0) { - LaserRenderer.this.isEmpty = false; - } - int compiledVertices = bufferBuilder.vertices * bufferBuilder.format.getVertexSize(); - long allocated = ALLOCATOR.malloc(compiledVertices); - MemoryUtil.memCopy(ptr + offsetBeforeCompile, allocated, compiledVertices); - MeshData mesh = bufferBuilder.build(); - if (mesh != null) { - mesh.close(); + if (bufferBuilder.vertices > 0) { + LaserRenderer.this.isEmpty = false; + } + int compiledVertices = bufferBuilder.vertices * bufferBuilder.format.getVertexSize(); + long allocated = ALLOCATOR.malloc(compiledVertices); + MemoryUtil.memCopy(ptr + offsetBeforeCompile, allocated, compiledVertices); + MeshData mesh = bufferBuilder.build(); + if (mesh != null) { + mesh.close(); + } + CompileResult compileResult = new CompileResult( + renderType, + bufferBuilder.vertices, + bufferBuilder.format.getVertexSize(), + allocated, + renderType.mode.indexCount(bufferBuilder.vertices) + ); + compileResultMap.computeIfAbsent(chunkPos, it -> new HashMap<>()) + .put(renderType, compileResult); } - CompileResult compileResult = new CompileResult( - renderType, - bufferBuilder.vertices, - bufferBuilder.format.getVertexSize(), - allocated, - renderType.mode.indexCount(bufferBuilder.vertices) - ); - compileResultMap.put(renderType, compileResult); } - LaserRenderer.this.compileResultMap.values().forEach(CompileResult::free); + + LaserRenderer.this.compileResultMap + .values() + .forEach(it -> it.values().forEach(CompileResult::free)); + LaserRenderer.this.compileResultMap = compileResultMap; - compileResultMap.forEach((renderType, compileResult) -> { - pendingUploads.add(() -> { - VertexBuffer vb = buffers.get(renderType); - compileResult.upload(vb); - }); - }); + compileResultMap.forEach((chunkPos, map) -> + map.forEach((renderType, compileResult) -> + pendingUploads.add(() -> { + VertexBuffer vb = getBufferForChunk(chunkPos).get(renderType); + compileResult.upload(vb); + }) + ) + ); lastRebuildTask = null; } diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java index 0b84343fb..a920de142 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/LevelRendererMixin.java @@ -45,7 +45,8 @@ public abstract class LevelRendererMixin { method = "renderLevel", at = @At( value = "INVOKE", - target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;" + target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", + ordinal = 2 ) ) void renderEnhancedTransmitterLines( @@ -105,6 +106,7 @@ void bloomPostProcess( if (ModRenderTargets.getBloomTarget() != null) { ModRenderTargets.getBloomTarget().copyDepthFrom(Minecraft.getInstance().getMainRenderTarget()); } + RenderSystem.enableDepthTest(); LaserRenderer.getInstance().renderBloomed(frustumMatrix, projectionMatrix); RenderTarget mcInput = ModShaders.getBloomChain().getTempTarget("mcinput"); mcInput.setClearColor(0, 0, 0, 0);