Compare commits
1 Commits
3.0.1b
...
dynamicFade
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a3c24f39e |
@@ -23,6 +23,7 @@ import com.seibel.distanthorizons.api.DhApi;
|
|||||||
import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode;
|
||||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||||
|
import com.seibel.distanthorizons.api.objects.DhApiResult;
|
||||||
import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState;
|
import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState;
|
||||||
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||||
@@ -32,8 +33,8 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
|||||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||||
import com.seibel.distanthorizons.core.render.renderer.*;
|
import com.seibel.distanthorizons.core.render.renderer.*;
|
||||||
import com.seibel.distanthorizons.core.util.TimerUtil;
|
import com.seibel.distanthorizons.core.util.TimerUtil;
|
||||||
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
import com.seibel.distanthorizons.core.util.objects.Pair;
|
import com.seibel.distanthorizons.core.util.objects.Pair;
|
||||||
import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
|
|
||||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||||
@@ -41,7 +42,6 @@ import com.seibel.distanthorizons.core.config.Config;
|
|||||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||||
import com.seibel.distanthorizons.core.network.session.NetworkSession;
|
import com.seibel.distanthorizons.core.network.session.NetworkSession;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiDebugRendering;
|
|
||||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode;
|
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||||
@@ -55,13 +55,23 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapp
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.NumberFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This holds the methods that should be called
|
* This holds the methods that should be called
|
||||||
@@ -551,8 +561,11 @@ public class ClientApi
|
|||||||
* The first fade pass.
|
* The first fade pass.
|
||||||
* Called after MC finishes rendering the opaque passes.
|
* Called after MC finishes rendering the opaque passes.
|
||||||
*/
|
*/
|
||||||
public void renderFadeOpaque()
|
public void renderFadeOpaque() // TODO this is actually the transparent pass
|
||||||
{
|
{
|
||||||
|
DepthCalculator.INSTANCE.getMcTransparentDepthTexture();
|
||||||
|
DepthCalculator.INSTANCE.tryCalculateAsync();
|
||||||
|
|
||||||
// only fade when DH is rendering
|
// only fade when DH is rendering
|
||||||
if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT
|
if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT
|
||||||
&&
|
&&
|
||||||
@@ -573,8 +586,10 @@ public class ClientApi
|
|||||||
* Called after MC finishes rendering both opaque
|
* Called after MC finishes rendering both opaque
|
||||||
* and transparent passes.
|
* and transparent passes.
|
||||||
*/
|
*/
|
||||||
public void renderFadeTransparent()
|
public void renderFadeTransparent() // TODO this is actually the opaque pass
|
||||||
{
|
{
|
||||||
|
DepthCalculator.INSTANCE.getMcOpaqueDepthTexture();
|
||||||
|
|
||||||
// only fade when DH is rendering
|
// only fade when DH is rendering
|
||||||
if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT)
|
if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT)
|
||||||
{
|
{
|
||||||
@@ -603,27 +618,30 @@ public class ClientApi
|
|||||||
/** Trigger once on key press, with CLIENT PLAYER. */
|
/** Trigger once on key press, with CLIENT PLAYER. */
|
||||||
public void keyPressedEvent(int glfwKey)
|
public void keyPressedEvent(int glfwKey)
|
||||||
{
|
{
|
||||||
if (!Config.Client.Advanced.Debugging.enableDebugKeybindings.get())
|
//if (!Config.Client.Advanced.Debugging.enableDebugKeybindings.get())
|
||||||
{
|
//{
|
||||||
// keybindings are disabled
|
// // keybindings are disabled
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
if (glfwKey == GLFW.GLFW_KEY_F8)
|
if (glfwKey == GLFW.GLFW_KEY_F8)
|
||||||
{
|
{
|
||||||
Config.Client.Advanced.Debugging.debugRendering.set(EDhApiDebugRendering.next(Config.Client.Advanced.Debugging.debugRendering.get()));
|
DepthCalculator.INSTANCE.pause = true;
|
||||||
MC_CLIENT.sendChatMessage("F8: Set debug mode to " + Config.Client.Advanced.Debugging.debugRendering.get());
|
//Config.Client.Advanced.Debugging.debugRendering.set(EDhApiDebugRendering.next(Config.Client.Advanced.Debugging.debugRendering.get()));
|
||||||
|
//MC_CLIENT.sendChatMessage("F8: Set debug mode to " + Config.Client.Advanced.Debugging.debugRendering.get());
|
||||||
}
|
}
|
||||||
else if (glfwKey == GLFW.GLFW_KEY_F6)
|
else if (glfwKey == GLFW.GLFW_KEY_F6)
|
||||||
{
|
{
|
||||||
Config.Client.Advanced.Debugging.rendererMode.set(EDhApiRendererMode.next(Config.Client.Advanced.Debugging.rendererMode.get()));
|
DepthCalculator.INSTANCE.pause = true;
|
||||||
MC_CLIENT.sendChatMessage("F6: Set rendering to " + Config.Client.Advanced.Debugging.rendererMode.get());
|
//Config.Client.Advanced.Debugging.rendererMode.set(EDhApiRendererMode.next(Config.Client.Advanced.Debugging.rendererMode.get()));
|
||||||
|
//MC_CLIENT.sendChatMessage("F6: Set rendering to " + Config.Client.Advanced.Debugging.rendererMode.get());
|
||||||
}
|
}
|
||||||
else if (glfwKey == GLFW.GLFW_KEY_P)
|
else if (glfwKey == GLFW.GLFW_KEY_P)
|
||||||
{
|
{
|
||||||
prefLoggerEnabled = !prefLoggerEnabled;
|
DepthCalculator.INSTANCE.pause = true;
|
||||||
MC_CLIENT.sendChatMessage("P: Debug Pref Logger is " + (prefLoggerEnabled ? "enabled" : "disabled"));
|
//prefLoggerEnabled = !prefLoggerEnabled;
|
||||||
|
//MC_CLIENT.sendChatMessage("P: Debug Pref Logger is " + (prefLoggerEnabled ? "enabled" : "disabled"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,20 @@ public class Config
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static ConfigEntry<Boolean> dynamicFadeUseOpaqueMcDepth = new ConfigEntry.Builder<Boolean>()
|
||||||
|
.set(true)
|
||||||
|
.comment(""
|
||||||
|
+ "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public static ConfigEntry<String> dynamicFadeExportPath = new ConfigEntry.Builder<String>()
|
||||||
|
.set("C:/Users/James_Seibel/Desktop/")
|
||||||
|
.comment(""
|
||||||
|
+ "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class Advanced
|
public static class Advanced
|
||||||
{
|
{
|
||||||
// common config links need to have their destination
|
// common config links need to have their destination
|
||||||
|
|||||||
+444
@@ -0,0 +1,444 @@
|
|||||||
|
package com.seibel.distanthorizons.core.render.renderer;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
import org.lwjgl.opengl.GL46;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class DepthCalculator
|
||||||
|
{
|
||||||
|
|
||||||
|
public static DepthCalculator INSTANCE = new DepthCalculator();
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||||
|
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||||
|
private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class);
|
||||||
|
|
||||||
|
|
||||||
|
private float[] mcOpaqueDepthTextureValues = new float[1];
|
||||||
|
private float[] mcTransparentDepthTextureValues = new float[1];
|
||||||
|
private float[] dhDepthTextureValues = new float[1];
|
||||||
|
private float[] outDepthTextureValues = new float[1];
|
||||||
|
private float lastClosestDhDepth = 1.0f;
|
||||||
|
|
||||||
|
public float actualMcBlockDistance = 8 * 16; // needs to be non-zero to start DH rendering
|
||||||
|
@Deprecated // Replace with thread pool and an AtomicBool for running state
|
||||||
|
public Thread thread = null;
|
||||||
|
public boolean pause = false;
|
||||||
|
|
||||||
|
private boolean gotDhDepthThisFrame = false;
|
||||||
|
private boolean gotMcDepthThisFrame = false;
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
|
private DepthCalculator() { }
|
||||||
|
|
||||||
|
|
||||||
|
//======//
|
||||||
|
// test //
|
||||||
|
//======//
|
||||||
|
|
||||||
|
public void getMcOpaqueDepthTexture() { this.gotMcDepthThisFrame = this.trySetDepthTexture(MC_RENDER.getDepthTextureId(), this.mcOpaqueDepthTextureValues); }
|
||||||
|
public void getMcTransparentDepthTexture() { this.gotMcDepthThisFrame = this.trySetDepthTexture(MC_RENDER.getDepthTextureId(), this.mcTransparentDepthTextureValues); }
|
||||||
|
public void trySetDhDepthTexture() { this.gotDhDepthThisFrame = this.trySetDepthTexture(LodRenderer.INSTANCE.getActiveDepthTextureId(), this.dhDepthTextureValues); }
|
||||||
|
private boolean trySetDepthTexture(int id, float[] outputRef)
|
||||||
|
{
|
||||||
|
// don't change the texture if a process is already running
|
||||||
|
if (this.thread != null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resizeTexturesIfNeeded();
|
||||||
|
if (id == -1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME this is slow and causes frame stuttering
|
||||||
|
GL46.glGetTextureImage(id, 0, GL32.GL_DEPTH_COMPONENT, GL32.GL_FLOAT, outputRef);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private void resizeTexturesIfNeeded()
|
||||||
|
{
|
||||||
|
int width = MC_RENDER.getTargetFramebufferViewportWidth();
|
||||||
|
int height = MC_RENDER.getTargetFramebufferViewportHeight();
|
||||||
|
int elementCount = width * height;
|
||||||
|
if (this.dhDepthTextureValues.length != elementCount)
|
||||||
|
{
|
||||||
|
this.mcOpaqueDepthTextureValues = new float[width * height];
|
||||||
|
this.mcTransparentDepthTextureValues = new float[width * height];
|
||||||
|
|
||||||
|
this.dhDepthTextureValues = new float[width * height];
|
||||||
|
this.outDepthTextureValues = new float[width * height];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void tryCalculateAsync()
|
||||||
|
{
|
||||||
|
if (this.thread != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (!this.gotDhDepthThisFrame
|
||||||
|
// || !this.gotMcDepthThisFrame)
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (this.pause)
|
||||||
|
{
|
||||||
|
int k = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.thread = new Thread(() ->
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.calculateDepth();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LOGGER.error("async test: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.thread = null;
|
||||||
|
this.pause = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.thread.start();
|
||||||
|
}
|
||||||
|
public void calculateDepth()
|
||||||
|
{
|
||||||
|
int width = MC_RENDER.getTargetFramebufferViewportWidth();
|
||||||
|
int height = MC_RENDER.getTargetFramebufferViewportHeight();
|
||||||
|
int elementCount = width * height;
|
||||||
|
|
||||||
|
|
||||||
|
// used to calculate the DH render matrices
|
||||||
|
RenderParams renderParams =
|
||||||
|
new RenderParams(
|
||||||
|
EDhApiRenderPass.OPAQUE,
|
||||||
|
ClientApi.RENDER_STATE.frameTime,
|
||||||
|
ClientApi.RENDER_STATE.mcProjectionMatrix, ClientApi.RENDER_STATE.mcModelViewMatrix,
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper
|
||||||
|
);
|
||||||
|
|
||||||
|
Mat4f dhInvProj = new Mat4f(renderParams.dhProjectionMatrix);
|
||||||
|
dhInvProj.invert();
|
||||||
|
Matrix4f dhInvProjJoml = dhInvProj.createJomlMatrix();
|
||||||
|
|
||||||
|
Mat4f dhInvMvm = new Mat4f(renderParams.dhModelViewMatrix);
|
||||||
|
dhInvMvm.invert();
|
||||||
|
Matrix4f dhInvMvmJoml = dhInvMvm.createJomlMatrix(); // TODO can we use JOML for MC 1.16?
|
||||||
|
|
||||||
|
|
||||||
|
float[] sampledDistances = new float[9];
|
||||||
|
|
||||||
|
// find the closest depth value MC hasn't drawn to
|
||||||
|
float closestDhDepth = 1.0f; float closestDhDistance = Float.MAX_VALUE;
|
||||||
|
int closeUIndex = 0; int closeVIndex = 0;
|
||||||
|
for (int u = 0; u < width; u++) // x
|
||||||
|
{
|
||||||
|
for (int v = 0; v < height; v++) // y
|
||||||
|
{
|
||||||
|
int invertedV = height - 1 - v;
|
||||||
|
int i = (invertedV * width) + u;
|
||||||
|
|
||||||
|
|
||||||
|
this.outDepthTextureValues[i] = 0.0f;
|
||||||
|
|
||||||
|
float mcDepth = Config.Client.dynamicFadeUseOpaqueMcDepth.get()
|
||||||
|
? this.mcOpaqueDepthTextureValues[i]
|
||||||
|
: this.mcTransparentDepthTextureValues[i];
|
||||||
|
if (mcDepth < 1.0f) // ignore positions MC has drawn to
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dhDepth = this.dhDepthTextureValues[i];
|
||||||
|
if (dhDepth == 1.0f) // ignore positions DH has NOT drawn to
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.outDepthTextureValues[i] = dhDepth;
|
||||||
|
|
||||||
|
|
||||||
|
// calculate this point's distance from the camera
|
||||||
|
float ndcU = u / (float)width;
|
||||||
|
float ndcV = invertedV / (float)height;
|
||||||
|
float dist = convertDepthToBlockDistance(ndcU, ndcV, dhInvProjJoml, dhInvMvmJoml, dhDepth);
|
||||||
|
|
||||||
|
//// sample the 9 surrounding pixels to account for off-by-one errors between the MC and DH depth textures
|
||||||
|
//int sampleIndex = 0;
|
||||||
|
//for (int relU = -1; relU < 1; relU++)
|
||||||
|
//{
|
||||||
|
// for (int relV = -1; relV < 1; relV++)
|
||||||
|
// {
|
||||||
|
// invertedV = height - 1 - v + relV;
|
||||||
|
// i = (invertedV * width) + u + relU;
|
||||||
|
// dhDepth = this.dhDepthTextureValues[i];
|
||||||
|
//
|
||||||
|
// if (v + relV < 0 || v + relV > height
|
||||||
|
// || u + relU < 0 || u + relU > width)
|
||||||
|
// {
|
||||||
|
// sampledDistances[sampleIndex] = 0.0f;
|
||||||
|
// sampleIndex++;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // calculate this point's distance from the camera
|
||||||
|
// float ndcU = u / (float)width;
|
||||||
|
// float ndcV = invertedV / (float)height;
|
||||||
|
// float dist = convertDepthToBlockDistance(ndcU, ndcV, dhInvProjJoml, dhInvMvmJoml, dhDepth);
|
||||||
|
//
|
||||||
|
// sampledDistances[sampleIndex] = dist;
|
||||||
|
// sampleIndex++;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//Arrays.sort(sampledDistances);
|
||||||
|
//// return the median element
|
||||||
|
//float dist = sampledDistances[sampledDistances.length / 2];
|
||||||
|
//if (dist == 0.0f)
|
||||||
|
//{
|
||||||
|
// // the median was 0, return the smallest non-zero element
|
||||||
|
// for (sampleIndex = 0; sampleIndex < sampledDistances.length; sampleIndex++)
|
||||||
|
// {
|
||||||
|
// if (sampledDistances[sampleIndex] != 0.0f)
|
||||||
|
// {
|
||||||
|
// dist = sampledDistances[sampleIndex];
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (dist < closestDhDistance)
|
||||||
|
{
|
||||||
|
closestDhDepth = dhDepth;
|
||||||
|
closestDhDistance = dist;
|
||||||
|
|
||||||
|
closeUIndex = u;
|
||||||
|
closeVIndex = invertedV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (this.lastClosestDhDepth != closestDhDepth)
|
||||||
|
{
|
||||||
|
NumberFormat numForm = NumberFormat.getNumberInstance();
|
||||||
|
ClientApi.INSTANCE.showChatMessageNextFrame(
|
||||||
|
"closest: ["+numForm.format(closestDhDepth)+"]-b["+numForm.format(closestDhDistance)+"]c["+numForm.format(closestDhDistance/16)+"] ("+(closeUIndex)+","+(closeVIndex)+")" +
|
||||||
|
"");
|
||||||
|
|
||||||
|
this.actualMcBlockDistance = closestDhDistance;
|
||||||
|
}
|
||||||
|
this.lastClosestDhDepth = closestDhDepth;
|
||||||
|
|
||||||
|
|
||||||
|
if (this.pause)
|
||||||
|
{
|
||||||
|
// find the range of depth values used by both textures for clearer exporting
|
||||||
|
float closestMcDepth = 1.0f; float furthestMcDepth = 0.0f;
|
||||||
|
float minDhDepth = 1.0f; float maxDhDepth = 0.0f;
|
||||||
|
for (int i = 0; i < elementCount; i++)
|
||||||
|
{
|
||||||
|
float mcDepth = this.mcOpaqueDepthTextureValues[i];
|
||||||
|
if (mcDepth != 0.0f && mcDepth != 1.0f)
|
||||||
|
{
|
||||||
|
if (mcDepth < closestMcDepth)
|
||||||
|
{
|
||||||
|
closestMcDepth = mcDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mcDepth > furthestMcDepth)
|
||||||
|
{
|
||||||
|
furthestMcDepth = mcDepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float dhDepth = this.dhDepthTextureValues[i];
|
||||||
|
if (dhDepth != 0.0f && dhDepth != 1.0f)
|
||||||
|
{
|
||||||
|
if (dhDepth < minDhDepth)
|
||||||
|
{
|
||||||
|
minDhDepth = dhDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dhDepth > maxDhDepth)
|
||||||
|
{
|
||||||
|
maxDhDepth = dhDepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String exportPath = Config.Client.dynamicFadeExportPath.get();
|
||||||
|
|
||||||
|
ClientApi.INSTANCE.showChatMessageNextFrame("exporting debug textures to: ["+exportPath+"]...");
|
||||||
|
|
||||||
|
// mc opaque
|
||||||
|
createImg(
|
||||||
|
this.mcOpaqueDepthTextureValues,
|
||||||
|
closeUIndex, closeVIndex,
|
||||||
|
(Float depth) -> { return null; },
|
||||||
|
width, height, closestMcDepth, furthestMcDepth,
|
||||||
|
exportPath+"mc-opaque_depth.png");
|
||||||
|
|
||||||
|
// mc transparent
|
||||||
|
createImg(
|
||||||
|
this.mcTransparentDepthTextureValues,
|
||||||
|
closeUIndex, closeVIndex,
|
||||||
|
(Float depth) -> { return null; },
|
||||||
|
width, height, closestMcDepth, furthestMcDepth,
|
||||||
|
exportPath+"mc-tran_depth.png");
|
||||||
|
|
||||||
|
// dh
|
||||||
|
Function<Float, Color> customColorFunc = (Float depth) ->
|
||||||
|
{
|
||||||
|
if (depth == this.lastClosestDhDepth)
|
||||||
|
{
|
||||||
|
return Color.RED;
|
||||||
|
}
|
||||||
|
//else if (depth <= (lastClosestDhDepth + 0.01f))
|
||||||
|
//{
|
||||||
|
// return Color.ORANGE;
|
||||||
|
//}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
createImg(
|
||||||
|
this.dhDepthTextureValues,
|
||||||
|
closeUIndex, closeVIndex,
|
||||||
|
customColorFunc,
|
||||||
|
width, height, minDhDepth, maxDhDepth,
|
||||||
|
exportPath+"dh_depth.png");
|
||||||
|
|
||||||
|
// temp
|
||||||
|
|
||||||
|
createImg(
|
||||||
|
this.outDepthTextureValues,
|
||||||
|
closeUIndex, closeVIndex,
|
||||||
|
(Float depth) -> { return null; },
|
||||||
|
width, height, minDhDepth, maxDhDepth,
|
||||||
|
exportPath+"temp_depth.png");
|
||||||
|
|
||||||
|
int breakPoint = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** NDC (Normalized Device Coordinates) must be between 0.0 and 1.0 (inclusive) */
|
||||||
|
private static float convertDepthToBlockDistance(float ndcU, float ndcV, Matrix4f invProj, Matrix4f invMvm, float depth)
|
||||||
|
{
|
||||||
|
// This assumes depth is scaled to [0, 1]
|
||||||
|
// Transform depth to clip space Z value
|
||||||
|
float z = depth * 2.0f - 1.0f;
|
||||||
|
|
||||||
|
// Create a vector in clip space
|
||||||
|
Vector4f clipSpacePosition = new Vector4f(ndcU, ndcV, z, 1.0f);
|
||||||
|
|
||||||
|
// Transform to world space
|
||||||
|
Vector4f worldSpacePosition = clipSpacePosition.mul(invProj);
|
||||||
|
worldSpacePosition.div(worldSpacePosition.w); // Perform perspective divide
|
||||||
|
|
||||||
|
// Finally apply the inverse model-view matrix to get world space coordinates
|
||||||
|
worldSpacePosition = worldSpacePosition.mul(invMvm);
|
||||||
|
|
||||||
|
// calculate distance from the camera
|
||||||
|
float distance = worldSpacePosition.distance(0, 0, 0, 0);
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
private static void createImg(
|
||||||
|
float[] tex,
|
||||||
|
int nearestU, int nearestV,
|
||||||
|
Function<Float, Color> customColorFunc,
|
||||||
|
int width, int height,
|
||||||
|
float minDepth, float maxDepth,
|
||||||
|
String filePath)
|
||||||
|
{
|
||||||
|
// Create a BufferedImage
|
||||||
|
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
|
for (int u = 0; u < width; u++)
|
||||||
|
{
|
||||||
|
for (int v = 0; v < height; v++)
|
||||||
|
{
|
||||||
|
int invertedY = height - 1 - v;
|
||||||
|
|
||||||
|
// Normalize the depth value to a grayscale pixel
|
||||||
|
float depthValue = tex[(invertedY * width) + u];
|
||||||
|
Color color = customColorFunc.apply(depthValue);
|
||||||
|
if (color == null)
|
||||||
|
{
|
||||||
|
float normalizedDepth = (depthValue - minDepth) / (maxDepth - minDepth); // Normalize to 0.0 to 1.0
|
||||||
|
normalizedDepth = Math.max(0.0f, Math.min(1.0f, normalizedDepth)); // Clamp to valid range
|
||||||
|
|
||||||
|
int gray = (int) (normalizedDepth * 255); // Map to 0-255
|
||||||
|
gray = Math.max(0, Math.min(255, gray)); // Clamp to valid range
|
||||||
|
color = new Color(gray, gray, gray);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthValue == 1.0f)
|
||||||
|
{
|
||||||
|
color = new Color(0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u == nearestU)
|
||||||
|
{
|
||||||
|
color = Color.MAGENTA;
|
||||||
|
}
|
||||||
|
else if (invertedY == nearestV)
|
||||||
|
{
|
||||||
|
color = Color.ORANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
image.setRGB(u, v, color.getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the image to a file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ImageIO.write(image, "png", new File(filePath));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
LOGGER.error("Unable to write texture to file, error: ["+e.getMessage()+"].", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+7
-7
@@ -204,17 +204,17 @@ public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShade
|
|||||||
this.setUniform(this.uIsWhiteWorld, Config.Client.Advanced.Debugging.enableWhiteWorld.get());
|
this.setUniform(this.uIsWhiteWorld, Config.Client.Advanced.Debugging.enableWhiteWorld.get());
|
||||||
|
|
||||||
// Clip Uniform
|
// Clip Uniform
|
||||||
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocksForFading(renderParameters.partialTicks);
|
float dhNearClipDistance = 0.1f;//RenderUtil.getNearClipPlaneInBlocksForFading(renderParameters.partialTicks);
|
||||||
if (!Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
//if (!Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||||
{
|
//{
|
||||||
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
// // this added value prevents the near clip plane and discard circle from touching, which looks bad
|
||||||
dhNearClipDistance += 16f;
|
// dhNearClipDistance += 16f;
|
||||||
}
|
//}
|
||||||
// if the player is very high up and the near clip plane has been modified, disable the distance clipping
|
// if the player is very high up and the near clip plane has been modified, disable the distance clipping
|
||||||
// we're high enough that nothing will render on top of the player and this can cause issues otherwise
|
// we're high enough that nothing will render on top of the player and this can cause issues otherwise
|
||||||
if (RenderUtil.getHeightBasedNearClipOverride() != -1)
|
if (RenderUtil.getHeightBasedNearClipOverride() != -1)
|
||||||
{
|
{
|
||||||
dhNearClipDistance = 1.0f;
|
dhNearClipDistance = 1.0f; // TODO does this actually disable anything?
|
||||||
}
|
}
|
||||||
this.setUniform(this.uClipDistance, dhNearClipDistance);
|
this.setUniform(this.uClipDistance, dhNearClipDistance);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,6 +222,8 @@ public class LodRenderer
|
|||||||
profiler.popPush("LOD Opaque");
|
profiler.popPush("LOD Opaque");
|
||||||
this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ true);
|
this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ true);
|
||||||
|
|
||||||
|
DepthCalculator.INSTANCE.trySetDhDepthTexture();
|
||||||
|
|
||||||
// custom objects with SSAO
|
// custom objects with SSAO
|
||||||
if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get())
|
if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get())
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-1
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||||
@@ -114,7 +115,7 @@ public class VanillaFadeShader extends AbstractShaderRenderer
|
|||||||
|
|
||||||
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocksForFading(partialTicks);
|
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocksForFading(partialTicks);
|
||||||
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
||||||
dhNearClipDistance += 16f;
|
//dhNearClipDistance += 16f;
|
||||||
|
|
||||||
// measured in blocks
|
// measured in blocks
|
||||||
// these multipliers in James' tests should provide a fairly smooth transition
|
// these multipliers in James' tests should provide a fairly smooth transition
|
||||||
|
|||||||
@@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.core.util;
|
package com.seibel.distanthorizons.core.util;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
|
import com.seibel.distanthorizons.core.render.renderer.DepthCalculator;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
@@ -127,13 +129,16 @@ public class RenderUtil
|
|||||||
}
|
}
|
||||||
public static float getNearClipPlaneInBlocksForFading(float partialTicks)
|
public static float getNearClipPlaneInBlocksForFading(float partialTicks)
|
||||||
{
|
{
|
||||||
float overdraw = getAutoOverdrawPrevention();
|
//float overdraw = getAutoOverdrawPrevention();
|
||||||
return getNearClipPlaneDistanceInBlocks(partialTicks, overdraw);
|
//return getNearClipPlaneDistanceInBlocks(partialTicks, overdraw);
|
||||||
|
|
||||||
|
return DepthCalculator.INSTANCE.actualMcBlockDistance;
|
||||||
}
|
}
|
||||||
private static float getNearClipPlaneDistanceInBlocks(float partialTicks, float overdrawPreventionPercent)
|
private static float getNearClipPlaneDistanceInBlocks(float partialTicks, float overdrawPreventionPercent)
|
||||||
{
|
{
|
||||||
int chunkRenderDistance = MC_RENDER.getRenderDistance();
|
int chunkRenderDistance = MC_RENDER.getRenderDistance();
|
||||||
int vanillaBlockRenderedDistance = chunkRenderDistance * LodUtil.CHUNK_WIDTH;
|
//float chunkRenderDistance = ClientApi.actualMcBlockDistance / 16.0f;
|
||||||
|
float vanillaBlockRenderedDistance = chunkRenderDistance * LodUtil.CHUNK_WIDTH;
|
||||||
|
|
||||||
float nearClipPlane;
|
float nearClipPlane;
|
||||||
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
if (Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||||
|
|||||||
@@ -84,7 +84,13 @@
|
|||||||
"Show The Options Button",
|
"Show The Options Button",
|
||||||
"distanthorizons.config.client.optionsButton.@tooltip":
|
"distanthorizons.config.client.optionsButton.@tooltip":
|
||||||
"Show the config button to the left of the fov button",
|
"Show the config button to the left of the fov button",
|
||||||
|
|
||||||
|
"distanthorizons.config.client.dynamicFadeUseOpaqueMcDepth":
|
||||||
|
"Dynamic Fade Use MC Opaque Depth",
|
||||||
|
"distanthorizons.config.client.dynamicFadeExportPath":
|
||||||
|
"Dynamic Fade Export Path",
|
||||||
|
"distanthorizons.config.client.dynamicFadeExportPath.@tooltip":
|
||||||
|
"Press 'p' to export the depth textures for troubleshooting",
|
||||||
|
|
||||||
|
|
||||||
"distanthorizons.config.client.advanced":
|
"distanthorizons.config.client.advanced":
|
||||||
|
|||||||
Reference in New Issue
Block a user