From e354ca33b94cefca43f0f3f5ff3cb8ab66d34ce4 Mon Sep 17 00:00:00 2001 From: FiniteReality Date: Sat, 30 Nov 2024 18:38:55 +0000 Subject: [PATCH] Flow stencil information through post chains --- .../framegraph/FrameGraphBuilder.java.patch | 46 ++++++++++++++++++ .../blaze3d/pipeline/RenderTarget.java.patch | 2 +- .../blaze3d/pipeline/TextureTarget.java.patch | 14 ++++++ .../RenderTargetDescriptor.java.patch | 18 +++++++ .../client/renderer/LevelRenderer.java.patch | 10 ++++ .../client/renderer/PostChain.java.patch | 48 +++++++++++++++++++ .../renderer/PostChainConfig.java.patch | 23 +++++++++ .../client/renderer/PostPass.java.patch | 28 +++++++++++ .../resources/META-INF/accesstransformer.cfg | 4 ++ 9 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 patches/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java.patch create mode 100644 patches/com/mojang/blaze3d/pipeline/TextureTarget.java.patch create mode 100644 patches/com/mojang/blaze3d/resource/RenderTargetDescriptor.java.patch create mode 100644 patches/net/minecraft/client/renderer/PostChain.java.patch create mode 100644 patches/net/minecraft/client/renderer/PostChainConfig.java.patch create mode 100644 patches/net/minecraft/client/renderer/PostPass.java.patch diff --git a/patches/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java.patch b/patches/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java.patch new file mode 100644 index 00000000000..b03f4d9e054 --- /dev/null +++ b/patches/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java.patch @@ -0,0 +1,46 @@ +--- a/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java ++++ b/com/mojang/blaze3d/framegraph/FrameGraphBuilder.java +@@ -173,6 +_,11 @@ + public T get() { + return this.resource; + } ++ ++ @Override ++ public ResourceDescriptor getDescriptor() { ++ return null; ++ } + } + + @OnlyIn(Dist.CLIENT) +@@ -211,6 +_,10 @@ + public String toString() { + return this.createdBy != null ? this.holder + "#" + this.version + " (from " + this.createdBy + ")" : this.holder + "#" + this.version; + } ++ ++ public ResourceDescriptor getDescriptor() { ++ return this.holder.getDescriptor(); ++ } + } + + @OnlyIn(Dist.CLIENT) +@@ -265,6 +_,11 @@ + this.physicalResource = null; + } + } ++ ++ @Override ++ public ResourceDescriptor getDescriptor() { ++ return descriptor; ++ } + } + + @OnlyIn(Dist.CLIENT) +@@ -364,5 +_,8 @@ + public String toString() { + return this.name; + } ++ ++ @Nullable ++ public abstract ResourceDescriptor getDescriptor(); + } + } diff --git a/patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch b/patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch index bddf05a9c12..b4990074aef 100644 --- a/patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch +++ b/patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch @@ -128,7 +128,7 @@ return this.depthBufferId; + } + -+ public int getStencilBufferId() { ++ public int getStencilTextureId() { + return this.stencilBufferId; } } diff --git a/patches/com/mojang/blaze3d/pipeline/TextureTarget.java.patch b/patches/com/mojang/blaze3d/pipeline/TextureTarget.java.patch new file mode 100644 index 00000000000..e0661d83e49 --- /dev/null +++ b/patches/com/mojang/blaze3d/pipeline/TextureTarget.java.patch @@ -0,0 +1,14 @@ +--- a/com/mojang/blaze3d/pipeline/TextureTarget.java ++++ b/com/mojang/blaze3d/pipeline/TextureTarget.java +@@ -7,7 +_,10 @@ + @OnlyIn(Dist.CLIENT) + public class TextureTarget extends RenderTarget { + public TextureTarget(int p_166213_, int p_166214_, boolean p_166215_) { +- super(p_166215_); ++ this(p_166213_, p_166214_, p_166215_, false); ++ } ++ public TextureTarget(int p_166213_, int p_166214_, boolean p_166215_, boolean useStencil) { ++ super(p_166215_, useStencil); + RenderSystem.assertOnRenderThreadOrInit(); + this.resize(p_166213_, p_166214_); + } diff --git a/patches/com/mojang/blaze3d/resource/RenderTargetDescriptor.java.patch b/patches/com/mojang/blaze3d/resource/RenderTargetDescriptor.java.patch new file mode 100644 index 00000000000..060e486b3c7 --- /dev/null +++ b/patches/com/mojang/blaze3d/resource/RenderTargetDescriptor.java.patch @@ -0,0 +1,18 @@ +--- a/com/mojang/blaze3d/resource/RenderTargetDescriptor.java ++++ b/com/mojang/blaze3d/resource/RenderTargetDescriptor.java +@@ -6,9 +_,13 @@ + import net.neoforged.api.distmarker.OnlyIn; + + @OnlyIn(Dist.CLIENT) +-public record RenderTargetDescriptor(int width, int height, boolean useDepth) implements ResourceDescriptor { ++public record RenderTargetDescriptor(int width, int height, boolean useDepth, boolean useStencil) implements ResourceDescriptor { ++ public RenderTargetDescriptor(int width, int height, boolean useDepth) { ++ this(width, height, useDepth, false); ++ } ++ + public RenderTarget allocate() { +- return new TextureTarget(this.width, this.height, this.useDepth); ++ return new TextureTarget(this.width, this.height, this.useDepth, this.useStencil); + } + + public void free(RenderTarget p_363223_) { diff --git a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch index f5f9a14c0d7..7c0b716828d 100644 --- a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch @@ -1,5 +1,15 @@ --- a/net/minecraft/client/renderer/LevelRenderer.java +++ b/net/minecraft/client/renderer/LevelRenderer.java +@@ -464,7 +_,8 @@ + this.targets.main = framegraphbuilder.importExternal("main", this.minecraft.getMainRenderTarget()); + int i = this.minecraft.getMainRenderTarget().width; + int j = this.minecraft.getMainRenderTarget().height; +- RenderTargetDescriptor rendertargetdescriptor = new RenderTargetDescriptor(i, j, true); ++ boolean useStencil = this.minecraft.getMainRenderTarget().useStencil; ++ RenderTargetDescriptor rendertargetdescriptor = new RenderTargetDescriptor(i, j, true, useStencil); + PostChain postchain = this.getTransparencyChain(); + if (postchain != null) { + this.targets.translucent = framegraphbuilder.createInternal("translucent", rendertargetdescriptor); @@ -485,7 +_,7 @@ RenderSystem.clear(16640); }); diff --git a/patches/net/minecraft/client/renderer/PostChain.java.patch b/patches/net/minecraft/client/renderer/PostChain.java.patch new file mode 100644 index 00000000000..ba8b1b191e7 --- /dev/null +++ b/patches/net/minecraft/client/renderer/PostChain.java.patch @@ -0,0 +1,48 @@ +--- a/net/minecraft/client/renderer/PostChain.java ++++ b/net/minecraft/client/renderer/PostChain.java +@@ -83,8 +_,8 @@ + abstracttexture.setFilter(flag, false); + postpass.addInput(new PostPass.TextureInput(s3, abstracttexture, i, j)); + continue; +- case PostChainConfig.TargetInput(String s1, ResourceLocation resourcelocation2, boolean flag1, boolean flag2): +- postpass.addInput(new PostPass.TargetInput(s1, resourcelocation2, flag1, flag2)); ++ case PostChainConfig.TargetInput(String s1, ResourceLocation resourcelocation2, boolean flag1, boolean flag2, boolean useStencilBuffer): ++ postpass.addInput(new PostPass.TargetInput(s1, resourcelocation2, flag1, flag2, useStencilBuffer)); + continue; + default: + throw new MatchException(null, null); +@@ -99,17 +_,32 @@ + Matrix4f matrix4f = new Matrix4f().setOrtho(0.0F, (float)p_361423_, 0.0F, (float)p_362735_, 0.1F, 1000.0F); + Map> map = new HashMap<>(this.internalTargets.size() + this.externalTargets.size()); + ++ // Enable the depth and stencil buffers based on whether any external targets use them. ++ // This is necessary so any created buffers get the correct parameters for blitting. ++ boolean useDepth = false; ++ boolean useStencil = false; + for (ResourceLocation resourcelocation : this.externalTargets) { + map.put(resourcelocation, p_361871_.getOrThrow(resourcelocation)); ++ ++ var handle = p_361871_.get(resourcelocation); ++ ++ if (handle instanceof FrameGraphBuilder.Handle frameHandle ++ && frameHandle.getDescriptor() instanceof RenderTargetDescriptor renderDescriptor) { ++ useDepth |= renderDescriptor.useDepth(); ++ useStencil |= renderDescriptor.useStencil(); ++ } else { ++ useDepth |= p_361871_.get(resourcelocation).get().useDepth; ++ useStencil |= p_361871_.get(resourcelocation).get().useStencil; ++ } + } + + for (Entry entry : this.internalTargets.entrySet()) { + ResourceLocation resourcelocation1 = entry.getKey(); + RenderTargetDescriptor rendertargetdescriptor = switch (entry.getValue()) { + case PostChainConfig.FixedSizedTarget(int i, int j) -> { +- yield new RenderTargetDescriptor(i, j, true); ++ yield new RenderTargetDescriptor(i, j, useDepth, useStencil); + } +- case PostChainConfig.FullScreenTarget postchainconfig$fullscreentarget -> new RenderTargetDescriptor(p_361423_, p_362735_, true); ++ case PostChainConfig.FullScreenTarget postchainconfig$fullscreentarget -> new RenderTargetDescriptor(p_361423_, p_362735_, useDepth, useStencil); + default -> throw new MatchException(null, null); + }; + map.put(resourcelocation1, p_362523_.createInternal(resourcelocation1.toString(), rendertargetdescriptor)); diff --git a/patches/net/minecraft/client/renderer/PostChainConfig.java.patch b/patches/net/minecraft/client/renderer/PostChainConfig.java.patch new file mode 100644 index 00000000000..1fb00de8e61 --- /dev/null +++ b/patches/net/minecraft/client/renderer/PostChainConfig.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/client/renderer/PostChainConfig.java ++++ b/net/minecraft/client/renderer/PostChainConfig.java +@@ -103,13 +_,18 @@ + } + + @OnlyIn(Dist.CLIENT) +- public static record TargetInput(String samplerName, ResourceLocation targetId, boolean useDepthBuffer, boolean bilinear) implements PostChainConfig.Input { ++ public static record TargetInput(String samplerName, ResourceLocation targetId, boolean useDepthBuffer, boolean bilinear, boolean useStencilBuffer) implements PostChainConfig.Input { ++ public TargetInput(String samplerName, ResourceLocation targetId, boolean useDepthBuffer, boolean bilinear) { ++ this(samplerName, targetId, useDepthBuffer, bilinear, false); ++ } ++ + public static final Codec CODEC = RecordCodecBuilder.create( + p_363892_ -> p_363892_.group( + Codec.STRING.fieldOf("sampler_name").forGetter(PostChainConfig.TargetInput::samplerName), + ResourceLocation.CODEC.fieldOf("target").forGetter(PostChainConfig.TargetInput::targetId), + Codec.BOOL.optionalFieldOf("use_depth_buffer", Boolean.valueOf(false)).forGetter(PostChainConfig.TargetInput::useDepthBuffer), +- Codec.BOOL.optionalFieldOf("bilinear", Boolean.valueOf(false)).forGetter(PostChainConfig.TargetInput::bilinear) ++ Codec.BOOL.optionalFieldOf("bilinear", Boolean.valueOf(false)).forGetter(PostChainConfig.TargetInput::bilinear), ++ Codec.BOOL.optionalFieldOf("neoforge:use_stencil_buffer", Boolean.valueOf(false)).forGetter(PostChainConfig.TargetInput::useStencilBuffer) + ) + .apply(p_363892_, PostChainConfig.TargetInput::new) + ); diff --git a/patches/net/minecraft/client/renderer/PostPass.java.patch b/patches/net/minecraft/client/renderer/PostPass.java.patch new file mode 100644 index 00000000000..5ef576cd68a --- /dev/null +++ b/patches/net/minecraft/client/renderer/PostPass.java.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/client/renderer/PostPass.java ++++ b/net/minecraft/client/renderer/PostPass.java +@@ -122,7 +_,10 @@ + } + + @OnlyIn(Dist.CLIENT) +- public static record TargetInput(String samplerName, ResourceLocation targetId, boolean depthBuffer, boolean bilinear) implements PostPass.Input { ++ public static record TargetInput(String samplerName, ResourceLocation targetId, boolean depthBuffer, boolean bilinear, boolean stencilBuffer) implements PostPass.Input { ++ public TargetInput(String samplerName, ResourceLocation targetId, boolean depthBuffer, boolean bilinear) { ++ this(samplerName, targetId, depthBuffer, bilinear, false); ++ } + private ResourceHandle getHandle(Map> p_364534_) { + ResourceHandle resourcehandle = p_364534_.get(this.targetId); + if (resourcehandle == null) { +@@ -142,7 +_,12 @@ + ResourceHandle resourcehandle = this.getHandle(p_361239_); + RenderTarget rendertarget = resourcehandle.get(); + rendertarget.setFilterMode(this.bilinear ? 9729 : 9728); +- p_366564_.bindSampler(this.samplerName + "Sampler", this.depthBuffer ? rendertarget.getDepthTextureId() : rendertarget.getColorTextureId()); ++ if (this.depthBuffer) ++ p_366564_.bindSampler(this.samplerName + "Sampler", rendertarget.getDepthTextureId()); ++ else if (this.stencilBuffer) ++ p_366564_.bindSampler(this.samplerName + "Sampler", rendertarget.getStencilTextureId()); ++ else ++ p_366564_.bindSampler(this.samplerName + "Sampler", rendertarget.getColorTextureId()); + p_366564_.safeGetUniform(this.samplerName + "Size").set((float)rendertarget.width, (float)rendertarget.height); + } + diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index e50564837a7..08412f5bafe 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -1,3 +1,7 @@ +public com.mojang.blaze3d.framegraph.FrameGraphBuilder$Handle +public com.mojang.blaze3d.framegraph.FrameGraphBuilder$Handle holder +public com.mojang.blaze3d.framegraph.FrameGraphBuilder$VirtualResource +public com.mojang.blaze3d.framegraph.FrameGraphBuilder$Pass public net.minecraft.advancements.CriteriaTriggers register(Ljava/lang/String;Lnet/minecraft/advancements/CriterionTrigger;)Lnet/minecraft/advancements/CriterionTrigger; # register default net.minecraft.client.KeyMapping isDown # isDown public-f net.minecraft.client.Options keyMappings # keyMappings