From 2e0d4591898f879b9ad0457491b09f7a9b2b31e1 Mon Sep 17 00:00:00 2001 From: spiralhalo Date: Thu, 29 Apr 2021 01:50:40 +0700 Subject: [PATCH 1/5] Alter "moved one block" frustum update requirement --- .../java/grondag/canvas/render/TerrainFrustum.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/grondag/canvas/render/TerrainFrustum.java b/src/main/java/grondag/canvas/render/TerrainFrustum.java index 3752b1083..3616bd57e 100644 --- a/src/main/java/grondag/canvas/render/TerrainFrustum.java +++ b/src/main/java/grondag/canvas/render/TerrainFrustum.java @@ -166,20 +166,20 @@ public void prepare(Matrix4f modelMatrix, float tickDelta, Camera camera) { final double z = vec.z; final long cameraBlockPos = camera.getBlockPos().asLong(); - boolean movedOneBlock = false; + boolean cameraMoved = false; if (cameraBlockPos != lastCameraBlockPos) { lastCameraBlockPos = cameraBlockPos; - movedOneBlock = true; + cameraMoved = true; } else { - // could move 1.0 or more diagonally within same block pos + // the assumption that occlusion data only needs updating if the camera moves 1 block doesn't hold up final double dx = x - lastPositionX; final double dy = y - lastPositionY; final double dz = z - lastPositionZ; - movedOneBlock = dx * dx + dy * dy + dz * dz >= 1.0D; + cameraMoved = dx * dx + dy * dy + dz * dz >= 0.01D; } - if (movedOneBlock) { + if (cameraMoved) { ++positionVersion; lastPositionX = x; lastPositionY = y; @@ -201,7 +201,7 @@ public void prepare(Matrix4f modelMatrix, float tickDelta, Camera camera) { modelMatrixUpdate = dPitch * dPitch + dYaw * dYaw >= paddingFov * paddingFov; } - if (movedOneBlock || modelMatrixUpdate || !projectionMatrixExt.matches(occlusionProjMat)) { + if (cameraMoved || modelMatrixUpdate || !projectionMatrixExt.matches(occlusionProjMat)) { ++viewVersion; lastViewX = x; From cb606243ffa442ac38572660689ef972338a40d8 Mon Sep 17 00:00:00 2001 From: spiralhalo Date: Fri, 30 Apr 2021 23:34:49 +0700 Subject: [PATCH 2/5] Load material program samplers, various sampler helpers --- .../canvas/material/state/RenderState.java | 12 ++++ .../grondag/canvas/pipeline/Pipeline.java | 7 ++ .../canvas/pipeline/ProgramTextureData.java | 45 +++++++++++++ .../config/MaterialProgramConfig.java | 28 ++++++++ .../canvas/pipeline/pass/ProgramPass.java | 43 ++---------- .../grondag/canvas/shader/ProcessShader.java | 11 +--- .../canvas/shader/SamplerTypeHelper.java | 66 +++++++++++++++++++ .../grondag/canvas/shader/ShaderData.java | 8 +++ .../grondag/canvas/texture/TextureData.java | 1 + 9 files changed, 174 insertions(+), 47 deletions(-) create mode 100644 src/main/java/grondag/canvas/pipeline/ProgramTextureData.java create mode 100644 src/main/java/grondag/canvas/shader/SamplerTypeHelper.java diff --git a/src/main/java/grondag/canvas/material/state/RenderState.java b/src/main/java/grondag/canvas/material/state/RenderState.java index 3ae6697c8..b94ac6455 100644 --- a/src/main/java/grondag/canvas/material/state/RenderState.java +++ b/src/main/java/grondag/canvas/material/state/RenderState.java @@ -177,6 +177,18 @@ private void enableMaterial(int x, int y, int z) { CanvasTextureState.activeTextureUnit(TextureData.MC_SPRITE_ATLAS); } + if (Pipeline.config().materialProgram.samplerNames.length > 0) { + // Activate non-frex material program textures + for (int i = 0; i < Pipeline.config().materialProgram.samplerNames.length; i++) { + final int bindTarget = Pipeline.materialTextures().texTargets[i]; + final int bind = Pipeline.materialTextures().texIds[i]; + CanvasTextureState.activeTextureUnit(TextureData.PROGRAM_SAMPLERS + i); + CanvasTextureState.bindTexture(bindTarget, bind); + assert CanvasGlHelper.checkError(); + } + CanvasTextureState.activeTextureUnit(TextureData.MC_SPRITE_ATLAS); + } + texture.enable(blur); assert CanvasGlHelper.checkError(); diff --git a/src/main/java/grondag/canvas/pipeline/Pipeline.java b/src/main/java/grondag/canvas/pipeline/Pipeline.java index 5cd7bf5e5..c72bb6877 100644 --- a/src/main/java/grondag/canvas/pipeline/Pipeline.java +++ b/src/main/java/grondag/canvas/pipeline/Pipeline.java @@ -40,6 +40,7 @@ public class Pipeline { private static boolean reload = true; private static int lastWidth; private static int lastHeight; + private static ProgramTextureData materialTextures; static Pass[] onWorldRenderStart = { }; static Pass[] afterRenderHand = { }; static Pass[] fabulous = { }; @@ -103,6 +104,10 @@ public static PipelineFramebuffer getFramebuffer(String name) { return FRAMEBUFFERS.get(name); } + public static ProgramTextureData materialTextures() { + return materialTextures; + } + static boolean needsReload() { return reload; } @@ -229,6 +234,8 @@ private static void activateInner(PrimaryFrameBuffer primary, int width, int hei defaultZenithAngle = 0f; } + materialTextures = new ProgramTextureData(config.materialProgram.samplerImages); + isFabulous = config.fabulosity != null; if (isFabulous) { diff --git a/src/main/java/grondag/canvas/pipeline/ProgramTextureData.java b/src/main/java/grondag/canvas/pipeline/ProgramTextureData.java new file mode 100644 index 000000000..27614141b --- /dev/null +++ b/src/main/java/grondag/canvas/pipeline/ProgramTextureData.java @@ -0,0 +1,45 @@ +package grondag.canvas.pipeline; + +import grondag.canvas.pipeline.Image; +import grondag.canvas.pipeline.Pipeline; +import grondag.canvas.pipeline.config.ImageConfig; +import grondag.canvas.pipeline.config.util.NamedDependency; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.texture.AbstractTexture; +import net.minecraft.util.Identifier; +import org.lwjgl.opengl.GL46; + +public class ProgramTextureData { + final public int[] texIds; + final public int[] texTargets; + + public ProgramTextureData(NamedDependency[] samplerImages) { + texIds = new int[samplerImages.length]; + texTargets = new int[samplerImages.length]; + + for (int i = 0; i < samplerImages.length; ++i) { + final String imageName = samplerImages[i].name; + + int imageBind = 0; + int bindTarget = GL46.GL_TEXTURE_2D; + + if (imageName.contains(":")) { + final AbstractTexture tex = MinecraftClient.getInstance().getTextureManager().getTexture(new Identifier(imageName)); + + if (tex != null) { + imageBind = tex.getGlId(); + } + } else { + final Image img = Pipeline.getImage(imageName); + + if (img != null) { + imageBind = img.glId(); + bindTarget = img.config.target; + } + } + + texIds[i] = imageBind; + texTargets[i] = bindTarget; + } + } +} diff --git a/src/main/java/grondag/canvas/pipeline/config/MaterialProgramConfig.java b/src/main/java/grondag/canvas/pipeline/config/MaterialProgramConfig.java index 7e72fc2fa..5f0a13eb4 100644 --- a/src/main/java/grondag/canvas/pipeline/config/MaterialProgramConfig.java +++ b/src/main/java/grondag/canvas/pipeline/config/MaterialProgramConfig.java @@ -16,16 +16,44 @@ package grondag.canvas.pipeline.config; +import blue.endless.jankson.JsonArray; import blue.endless.jankson.JsonObject; +import grondag.canvas.CanvasMod; import grondag.canvas.pipeline.config.util.ConfigContext; +import grondag.canvas.pipeline.config.util.NamedDependency; public class MaterialProgramConfig extends ProgramConfig { + public final NamedDependency[] samplerImages; + public MaterialProgramConfig(ConfigContext ctx, JsonObject config) { super(ctx, config, "materialProgram"); + + if (!config.containsKey("samplerImages")) { + samplerImages = new NamedDependency[0]; + } else { + final JsonArray names = config.get(JsonArray.class, "samplerImages"); + final int limit = names.size(); + samplerImages = new NamedDependency[limit]; + + for (int i = 0; i < limit; ++i) { + samplerImages[i] = ctx.images.dependOn(names.get(i)); + } + } } public MaterialProgramConfig(ConfigContext ctx) { super(ctx, "materialProgram", "canvas:shaders/pipeline/standard.vert", "canvas:shaders/pipeline/standard.vert"); + samplerImages = new NamedDependency[0]; + } + + @Override + public boolean validate() { + if (samplerImages.length != samplerNames.length) { + CanvasMod.LOG.warn(String.format("Material program is invalid because it expects %d samplers but the pass binds %d.", + samplerNames.length, samplerImages.length)); + return false; + } + return super.validate(); } } diff --git a/src/main/java/grondag/canvas/pipeline/pass/ProgramPass.java b/src/main/java/grondag/canvas/pipeline/pass/ProgramPass.java index 2818f1e24..8dfddaac9 100644 --- a/src/main/java/grondag/canvas/pipeline/pass/ProgramPass.java +++ b/src/main/java/grondag/canvas/pipeline/pass/ProgramPass.java @@ -18,15 +18,10 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; +import grondag.canvas.pipeline.ProgramTextureData; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL21; -import org.lwjgl.opengl.GL46; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.texture.AbstractTexture; -import net.minecraft.util.Identifier; - -import grondag.canvas.pipeline.Image; import grondag.canvas.pipeline.Pipeline; import grondag.canvas.pipeline.PipelineManager; import grondag.canvas.pipeline.config.PassConfig; @@ -34,8 +29,7 @@ import grondag.canvas.shader.ProcessShader; class ProgramPass extends Pass { - final int[] binds; - final int[] bindTargets; + final ProgramTextureData textures; ProcessShader shader; @@ -43,34 +37,7 @@ class ProgramPass extends Pass { super(config); shader = Pipeline.getShader(config.program.name); - - binds = new int[config.samplerImages.length]; - bindTargets = new int[config.samplerImages.length]; - - for (int i = 0; i < config.samplerImages.length; ++i) { - final String imageName = config.samplerImages[i].name; - - int imageBind = 0; - int bindTarget = GL46.GL_TEXTURE_2D; - - if (imageName.contains(":")) { - final AbstractTexture tex = MinecraftClient.getInstance().getTextureManager().getTexture(new Identifier(imageName)); - - if (tex != null) { - imageBind = tex.getGlId(); - } - } else { - final Image img = Pipeline.getImage(imageName); - - if (img != null) { - imageBind = img.glId(); - bindTarget = img.config.target; - } - } - - binds[i] = imageBind; - bindTargets[i] = bindTarget; - } + textures = new ProgramTextureData(config.samplerImages); } @Override @@ -91,11 +58,11 @@ public void run(int width, int height) { PipelineManager.setProjection(width, height); RenderSystem.viewport(0, 0, width, height); - final int slimit = binds.length; + final int slimit = textures.texIds.length; for (int i = 0; i < slimit; ++i) { CanvasTextureState.activeTextureUnit(GL21.GL_TEXTURE0 + i); - CanvasTextureState.bindTexture(bindTargets[i], binds[i]); + CanvasTextureState.bindTexture(textures.texTargets[i], textures.texIds[i]); } shader.activate().lod(config.lod).size(width, height); diff --git a/src/main/java/grondag/canvas/shader/ProcessShader.java b/src/main/java/grondag/canvas/shader/ProcessShader.java index a83bd56cf..68a51b25b 100644 --- a/src/main/java/grondag/canvas/shader/ProcessShader.java +++ b/src/main/java/grondag/canvas/shader/ProcessShader.java @@ -71,15 +71,8 @@ public ProcessShader activate() { for (final String samplerName : samplers) { final int n = tex++; - - // PERF: should probably match on any sampler uniform type - names must be unique anyway - if (program.containsUniformSpec("sampler2DArray", samplerName)) { - program.uniformSampler("sampler2DArray", samplerName, UniformRefreshFrequency.ON_LOAD, u -> u.set(n)); - } else if (program.containsUniformSpec("sampler2DArrayShadow", samplerName)) { - program.uniformSampler("sampler2DArrayShadow", samplerName, UniformRefreshFrequency.ON_LOAD, u -> u.set(n)); - } else if (program.containsUniformSpec("sampler2D", samplerName)) { - program.uniformSampler("sampler2D", samplerName, UniformRefreshFrequency.ON_LOAD, u -> u.set(n)); - } + final String samplerType = SamplerTypeHelper.getSamplerType(program, samplerName); + program.uniformSampler(samplerType, samplerName, UniformRefreshFrequency.ON_LOAD, u -> u.set(n)); } program.load(); diff --git a/src/main/java/grondag/canvas/shader/SamplerTypeHelper.java b/src/main/java/grondag/canvas/shader/SamplerTypeHelper.java new file mode 100644 index 000000000..5f46b0c6e --- /dev/null +++ b/src/main/java/grondag/canvas/shader/SamplerTypeHelper.java @@ -0,0 +1,66 @@ +package grondag.canvas.shader; + +import grondag.canvas.shader.GlProgram; +import grondag.frex.api.material.UniformRefreshFrequency; + +public class SamplerTypeHelper { + public static final String[] samplerTypes = new String[]{ + // float samplers + "sampler1D", + "sampler2D", + "sampler3D", + "samplerCube", + "sampler2DRect", + "sampler1DArray", + "sampler2DArray", + "samplerCubeArray", + "samplerBuffer", + "sampler2DMS", + "sampler2DMSArray", + + // integer samplers + "isampler1D", + "isampler2D", + "isampler3D", + "isamplerCube", + "isampler2DRect", + "isampler1DArray", + "isampler2DArray", + "isamplerCubeArray", + "isamplerBuffer", + "isampler2DMS", + "isampler2DMSArray", + + // unsigned integer samplers + "usampler1D", + "usampler2D", + "usampler3D", + "usamplerCube", + "usampler2DRect", + "usampler1DArray", + "usampler2DArray", + "usamplerCubeArray", + "usamplerBuffer", + "usampler2DMS", + "usampler2DMSArray", + + // shadow samplers + "sampler1DShadow", + "sampler2DShadow", + "samplerCubeShadow", + "sampler2DRectShadow", + "sampler1DArrayShadow", + "sampler2DArrayShadow", + "samplerCubeArrayShadow", + }; + + public static String getSamplerType(GlProgram program, String samplerName) { + for (String type:samplerTypes) { + if (program.containsUniformSpec(type, samplerName)) { + return type; + } + } + + return "sampler2D"; + } +} diff --git a/src/main/java/grondag/canvas/shader/ShaderData.java b/src/main/java/grondag/canvas/shader/ShaderData.java index c532ff06a..dd260224a 100644 --- a/src/main/java/grondag/canvas/shader/ShaderData.java +++ b/src/main/java/grondag/canvas/shader/ShaderData.java @@ -18,6 +18,7 @@ import java.util.function.Consumer; +import grondag.canvas.pipeline.Pipeline; import org.lwjgl.opengl.GL21; import net.minecraft.util.Identifier; @@ -57,6 +58,13 @@ public class ShaderData { program.uniformSampler("sampler2D", "_cvu_spriteInfo", UniformRefreshFrequency.ON_LOAD, u -> u.set(TextureData.SPRITE_INFO - GL21.GL_TEXTURE0)); program.uniformSampler("sampler2D", "_cvu_materialInfo", UniformRefreshFrequency.ON_LOAD, u -> u.set(TextureData.MATERIAL_INFO - GL21.GL_TEXTURE0)); + + for (int i = 0; i < Pipeline.config().materialProgram.samplerNames.length; i++) { + final int texId = i; + final String samplerName = Pipeline.config().materialProgram.samplerNames[i]; + final String samplerType = SamplerTypeHelper.getSamplerType(program, samplerName); + program.uniformSampler(samplerType, samplerName, UniformRefreshFrequency.ON_LOAD, u -> u.set(TextureData.PROGRAM_SAMPLERS - GL21.GL_TEXTURE0 + texId)); + } }; public static final Consumer COMMON_UNIFORM_SETUP = program -> { diff --git a/src/main/java/grondag/canvas/texture/TextureData.java b/src/main/java/grondag/canvas/texture/TextureData.java index 68ce872f2..cb8ab04f0 100644 --- a/src/main/java/grondag/canvas/texture/TextureData.java +++ b/src/main/java/grondag/canvas/texture/TextureData.java @@ -32,4 +32,5 @@ public class TextureData { // want these outside of the range managed by Mojang's damn GlStateManager public static final int SHADOWMAP = GL21.GL_TEXTURE12; public static final int SHADOWMAP_TEXTURE = GL21.GL_TEXTURE13; + public static final int PROGRAM_SAMPLERS = GL21.GL_TEXTURE14; } From 1ced025b3b8262e822506a71468d2b76f9d9381d Mon Sep 17 00:00:00 2001 From: spiralhalo Date: Sat, 1 May 2021 12:46:42 +0700 Subject: [PATCH 3/5] Load resource textures when needed by the pipeline --- .../canvas/pipeline/ProgramTextureData.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/java/grondag/canvas/pipeline/ProgramTextureData.java b/src/main/java/grondag/canvas/pipeline/ProgramTextureData.java index 27614141b..c9c32020e 100644 --- a/src/main/java/grondag/canvas/pipeline/ProgramTextureData.java +++ b/src/main/java/grondag/canvas/pipeline/ProgramTextureData.java @@ -1,11 +1,11 @@ package grondag.canvas.pipeline; -import grondag.canvas.pipeline.Image; -import grondag.canvas.pipeline.Pipeline; import grondag.canvas.pipeline.config.ImageConfig; import grondag.canvas.pipeline.config.util.NamedDependency; import net.minecraft.client.MinecraftClient; import net.minecraft.client.texture.AbstractTexture; +import net.minecraft.client.texture.ResourceTexture; +import net.minecraft.client.texture.TextureManager; import net.minecraft.util.Identifier; import org.lwjgl.opengl.GL46; @@ -24,7 +24,7 @@ public ProgramTextureData(NamedDependency[] samplerImages) { int bindTarget = GL46.GL_TEXTURE_2D; if (imageName.contains(":")) { - final AbstractTexture tex = MinecraftClient.getInstance().getTextureManager().getTexture(new Identifier(imageName)); + final AbstractTexture tex = tryLoadResourceTexture(new Identifier(imageName)); if (tex != null) { imageBind = tex.getGlId(); @@ -42,4 +42,20 @@ public ProgramTextureData(NamedDependency[] samplerImages) { texTargets[i] = bindTarget; } } + + private static AbstractTexture tryLoadResourceTexture(Identifier identifier) { + final TextureManager textureManager = MinecraftClient.getInstance().getTextureManager(); + final AbstractTexture existingTexture = textureManager.getTexture(identifier); + + if (existingTexture != null) { + return existingTexture; + } else { + // NB: `registerTexture` will replace the texture with MissingSprite if not found. This is useful for + // pipeline developers. + // Additionally, TextureManager will handle removing missing textures on resource reload. + ResourceTexture resourceTexture = new ResourceTexture(identifier); + textureManager.registerTexture(identifier, resourceTexture); + return textureManager.getTexture(identifier); + } + } } From fdc76e15d1ec8eeadbcf7b713694e168e3336d57 Mon Sep 17 00:00:00 2001 From: spiralhalo Date: Thu, 6 May 2021 00:08:41 +0700 Subject: [PATCH 4/5] Render first person player shadow --- .../canvas/render/CanvasWorldRenderer.java | 26 ++++++++++++++----- .../canvas/render/SkyShadowRenderer.java | 7 ++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/grondag/canvas/render/CanvasWorldRenderer.java b/src/main/java/grondag/canvas/render/CanvasWorldRenderer.java index 5edf41a66..d991457de 100644 --- a/src/main/java/grondag/canvas/render/CanvasWorldRenderer.java +++ b/src/main/java/grondag/canvas/render/CanvasWorldRenderer.java @@ -157,6 +157,7 @@ public class CanvasWorldRenderer extends WorldRenderer { private final RenderContextState contextState = new RenderContextState(); public final CanvasImmediate worldRenderImmediate = new CanvasImmediate(new BufferBuilder(256), CanvasImmediate.entityBuilders(), contextState); + private final CanvasImmediate shadowExtrasProvider = new CanvasImmediate(new BufferBuilder(256), CanvasImmediate.entityBuilders(), contextState); private final CanvasParticleRenderer particleRenderer = new CanvasParticleRenderer(); public final WorldRenderContextImpl eventContext = new WorldRenderContextImpl(); @@ -494,16 +495,22 @@ public void renderWorld(MatrixStack viewMatrixStack, MatrixStack identityStack, blockContext.collectors = immediate.collectors; SkyShadowRenderer.suppressEntityShadows(mc); - // PERF: find way to reduce allocation for this and MatrixStack generally while (entities.hasNext()) { final Entity entity = entities.next(); - if ((!entityRenderDispatcher.shouldRender(entity, frustum, cameraX, cameraY, cameraZ) && !entity.hasPassengerDeep(mc.player)) - || (entity == camera.getFocusedEntity() && !FirstPersonModelHolder.handler.isThirdPerson(this, camera, viewMatrixStack) && (!(camera.getFocusedEntity() instanceof LivingEntity) || !((LivingEntity) camera.getFocusedEntity()).isSleeping())) - || (entity instanceof ClientPlayerEntity && camera.getFocusedEntity() != entity)) { + boolean isFirstPersonPlayer = false; + if (!entityRenderDispatcher.shouldRender(entity, frustum, cameraX, cameraY, cameraZ) && !entity.hasPassengerDeep(mc.player)) { continue; } + if ((entity == camera.getFocusedEntity() && !FirstPersonModelHolder.handler.isThirdPerson(this, camera, viewMatrixStack) && (!(camera.getFocusedEntity() instanceof LivingEntity) || !((LivingEntity) camera.getFocusedEntity()).isSleeping())) + || (entity instanceof ClientPlayerEntity && camera.getFocusedEntity() != entity)) { + if (Pipeline.skyShadowFbo == null) { + continue; + } + isFirstPersonPlayer = true; + } + ++entityCount; contextState.setCurrentEntity(entity); @@ -515,7 +522,10 @@ public void renderWorld(MatrixStack viewMatrixStack, MatrixStack identityStack, VertexConsumerProvider renderProvider; - if (canDrawEntityOutlines && mc.hasOutline(entity)) { + if (isFirstPersonPlayer) { + // only render as shadow + renderProvider = shadowExtrasProvider; + } else if (canDrawEntityOutlines && mc.hasOutline(entity)) { didRenderOutlines = true; final OutlineVertexConsumerProvider outlineVertexConsumerProvider = bufferBuilders.getOutlineVertexConsumers(); renderProvider = outlineVertexConsumerProvider; @@ -595,9 +605,11 @@ public void renderWorld(MatrixStack viewMatrixStack, MatrixStack identityStack, contextState.setCurrentBlockEntity(null); - try (DrawableBuffer entityBuffer = immediate.prepareDrawable(MaterialTarget.MAIN)) { + try (DrawableBuffer entityBuffer = immediate.prepareDrawable(MaterialTarget.MAIN); + DrawableBuffer shadowExtrasBuffer = shadowExtrasProvider.prepareDrawable(MaterialTarget.MAIN)) { profileSwap(profiler, ProfilerGroup.ShadowMap, "shadow_map"); - SkyShadowRenderer.render(this, cameraX, cameraY, cameraZ, entityBuffer); + SkyShadowRenderer.render(this, cameraX, cameraY, cameraZ, entityBuffer, shadowExtrasBuffer); + shadowExtrasBuffer.close(); profileSwap(profiler, ProfilerGroup.EndWorld, "terrain_solid"); MatrixState.set(MatrixState.REGION); diff --git a/src/main/java/grondag/canvas/render/SkyShadowRenderer.java b/src/main/java/grondag/canvas/render/SkyShadowRenderer.java index 1aa8f9ed8..f1f8ba03f 100644 --- a/src/main/java/grondag/canvas/render/SkyShadowRenderer.java +++ b/src/main/java/grondag/canvas/render/SkyShadowRenderer.java @@ -51,7 +51,7 @@ public static boolean isActive() { return active; } - public static void render(CanvasWorldRenderer canvasWorldRenderer, double cameraX, double cameraY, double cameraZ, DrawableBuffer entityBuffer) { + public static void render(CanvasWorldRenderer canvasWorldRenderer, double cameraX, double cameraY, double cameraZ, DrawableBuffer entityBuffer, DrawableBuffer shadowExtrasBuffer) { if (Pipeline.skyShadowFbo != null) { // Viewport call (or something else) seems to be messing up fixed-function matrix state RenderSystem.pushMatrix(); @@ -61,7 +61,7 @@ public static void render(CanvasWorldRenderer canvasWorldRenderer, double camera for (cascade = 0; cascade < MatrixState.CASCADE_COUNT; ++cascade) { Pipeline.skyShadowFbo.bind(); GL46.glFramebufferTextureLayer(GL46.GL_FRAMEBUFFER, FramebufferInfo.DEPTH_ATTACHMENT, Pipeline.shadowMapDepth, 0, cascade); - renderInner(canvasWorldRenderer, cameraX, cameraY, cameraZ, entityBuffer); + renderInner(canvasWorldRenderer, cameraX, cameraY, cameraZ, entityBuffer, shadowExtrasBuffer); } Pipeline.defaultFbo.bind(); @@ -72,7 +72,7 @@ public static void render(CanvasWorldRenderer canvasWorldRenderer, double camera } } - private static void renderInner(CanvasWorldRenderer canvasWorldRenderer, double cameraX, double cameraY, double cameraZ, DrawableBuffer entityBuffer) { + private static void renderInner(CanvasWorldRenderer canvasWorldRenderer, double cameraX, double cameraY, double cameraZ, DrawableBuffer entityBuffer, DrawableBuffer shadowExtrasBuffer) { Pipeline.skyShadowFbo.clear(); // WIP: will need purpose-specific methods for each frustum/render type @@ -82,6 +82,7 @@ private static void renderInner(CanvasWorldRenderer canvasWorldRenderer, double if (Pipeline.config().skyShadow.allowEntities && MinecraftClient.getInstance().options.entityShadows) { entityBuffer.draw(true); + shadowExtrasBuffer.draw(true); } } From 253a79463554bf334123454f4fcdb723c1d90ce6 Mon Sep 17 00:00:00 2001 From: spiralhalo Date: Thu, 6 May 2021 00:28:20 +0700 Subject: [PATCH 5/5] Shadow provider doesn't need multiple buffers --- .../java/grondag/canvas/buffer/encoding/CanvasImmediate.java | 4 ++++ src/main/java/grondag/canvas/render/CanvasWorldRenderer.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/grondag/canvas/buffer/encoding/CanvasImmediate.java b/src/main/java/grondag/canvas/buffer/encoding/CanvasImmediate.java index a2ccf68ab..5a1959804 100644 --- a/src/main/java/grondag/canvas/buffer/encoding/CanvasImmediate.java +++ b/src/main/java/grondag/canvas/buffer/encoding/CanvasImmediate.java @@ -136,6 +136,10 @@ public static SortedMap entityBuilders() { }); } + public static SortedMap dummyBuilders() { + return new Object2ObjectLinkedOpenHashMap<>(); + } + private static void assignBufferBuilder(Object2ObjectLinkedOpenHashMap builderStorage, RenderLayer layer) { builderStorage.put(layer, new BufferBuilder(layer.getExpectedBufferSize())); } diff --git a/src/main/java/grondag/canvas/render/CanvasWorldRenderer.java b/src/main/java/grondag/canvas/render/CanvasWorldRenderer.java index d991457de..d80dcbefd 100644 --- a/src/main/java/grondag/canvas/render/CanvasWorldRenderer.java +++ b/src/main/java/grondag/canvas/render/CanvasWorldRenderer.java @@ -157,7 +157,7 @@ public class CanvasWorldRenderer extends WorldRenderer { private final RenderContextState contextState = new RenderContextState(); public final CanvasImmediate worldRenderImmediate = new CanvasImmediate(new BufferBuilder(256), CanvasImmediate.entityBuilders(), contextState); - private final CanvasImmediate shadowExtrasProvider = new CanvasImmediate(new BufferBuilder(256), CanvasImmediate.entityBuilders(), contextState); + private final CanvasImmediate shadowExtrasProvider = new CanvasImmediate(new BufferBuilder(256), CanvasImmediate.dummyBuilders(), contextState); private final CanvasParticleRenderer particleRenderer = new CanvasParticleRenderer(); public final WorldRenderContextImpl eventContext = new WorldRenderContextImpl();