diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java
index 891263526..9e0d1fd36 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java
@@ -24,6 +24,7 @@ import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState;
+import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
@@ -40,6 +41,8 @@ import com.seibel.distanthorizons.core.util.objects.Pair;
import com.seibel.distanthorizons.core.util.objects.RollingAverage;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
+import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
+import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhVanillaFadeRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTestTriangleRenderer;
@@ -669,6 +672,19 @@ public class ClientApi
//================//
//region
+ private static boolean shouldRenderFade() {
+ // don't fade when Iris shaders are active, otherwise the rendering can get weird
+ if (DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) return false;
+
+ // When immersive portals and sodium are combined the fade renders on top of the portal, so turn it off when a portal is on-screen.
+ IImmersivePortalsAccessor immersivePortals = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
+ ISodiumAccessor sodium = ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
+ if (sodium != null && immersivePortals != null && immersivePortals.hasPortalOnScreen()) {
+ return false;
+ }
+ return true;
+ }
+
/**
* The first fade pass.
* Called after MC finishes rendering the opaque passes.
@@ -690,8 +706,7 @@ public class ClientApi
// or if LOD-only mode is enabled (fading is used to remove the MC render pass)
|| Config.Client.Advanced.Debugging.lodOnlyMode.get()
)
- // don't fade when Iris shaders are active, otherwise the rendering can get weird
- && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering())
+ && shouldRenderFade())
{
RenderParams renderParams = new RenderParams(EDhApiRenderPass.OPAQUE, RENDER_STATE);
fadeRenderer.render(renderParams);
@@ -720,8 +735,7 @@ public class ClientApi
// or if LOD-only mode is enabled (fading is used to remove the MC render pass)
|| Config.Client.Advanced.Debugging.lodOnlyMode.get()
)
- // don't fade when Iris shaders are active, otherwise the rendering can get weird
- && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering();
+ && shouldRenderFade();
if (renderFade)
{
RenderParams renderParams = new RenderParams(EDhApiRenderPass.TRANSPARENT, RENDER_STATE);
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/IImmersivePortalsAccessor.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/IImmersivePortalsAccessor.java
new file mode 100644
index 000000000..b9420a157
--- /dev/null
+++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/IImmersivePortalsAccessor.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the Distant Horizons mod
+ * licensed under the GNU LGPL v3 License.
+ *
+ * Copyright (C) 2020 James Seibel
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor;
+
+public interface IImmersivePortalsAccessor extends IModAccessor
+{
+
+ boolean isRenderingPortal();
+
+ boolean hasPortalOnScreen();
+
+}
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/ImmersivePortalsAccessor.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/ImmersivePortalsAccessor.java
new file mode 100644
index 000000000..86fea687a
--- /dev/null
+++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/modAccessor/ImmersivePortalsAccessor.java
@@ -0,0 +1,104 @@
+/*
+ * This file is part of the Distant Horizons mod
+ * licensed under the GNU LGPL v3 License.
+ *
+ * Copyright (C) 2020 James Seibel
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor;
+
+import com.seibel.distanthorizons.api.DhApi;
+import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderEvent;
+import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
+import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
+import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+public class ImmersivePortalsAccessor implements IImmersivePortalsAccessor
+{
+
+ private static MethodHandle isRendering;
+
+ private static long lastPortalTime = -1;
+ private static boolean portalVisible = false;
+
+ public ImmersivePortalsAccessor() {
+ DhApi.events.bind(DhApiBeforeRenderEvent.class, BeforeRender.INSTANCE);
+ }
+
+ @Override
+ public boolean isRenderingPortal()
+ {
+ try {
+ if (isRendering == null) {
+ isRendering = MethodHandles.lookup().findStatic(
+ #if MC_VER > MC_1_16_5
+ Class.forName("qouteall.imm_ptl.core.render.context_management.PortalRendering"),
+ #else
+ Class.forName("com.qouteall.immersive_portals.render.context_management.PortalRendering"),
+ #endif
+ "isRendering", MethodType.methodType(Boolean.TYPE)
+ );
+ }
+ boolean result = (boolean) isRendering.invoke();
+ if (result) {
+ portalVisible = true;
+ lastPortalTime = System.currentTimeMillis();
+ } else if (portalVisible) {
+ if (System.currentTimeMillis() - lastPortalTime > 1000) {
+ portalVisible = false;
+ }
+ }
+ return result;
+ }
+ catch (Throwable e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean hasPortalOnScreen() {
+ return portalVisible;
+ }
+
+ @Override
+ public String getModName()
+ {
+ return "ImmersivePortalsMod";
+ }
+
+
+ public static class BeforeRender extends DhApiBeforeRenderEvent
+ {
+
+ public static BeforeRender INSTANCE = new BeforeRender();
+
+ private BeforeRender() {}
+
+ @Override
+ public void beforeRender(DhApiCancelableEventParam event)
+ {
+ if (ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class).isRenderingPortal()) {
+ event.cancelEvent();
+ }
+ }
+
+ }
+
+}