mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-11-15 09:44:52 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
057ea8035c |
No files matched your search
@@ -136,6 +136,9 @@ dependencies {
|
||||
// Better Crashes
|
||||
compileOnly("com.github.GTNewHorizons:BetterCrashes:1.4.1-GTNH:dev")
|
||||
|
||||
// Distant Horizons
|
||||
compileOnly("maven.modrinth:DistantHorizonsApi:5.1.0")
|
||||
|
||||
afterEvaluate {
|
||||
dependencies {
|
||||
testImplementation(platform('org.junit:junit-bom:5.14.1'))
|
||||
|
||||
@@ -14,6 +14,7 @@ import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
|
||||
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
|
||||
import net.coderbot.iris.samplers.IrisSamplers;
|
||||
import net.coderbot.iris.texture.pbr.PBRTextureManager;
|
||||
import net.coderbot.iris.vertices.ImmediateState;
|
||||
|
||||
public class IrisGLSMBridge {
|
||||
|
||||
@@ -114,7 +115,7 @@ public class IrisGLSMBridge {
|
||||
if (!drp.shouldOverrideShaders()) return;
|
||||
if (drp.getActivePassProgramId() == -1) return;
|
||||
|
||||
if (DepthColorStorage.isOwnedProgram(event.newProgram)) {
|
||||
if (!ImmediateState.isRenderingLevel || DepthColorStorage.isOwnedProgram(event.newProgram)) {
|
||||
DepthColorStorage.unlockDepthColor();
|
||||
} else {
|
||||
drp.onModProgramOverride();
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.gtnewhorizons.angelica.AngelicaMod;
|
||||
import com.gtnewhorizons.angelica.Tags;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import cpw.mods.fml.client.registry.ClientRegistry;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.common.gameevent.InputEvent;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
@@ -17,6 +18,7 @@ import net.coderbot.iris.block_rendering.BlockRenderingSettings;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import net.coderbot.iris.celeritas.IrisCeleritasShaderProvider;
|
||||
import com.gtnewhorizons.angelica.rendering.celeritas.api.IrisShaderProviderHolder;
|
||||
import net.coderbot.iris.compat.dh.DHCompat;
|
||||
import net.coderbot.iris.config.IrisConfig;
|
||||
import net.coderbot.iris.gl.shader.StandardMacros;
|
||||
import net.coderbot.iris.gui.screen.ShaderPackScreen;
|
||||
@@ -113,11 +115,31 @@ public class Iris {
|
||||
// Used in favor of queueDefaultShaderPackOptionValues() for resetting as the
|
||||
// behavior is more concrete and therefore is more likely to repair a user's issues
|
||||
private static boolean resetShaderPackOptions = false;
|
||||
private static boolean loadShaderPackWhenPossible = false;
|
||||
|
||||
private static String IRIS_VERSION;
|
||||
@Getter
|
||||
private static boolean fallback;
|
||||
|
||||
public static boolean loadedIncompatiblePack() {
|
||||
return DHCompat.lastPackIncompatible();
|
||||
}
|
||||
|
||||
public static void loadShaderpackWhenPossible() {
|
||||
loadShaderPackWhenPossible = true;
|
||||
}
|
||||
|
||||
public static void tryLoadShaderpackWhenPossible() {
|
||||
if (loadShaderPackWhenPossible) {
|
||||
loadShaderPackWhenPossible = false;
|
||||
try {
|
||||
reload();
|
||||
} catch (IOException e) {
|
||||
logger.error("Error during deferred shader reload", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy executor for parallelizing shader transformations during shader pack loading.
|
||||
* Creates threads on demand and shuts down after a period of inactivity.
|
||||
@@ -350,6 +372,7 @@ public class Iris {
|
||||
* <p>This is called right before options are loaded, so we can add key bindings here.</p>
|
||||
*/
|
||||
public void onEarlyInitialize() {
|
||||
DHCompat.run();
|
||||
try {
|
||||
if (!Files.exists(getShaderpacksDirectory())) {
|
||||
Files.createDirectories(getShaderpacksDirectory());
|
||||
@@ -395,8 +418,19 @@ public class Iris {
|
||||
|
||||
PBRTextureManager.INSTANCE.init();
|
||||
|
||||
// Only load the shader pack when we can access OpenGL
|
||||
loadShaderpack();
|
||||
boolean isDHLoaded;
|
||||
try {
|
||||
Class.forName("com.seibel.distanthorizons.DistantHorizonsTweaker");
|
||||
isDHLoaded = true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
isDHLoaded = false;
|
||||
}
|
||||
|
||||
// When DH is present, defer shaderpack loading until its init callback has run.
|
||||
if (!isDHLoaded) {
|
||||
loadShaderpack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -721,6 +755,12 @@ public class Iris {
|
||||
|
||||
BlockRenderingSettings.INSTANCE.reloadRendererIfRequired();
|
||||
}
|
||||
|
||||
if (loadedIncompatiblePack() && Minecraft.getMinecraft().thePlayer != null) {
|
||||
Iris.logger.warn("Incompatible pack for DH!");
|
||||
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.BOLD.toString() + EnumChatFormatting.RED + "This pack doesn't have DH support."));
|
||||
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Distant Horizons (DH) chunks won't show up. This isn't a bug, get another shader."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,14 +1,129 @@
|
||||
package net.coderbot.iris.compat.dh;
|
||||
|
||||
/**
|
||||
* Stub implementation of Distant Horizons compatibility.
|
||||
*/
|
||||
public class DHCompat {
|
||||
public int getDepthTex() {
|
||||
return 0;
|
||||
}
|
||||
import com.gtnewhorizons.angelica.rendering.RenderingState;
|
||||
import net.coderbot.iris.Iris;
|
||||
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
public int getDepthTexNoTranslucent() {
|
||||
return 0;
|
||||
}
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class DHCompat {
|
||||
private static boolean dhPresent;
|
||||
private static boolean lastIncompatible;
|
||||
private DHCompatInternal compatInternalInstance;
|
||||
private final static Matrix4f tempProj = new Matrix4f();
|
||||
|
||||
public DHCompat(DeferredWorldRenderingPipeline pipeline, boolean renderDHShadow) {
|
||||
if (pipeline == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (dhPresent) {
|
||||
compatInternalInstance = new DHCompatInternal(pipeline, renderDHShadow);
|
||||
lastIncompatible = compatInternalInstance.incompatiblePack();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
lastIncompatible = false;
|
||||
if (e instanceof InvocationTargetException ite) {
|
||||
throw new RuntimeException("Unknown error loading Distant Horizons compatibility.", ite.getCause());
|
||||
} else {
|
||||
throw new RuntimeException("Unknown error loading Distant Horizons compatibility.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Matrix4fc getProjection() {
|
||||
Matrix4f projection = RenderingState.INSTANCE.getProjectionMatrix();
|
||||
if (!dhPresent) {
|
||||
return projection;
|
||||
}
|
||||
|
||||
return tempProj.setPerspective(projection.perspectiveFov(), projection.m11() / projection.m00(), DHCompat.getNearPlane(), DHCompat.getFarPlane());
|
||||
}
|
||||
|
||||
public static void run() {
|
||||
try {
|
||||
Class.forName("com.seibel.distanthorizons.DistantHorizonsTweaker");
|
||||
dhPresent = true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
dhPresent = false;
|
||||
}
|
||||
try {
|
||||
if (dhPresent) {
|
||||
LodRendererEvents.setupEventHandlers();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
dhPresent = false;
|
||||
if (e instanceof ExceptionInInitializerError eiie) {
|
||||
throw new RuntimeException("Failure loading DH compat.", eiie.getCause());
|
||||
} else {
|
||||
throw new RuntimeException("DH found, but one or more API methods are missing. Iris requires DH [2.0.4] or DH API version [1.1.0] or newer. Please make sure you are on the latest version of DH and Iris.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean lastPackIncompatible() {
|
||||
return dhPresent && hasRenderingEnabled() && lastIncompatible;
|
||||
}
|
||||
|
||||
public static float getFarPlane() {
|
||||
if (!dhPresent) return 0.01f;
|
||||
return DHCompatInternal.getFarPlane();
|
||||
}
|
||||
|
||||
public static float getNearPlane() {
|
||||
if (!dhPresent) return 0.01f;
|
||||
return DHCompatInternal.getNearPlane();
|
||||
}
|
||||
|
||||
public static int getRenderDistance() {
|
||||
if (!dhPresent) return Minecraft.getMinecraft().gameSettings.renderDistanceChunks * 16;
|
||||
|
||||
return DHCompatInternal.getRenderDistance();
|
||||
}
|
||||
|
||||
public static boolean checkFrame() {
|
||||
if (!dhPresent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return DHCompatInternal.checkFrame();
|
||||
}
|
||||
|
||||
public static boolean hasRenderingEnabled() {
|
||||
if (!dhPresent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return checkFrame();
|
||||
}
|
||||
|
||||
public void clearPipeline() {
|
||||
if (compatInternalInstance == null) return;
|
||||
|
||||
compatInternalInstance.clear();
|
||||
}
|
||||
|
||||
public int getDepthTex() {
|
||||
if (compatInternalInstance == null) return -1;
|
||||
|
||||
return compatInternalInstance.getStoredDepthTex();
|
||||
}
|
||||
|
||||
public int getDepthTexNoTranslucent() {
|
||||
if (compatInternalInstance == null) return -1;
|
||||
|
||||
return compatInternalInstance.getDepthTexNoTranslucent();
|
||||
}
|
||||
|
||||
public DHCompatInternal getInstance() {
|
||||
return compatInternalInstance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
package net.coderbot.iris.compat.dh;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
||||
import net.coderbot.iris.Iris;
|
||||
import net.coderbot.iris.gl.framebuffer.GlFramebuffer;
|
||||
import net.coderbot.iris.gl.texture.DepthBufferFormat;
|
||||
import net.coderbot.iris.gl.texture.DepthCopyStrategy;
|
||||
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
|
||||
import net.coderbot.iris.rendertarget.DepthTexture;
|
||||
import net.coderbot.iris.rendertarget.IRenderTargetExt;
|
||||
import net.coderbot.iris.shaderpack.CloudSetting;
|
||||
import net.coderbot.iris.shaderpack.ProgramSource;
|
||||
import net.coderbot.iris.uniforms.CapturedRenderingState;
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DHCompatInternal {
|
||||
public static final DHCompatInternal SHADERLESS = new DHCompatInternal(null, false);
|
||||
static boolean dhEnabled;
|
||||
private static int guiScale = -1;
|
||||
private final DeferredWorldRenderingPipeline pipeline;
|
||||
public boolean shouldOverrideShadow;
|
||||
public boolean shouldOverride;
|
||||
private GlFramebuffer dhGenericFramebuffer;
|
||||
private IrisLodRenderProgram solidProgram;
|
||||
private IrisGenericRenderProgram genericShader;
|
||||
private IrisLodRenderProgram translucentProgram;
|
||||
private IrisLodRenderProgram shadowProgram;
|
||||
private GlFramebuffer dhTerrainFramebuffer;
|
||||
private DhFrameBufferWrapper dhTerrainFramebufferWrapper;
|
||||
private GlFramebuffer dhWaterFramebuffer;
|
||||
private GlFramebuffer dhShadowFramebuffer;
|
||||
private DhFrameBufferWrapper dhShadowFramebufferWrapper;
|
||||
private DepthTexture depthTexNoTranslucent;
|
||||
private boolean translucentDepthDirty;
|
||||
private int storedDepthTex = -1;
|
||||
private boolean incompatible = false;
|
||||
private int cachedVersion;
|
||||
|
||||
public DHCompatInternal(DeferredWorldRenderingPipeline pipeline, boolean dhShadowEnabled) {
|
||||
this.pipeline = pipeline;
|
||||
|
||||
if (pipeline == null || !DhApi.Delayed.configs.graphics().renderingEnabled().getValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipeline.getDHTerrainShader().isEmpty() && pipeline.getDHWaterShader().isEmpty()) {
|
||||
Iris.logger.warn("No DH shader found in this pack.");
|
||||
incompatible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
cachedVersion = ((IRenderTargetExt) Minecraft.getMinecraft().getFramebuffer()).iris$getDepthBufferVersion();
|
||||
|
||||
createDepthTex(Minecraft.getMinecraft().getFramebuffer().framebufferWidth, Minecraft.getMinecraft().getFramebuffer().framebufferHeight);
|
||||
translucentDepthDirty = true;
|
||||
|
||||
ProgramSource terrain = pipeline.getDHTerrainShader().get();
|
||||
solidProgram = IrisLodRenderProgram.createProgram(terrain.getName(), false, false, terrain, pipeline.getCustomUniforms(), pipeline);
|
||||
|
||||
ProgramSource generic = pipeline.getDHGenericShader().get();
|
||||
genericShader = IrisGenericRenderProgram.createProgram(generic.getName() + "_g", false, false, generic, pipeline.getCustomUniforms(), pipeline);
|
||||
dhGenericFramebuffer = pipeline.createDHFramebuffer(generic, false);
|
||||
|
||||
if (pipeline.getDHWaterShader().isPresent()) {
|
||||
ProgramSource water = pipeline.getDHWaterShader().get();
|
||||
translucentProgram = IrisLodRenderProgram.createProgram(water.getName(), false, true, water, pipeline.getCustomUniforms(), pipeline);
|
||||
dhWaterFramebuffer = pipeline.createDHFramebuffer(water, true);
|
||||
}
|
||||
|
||||
if (pipeline.getDHShadowShader().isPresent() && dhShadowEnabled) {
|
||||
ProgramSource shadow = pipeline.getDHShadowShader().get();
|
||||
shadowProgram = IrisLodRenderProgram.createProgram(shadow.getName(), true, false, shadow, pipeline.getCustomUniforms(), pipeline);
|
||||
if (pipeline.hasShadowRenderTargets()) {
|
||||
dhShadowFramebuffer = pipeline.createDHFramebufferShadow(shadow);
|
||||
dhShadowFramebufferWrapper = new DhFrameBufferWrapper(dhShadowFramebuffer);
|
||||
}
|
||||
shouldOverrideShadow = true;
|
||||
} else {
|
||||
shouldOverrideShadow = false;
|
||||
}
|
||||
|
||||
dhTerrainFramebuffer = pipeline.createDHFramebuffer(terrain, false);
|
||||
dhTerrainFramebufferWrapper = new DhFrameBufferWrapper(dhTerrainFramebuffer);
|
||||
|
||||
if (translucentProgram == null) {
|
||||
translucentProgram = solidProgram;
|
||||
}
|
||||
|
||||
shouldOverride = true;
|
||||
}
|
||||
|
||||
public static int getDhBlockRenderDistance() {
|
||||
if (DhApi.Delayed.configs == null || !dhEnabled) {
|
||||
// Called before DH has finished setup
|
||||
return Minecraft.getMinecraft().gameSettings.renderDistanceChunks * 16;
|
||||
}
|
||||
|
||||
return DhApi.Delayed.configs.graphics().chunkRenderDistance().getValue() * 16;
|
||||
}
|
||||
|
||||
public static int getRenderDistance() {
|
||||
return getDhBlockRenderDistance();
|
||||
}
|
||||
|
||||
public static float getFarPlane() {
|
||||
if (DhApi.Delayed.configs == null) {
|
||||
// Called before DH has finished setup
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lodChunkDist = DhApi.Delayed.configs.graphics().chunkRenderDistance().getValue();
|
||||
int lodBlockDist = lodChunkDist * 16;
|
||||
// sqrt 2 to prevent the corners from being cut off
|
||||
return (float) ((lodBlockDist + 512) * Math.sqrt(2));
|
||||
}
|
||||
|
||||
public static float getNearPlane() {
|
||||
if (DhApi.Delayed.renderProxy == null) {
|
||||
// Called before DH has finished setup
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DhApi.Delayed.renderProxy.getNearClipPlaneDistanceInBlocks(CapturedRenderingState.INSTANCE.getTickDelta());
|
||||
}
|
||||
|
||||
public static boolean checkFrame() {
|
||||
if (guiScale == -1) {
|
||||
guiScale = Minecraft.getMinecraft().gameSettings.guiScale;
|
||||
}
|
||||
|
||||
if (DhApi.Delayed.configs == null) return dhEnabled;
|
||||
|
||||
if ((dhEnabled != DhApi.Delayed.configs.graphics().renderingEnabled().getValue() || guiScale != Minecraft.getMinecraft().gameSettings.guiScale)
|
||||
&& IrisApi.getInstance().isShaderPackInUse()) {
|
||||
guiScale = Minecraft.getMinecraft().gameSettings.guiScale;
|
||||
dhEnabled = DhApi.Delayed.configs.graphics().renderingEnabled().getValue();
|
||||
try {
|
||||
Iris.reload();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return dhEnabled;
|
||||
}
|
||||
|
||||
public boolean incompatiblePack() {
|
||||
return incompatible;
|
||||
}
|
||||
|
||||
public void reconnectDHTextures(int depthTex) {
|
||||
if (((IRenderTargetExt) Minecraft.getMinecraft().getFramebuffer()).iris$getDepthBufferVersion() != cachedVersion) {
|
||||
cachedVersion = ((IRenderTargetExt) Minecraft.getMinecraft().getFramebuffer()).iris$getDepthBufferVersion();
|
||||
createDepthTex(Minecraft.getMinecraft().getFramebuffer().framebufferWidth, Minecraft.getMinecraft().getFramebuffer().framebufferHeight);
|
||||
}
|
||||
if (storedDepthTex != depthTex && dhTerrainFramebuffer != null) {
|
||||
storedDepthTex = depthTex;
|
||||
dhTerrainFramebuffer.addDepthAttachmentBypass(depthTex);
|
||||
if (dhWaterFramebuffer != null) {
|
||||
dhWaterFramebuffer.addDepthAttachmentBypass(depthTex);
|
||||
}
|
||||
if (dhGenericFramebuffer != null) {
|
||||
dhGenericFramebuffer.addDepthAttachmentBypass(depthTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void createDepthTex(int width, int height) {
|
||||
if (depthTexNoTranslucent != null) {
|
||||
depthTexNoTranslucent.destroy();
|
||||
depthTexNoTranslucent = null;
|
||||
}
|
||||
|
||||
translucentDepthDirty = true;
|
||||
|
||||
depthTexNoTranslucent = new DepthTexture(width, height, DepthBufferFormat.DEPTH32F);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (solidProgram != null) {
|
||||
solidProgram.free();
|
||||
solidProgram = null;
|
||||
}
|
||||
if (translucentProgram != null) {
|
||||
translucentProgram.free();
|
||||
translucentProgram = null;
|
||||
}
|
||||
if (shadowProgram != null) {
|
||||
shadowProgram.free();
|
||||
shadowProgram = null;
|
||||
}
|
||||
shouldOverrideShadow = false;
|
||||
shouldOverride = false;
|
||||
dhTerrainFramebuffer = null;
|
||||
dhWaterFramebuffer = null;
|
||||
dhShadowFramebuffer = null;
|
||||
storedDepthTex = -1;
|
||||
translucentDepthDirty = true;
|
||||
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, dhTerrainFramebufferWrapper);
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiGenericObjectShaderProgram.class, genericShader);
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, dhShadowFramebufferWrapper);
|
||||
dhTerrainFramebufferWrapper = null;
|
||||
dhShadowFramebufferWrapper = null;
|
||||
}
|
||||
|
||||
public void setModelPos(DhApiVec3f modelPos) {
|
||||
solidProgram.bind();
|
||||
solidProgram.setModelPos(modelPos);
|
||||
translucentProgram.bind();
|
||||
translucentProgram.setModelPos(modelPos);
|
||||
solidProgram.bind();
|
||||
}
|
||||
|
||||
public IrisLodRenderProgram getSolidShader() {
|
||||
return solidProgram;
|
||||
}
|
||||
|
||||
public GlFramebuffer getSolidFB() {
|
||||
return dhTerrainFramebuffer;
|
||||
}
|
||||
|
||||
public DhFrameBufferWrapper getSolidFBWrapper() {
|
||||
return dhTerrainFramebufferWrapper;
|
||||
}
|
||||
|
||||
public IrisLodRenderProgram getShadowShader() {
|
||||
return shadowProgram;
|
||||
}
|
||||
|
||||
public GlFramebuffer getShadowFB() {
|
||||
return dhShadowFramebuffer;
|
||||
}
|
||||
|
||||
public DhFrameBufferWrapper getShadowFBWrapper() {
|
||||
return dhShadowFramebufferWrapper;
|
||||
}
|
||||
|
||||
public IrisLodRenderProgram getTranslucentShader() {
|
||||
if (translucentProgram == null) {
|
||||
return solidProgram;
|
||||
}
|
||||
return translucentProgram;
|
||||
}
|
||||
|
||||
public int getStoredDepthTex() {
|
||||
return storedDepthTex;
|
||||
}
|
||||
|
||||
public void copyTranslucents(int width, int height) {
|
||||
if (translucentDepthDirty) {
|
||||
translucentDepthDirty = false;
|
||||
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, depthTexNoTranslucent.getTextureId());
|
||||
dhTerrainFramebuffer.bindAsReadBuffer();
|
||||
GLStateManager.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, DepthBufferFormat.DEPTH32F.getGlInternalFormat(), 0, 0, width, height, 0);
|
||||
} else {
|
||||
DepthCopyStrategy.fastest(false).copy(dhTerrainFramebuffer, storedDepthTex, null, depthTexNoTranslucent.getTextureId(), width, height);
|
||||
}
|
||||
}
|
||||
|
||||
public GlFramebuffer getTranslucentFB() {
|
||||
return dhWaterFramebuffer;
|
||||
}
|
||||
|
||||
public GlFramebuffer getGenericFB() {
|
||||
return dhGenericFramebuffer;
|
||||
}
|
||||
|
||||
public int getDepthTexNoTranslucent() {
|
||||
if (depthTexNoTranslucent == null) return 0;
|
||||
|
||||
return depthTexNoTranslucent.getTextureId();
|
||||
}
|
||||
|
||||
public IDhApiGenericObjectShaderProgram getGenericShader() {
|
||||
return genericShader;
|
||||
}
|
||||
|
||||
public boolean avoidRenderingClouds() {
|
||||
return pipeline != null && (pipeline.getDHCloudSetting() == CloudSetting.OFF || (pipeline.getDHCloudSetting() == CloudSetting.DEFAULT && pipeline.getCloudSetting() == CloudSetting.OFF));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.coderbot.iris.compat.dh;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
|
||||
import net.coderbot.iris.gl.framebuffer.GlFramebuffer;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
|
||||
public class DhFrameBufferWrapper implements IDhApiFramebuffer {
|
||||
private final GlFramebuffer framebuffer;
|
||||
|
||||
|
||||
public DhFrameBufferWrapper(GlFramebuffer framebuffer) {
|
||||
this.framebuffer = framebuffer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean overrideThisFrame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind() {
|
||||
this.framebuffer.bind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDepthAttachment(int i, boolean b) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return this.framebuffer.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus() {
|
||||
this.bind();
|
||||
int status = GLStateManager.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER);
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColorAttachment(int i, int i1) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// ignore
|
||||
//this.framebuffer.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
package net.coderbot.iris.compat.dh;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.EntityRendererAccessor;
|
||||
import com.mitchej123.lwjgl.MemoryStack;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
|
||||
import net.coderbot.iris.gl.blending.BlendModeOverride;
|
||||
import net.coderbot.iris.gl.blending.BufferBlendOverride;
|
||||
import net.coderbot.iris.gl.program.ProgramImages;
|
||||
import net.coderbot.iris.gl.program.ProgramSamplers;
|
||||
import net.coderbot.iris.gl.program.ProgramUniforms;
|
||||
import net.coderbot.iris.gl.shader.GlShader;
|
||||
import net.coderbot.iris.gl.shader.ShaderType;
|
||||
import net.coderbot.iris.gl.state.FogMode;
|
||||
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
|
||||
import net.coderbot.iris.pipeline.PatchedShaderPrinter;
|
||||
import net.coderbot.iris.pipeline.transform.PatchShaderType;
|
||||
import net.coderbot.iris.pipeline.transform.TransformPatcher;
|
||||
import net.coderbot.iris.samplers.IrisSamplers;
|
||||
import net.coderbot.iris.shaderpack.ProgramSource;
|
||||
import net.coderbot.iris.uniforms.CommonUniforms;
|
||||
import net.coderbot.iris.uniforms.builtin.BuiltinReplacementUniforms;
|
||||
import net.coderbot.iris.uniforms.custom.CustomUniforms;
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class IrisGenericRenderProgram implements IDhApiGenericObjectShaderProgram {
|
||||
// Uniforms
|
||||
public final int modelViewUniform;
|
||||
public final int modelViewInverseUniform;
|
||||
public final int projectionUniform;
|
||||
public final int projectionInverseUniform;
|
||||
public final int normalMatrix3fUniform;
|
||||
// Fog/Clip Uniforms
|
||||
private final int id;
|
||||
private final ProgramUniforms uniforms;
|
||||
private final CustomUniforms customUniforms;
|
||||
private final ProgramSamplers samplers;
|
||||
private final ProgramImages images;
|
||||
private final BlendModeOverride blend;
|
||||
private final BufferBlendOverride[] bufferBlendOverrides;
|
||||
private final Matrix4f tempModel = new Matrix4f();
|
||||
private final Matrix4f tempProj = new Matrix4f();
|
||||
private final Matrix4f tempMat4 = new Matrix4f();
|
||||
private final Matrix3f tempMat3 = new Matrix3f();
|
||||
|
||||
private final int instancedShaderOffsetChunkUniform;
|
||||
private final int instancedShaderOffsetSubChunkUniform;
|
||||
private final int instancedShaderCameraChunkPosUniform;
|
||||
private final int instancedShaderCameraSubChunkPosUniform;
|
||||
private final int instancedShaderProjectionModelViewMatrixUniform;
|
||||
private final int va;
|
||||
private final int uBlockLight;
|
||||
private final int uSkyLight;
|
||||
|
||||
// This will bind AbstractVertexAttribute
|
||||
private IrisGenericRenderProgram(String name, boolean isShadowPass, boolean translucent, BlendModeOverride override, BufferBlendOverride[] bufferBlendOverrides, String vertex, String tessControl, String tessEval, String geometry, String fragment, CustomUniforms customUniforms, DeferredWorldRenderingPipeline pipeline) {
|
||||
id = GLStateManager.glCreateProgram();
|
||||
|
||||
GLStateManager.glBindAttribLocation(this.id, 0, "vPosition");
|
||||
|
||||
this.bufferBlendOverrides = bufferBlendOverrides;
|
||||
|
||||
GlShader vert = new GlShader(ShaderType.VERTEX, name + ".vsh", vertex);
|
||||
GLStateManager.glAttachShader(id, vert.getHandle());
|
||||
|
||||
GlShader tessCont = null;
|
||||
if (tessControl != null) {
|
||||
tessCont = new GlShader(ShaderType.TESSELATION_CONTROL, name + ".tcs", tessControl);
|
||||
GLStateManager.glAttachShader(id, tessCont.getHandle());
|
||||
}
|
||||
|
||||
GlShader tessE = null;
|
||||
if (tessEval != null) {
|
||||
tessE = new GlShader(ShaderType.TESSELATION_EVAL, name + ".tes", tessEval);
|
||||
GLStateManager.glAttachShader(id, tessE.getHandle());
|
||||
}
|
||||
|
||||
GlShader geom = null;
|
||||
if (geometry != null) {
|
||||
geom = new GlShader(ShaderType.GEOMETRY, name + ".gsh", geometry);
|
||||
GLStateManager.glAttachShader(id, geom.getHandle());
|
||||
}
|
||||
|
||||
GlShader frag = new GlShader(ShaderType.FRAGMENT, name + ".fsh", fragment);
|
||||
GLStateManager.glAttachShader(id, frag.getHandle());
|
||||
|
||||
GLStateManager.glLinkProgram(this.id);
|
||||
int status = GLStateManager.glGetProgrami(this.id, GL20.GL_LINK_STATUS);
|
||||
if (status != 1) {
|
||||
String message = "Shader link error in Iris DH program! Details: " + GLStateManager.glGetProgramInfoLog(this.id, 9999);
|
||||
this.free();
|
||||
throw new RuntimeException(message);
|
||||
} else {
|
||||
GLStateManager.glUseProgram(this.id);
|
||||
}
|
||||
|
||||
vert.destroy();
|
||||
frag.destroy();
|
||||
|
||||
if (tessCont != null) tessCont.destroy();
|
||||
if (tessE != null) tessE.destroy();
|
||||
if (geom != null) geom.destroy();
|
||||
|
||||
blend = override;
|
||||
ProgramUniforms.Builder uniformBuilder = ProgramUniforms.builder(name, id);
|
||||
ProgramSamplers.Builder samplerBuilder = ProgramSamplers.builder(id, IrisSamplers.WORLD_RESERVED_TEXTURE_UNITS);
|
||||
CommonUniforms.addDynamicUniforms(uniformBuilder, FogMode.PER_VERTEX);
|
||||
customUniforms.assignTo(uniformBuilder);
|
||||
BuiltinReplacementUniforms.addBuiltinReplacementUniforms(uniformBuilder);
|
||||
ProgramImages.Builder builder = ProgramImages.builder(id);
|
||||
pipeline.addGbufferOrShadowSamplers(samplerBuilder, builder,
|
||||
isShadowPass ? pipeline::getFlippedBeforeShadow : () -> translucent ? pipeline.getFlippedAfterTranslucent() : pipeline.getFlippedAfterPrepare(),
|
||||
isShadowPass, true, true, false);
|
||||
customUniforms.mapholderToPass(uniformBuilder, this);
|
||||
this.uniforms = uniformBuilder.buildUniforms();
|
||||
this.customUniforms = customUniforms;
|
||||
samplers = samplerBuilder.build();
|
||||
images = builder.build();
|
||||
|
||||
this.va = GLStateManager.glGenVertexArrays();
|
||||
GLStateManager.glBindVertexArray(va);
|
||||
GLStateManager.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
|
||||
GLStateManager.glEnableVertexAttribArray(0);
|
||||
|
||||
projectionUniform = tryGetUniformLocation2("iris_ProjectionMatrix");
|
||||
projectionInverseUniform = tryGetUniformLocation2("iris_ProjectionMatrixInverse");
|
||||
modelViewUniform = tryGetUniformLocation2("iris_ModelViewMatrix");
|
||||
modelViewInverseUniform = tryGetUniformLocation2("iris_ModelViewMatrixInverse");
|
||||
normalMatrix3fUniform = tryGetUniformLocation2("iris_NormalMatrix");
|
||||
|
||||
this.instancedShaderOffsetChunkUniform = this.tryGetUniformLocation2("uOffsetChunk");
|
||||
this.instancedShaderOffsetSubChunkUniform = this.tryGetUniformLocation2("uOffsetSubChunk");
|
||||
this.instancedShaderCameraChunkPosUniform = this.tryGetUniformLocation2("uCameraPosChunk");
|
||||
this.instancedShaderCameraSubChunkPosUniform = this.tryGetUniformLocation2("uCameraPosSubChunk");
|
||||
this.instancedShaderProjectionModelViewMatrixUniform = this.tryGetUniformLocation2("uProjectionMvm");
|
||||
this.uBlockLight = this.tryGetUniformLocation2("uBlockLight");
|
||||
this.uSkyLight = this.tryGetUniformLocation2("uSkyLight");
|
||||
}
|
||||
|
||||
public static IrisGenericRenderProgram createProgram(String name, boolean isShadowPass, boolean translucent, ProgramSource source, CustomUniforms uniforms, DeferredWorldRenderingPipeline pipeline) {
|
||||
Map<PatchShaderType, String> transformed = TransformPatcher.patchDHGeneric(
|
||||
name,
|
||||
source.getVertexSource().orElseThrow(RuntimeException::new),
|
||||
source.getTessControlSource().orElse(null),
|
||||
source.getTessEvalSource().orElse(null),
|
||||
source.getGeometrySource().orElse(null),
|
||||
source.getFragmentSource().orElseThrow(RuntimeException::new),
|
||||
pipeline.getTextureMap());
|
||||
String vertex = transformed.get(PatchShaderType.VERTEX);
|
||||
String tessControl = transformed.get(PatchShaderType.TESS_CONTROL);
|
||||
String tessEval = transformed.get(PatchShaderType.TESS_EVAL);
|
||||
String geometry = transformed.get(PatchShaderType.GEOMETRY);
|
||||
String fragment = transformed.get(PatchShaderType.FRAGMENT);
|
||||
PatchedShaderPrinter.debugPatchedShaders(source.getName() + "_g", vertex, geometry, tessControl, tessEval, fragment);
|
||||
|
||||
List<BufferBlendOverride> bufferOverrides = new ArrayList<>();
|
||||
|
||||
source.getDirectives().getBufferBlendOverrides().forEach(information -> {
|
||||
int index = Ints.indexOf(source.getDirectives().getDrawBuffers(), information.getIndex());
|
||||
if (index > -1) {
|
||||
bufferOverrides.add(new BufferBlendOverride(index, information.getBlendMode()));
|
||||
}
|
||||
});
|
||||
|
||||
return new IrisGenericRenderProgram(name, isShadowPass, translucent, source.getDirectives().getBlendModeOverride().orElse(null), bufferOverrides.toArray(BufferBlendOverride[]::new), vertex, tessControl, tessEval, geometry, fragment, uniforms, pipeline);
|
||||
}
|
||||
|
||||
// Noise Uniforms
|
||||
|
||||
private static int getChunkPosFromDouble(double value) {
|
||||
return (int) Math.floor(value / 16);
|
||||
}
|
||||
|
||||
private static float getSubChunkPosFromDouble(double value) {
|
||||
double chunkPos = Math.floor(value / 16);
|
||||
return (float) (value - chunkPos * 16);
|
||||
}
|
||||
|
||||
public int tryGetUniformLocation2(CharSequence name) {
|
||||
return GLStateManager.glGetUniformLocation(this.id, name);
|
||||
}
|
||||
|
||||
public void setUniform(int index, Matrix4f matrix) {
|
||||
if (index == -1 || matrix == null) return;
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
FloatBuffer buffer = stack.callocFloat(16);
|
||||
matrix.get(buffer);
|
||||
buffer.rewind();
|
||||
|
||||
GLStateManager.glUniformMatrix4(index, false, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setUniform(int index, Matrix3f matrix) {
|
||||
if (index == -1) return;
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
FloatBuffer buffer = stack.callocFloat(9);
|
||||
matrix.get(buffer);
|
||||
buffer.rewind();
|
||||
|
||||
GLStateManager.glUniformMatrix3(index, false, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Override ShaderProgram.bind()
|
||||
public void bind(DhApiRenderParam renderParam) {
|
||||
GLStateManager.glBindVertexArray(va);
|
||||
GLStateManager.glUseProgram(id);
|
||||
if (blend != null) blend.apply();
|
||||
|
||||
for (BufferBlendOverride override : bufferBlendOverrides) {
|
||||
override.apply();
|
||||
}
|
||||
|
||||
toJOML(tempModel, renderParam.dhModelViewMatrix);
|
||||
toJOML(tempProj, renderParam.dhProjectionMatrix);
|
||||
|
||||
setUniform(modelViewUniform, tempModel);
|
||||
setUniform(projectionUniform, tempProj);
|
||||
this.setUniform(this.instancedShaderProjectionModelViewMatrixUniform, tempMat4.set(tempProj).mul(tempModel));
|
||||
tempModel.invert();
|
||||
tempProj.invert();
|
||||
setUniform(modelViewInverseUniform, tempModel);
|
||||
setUniform(projectionInverseUniform, tempProj);
|
||||
setUniform(normalMatrix3fUniform, tempModel.transpose3x3(tempMat3));
|
||||
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + IrisSamplers.LIGHTMAP_TEXTURE_UNIT);
|
||||
DynamicTexture lightmapTexture = ((EntityRendererAccessor) Minecraft.getMinecraft().entityRenderer).getLightmapTexture();
|
||||
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, lightmapTexture.getGlTextureId());
|
||||
|
||||
samplers.update();
|
||||
uniforms.update();
|
||||
|
||||
customUniforms.push(this);
|
||||
|
||||
images.update();
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
GLStateManager.glBindVertexArray(0);
|
||||
GLStateManager.glUseProgram(0);
|
||||
ProgramUniforms.clearActiveUniforms();
|
||||
ProgramSamplers.clearActiveSamplers();
|
||||
BlendModeOverride.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindVertexBuffer(int i) {
|
||||
GLStateManager.glBindBuffer(GL15.GL_ARRAY_BUFFER, i);
|
||||
GLStateManager.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 12, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean overrideThisFrame() {
|
||||
return IrisApi.getInstance().isShaderPackInUse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void free() {
|
||||
GLStateManager.glDeleteProgram(id);
|
||||
}
|
||||
|
||||
public void fillIndirectUniformData(DhApiRenderParam dhApiRenderParam, DhApiRenderableBoxGroupShading dhApiRenderableBoxGroupShading, IDhApiRenderableBoxGroup boxGroup, DhApiVec3d camPos) {
|
||||
bind(dhApiRenderParam);
|
||||
GLStateManager.enableDepthTest();
|
||||
GLStateManager.glDepthFunc(GL11.GL_LEQUAL);
|
||||
this.setUniform(this.instancedShaderOffsetChunkUniform,
|
||||
getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||
getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||
getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||
);
|
||||
this.setUniform(this.instancedShaderOffsetSubChunkUniform,
|
||||
getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||
getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||
getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||
);
|
||||
|
||||
this.setUniform(this.instancedShaderCameraChunkPosUniform,
|
||||
getChunkPosFromDouble(camPos.x),
|
||||
getChunkPosFromDouble(camPos.y),
|
||||
getChunkPosFromDouble(camPos.z)
|
||||
);
|
||||
this.setUniform(this.instancedShaderCameraSubChunkPosUniform,
|
||||
getSubChunkPosFromDouble(camPos.x),
|
||||
getSubChunkPosFromDouble(camPos.y),
|
||||
getSubChunkPosFromDouble(camPos.z)
|
||||
);
|
||||
this.setUniform(this.uBlockLight,
|
||||
boxGroup.getBlockLight());
|
||||
this.setUniform(this.uSkyLight,
|
||||
boxGroup.getSkyLight());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillSharedDirectUniformData(DhApiRenderParam dhApiRenderParam, DhApiRenderableBoxGroupShading dhApiRenderableBoxGroupShading, IDhApiRenderableBoxGroup iDhApiRenderableBoxGroup, DhApiVec3d dhApiVec3d) {
|
||||
throw new IllegalStateException("Only indirect is supported with Iris.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillDirectUniformData(DhApiRenderParam dhApiRenderParam, IDhApiRenderableBoxGroup iDhApiRenderableBoxGroup, DhApiRenderableBox dhApiRenderableBox, DhApiVec3d dhApiVec3d) {
|
||||
throw new IllegalStateException("Only indirect is supported with Iris.");
|
||||
}
|
||||
|
||||
private void toJOML(Matrix4f target, DhApiMat4f mat4f) {
|
||||
target.setTransposed(mat4f.getValuesAsArray());
|
||||
}
|
||||
|
||||
private void setUniform(int index, int value) {
|
||||
GLStateManager.glUniform1i(index, value);
|
||||
}
|
||||
|
||||
private void setUniform(int index, float value) {
|
||||
GLStateManager.glUniform1f(index, value);
|
||||
}
|
||||
|
||||
private void setUniform(int index, float x, float y, float z) {
|
||||
GLStateManager.glUniform3f(index, x, y, z);
|
||||
}
|
||||
|
||||
private void setUniform(int index, int x, int y, int z) {
|
||||
GLStateManager.glUniform3i(index, x, y, z);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
package net.coderbot.iris.compat.dh;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.EntityRendererAccessor;
|
||||
import com.mitchej123.lwjgl.MemoryStack;
|
||||
import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
import net.coderbot.iris.gl.blending.BlendModeOverride;
|
||||
import net.coderbot.iris.gl.blending.BufferBlendOverride;
|
||||
import net.coderbot.iris.gl.program.ProgramImages;
|
||||
import net.coderbot.iris.gl.program.ProgramSamplers;
|
||||
import net.coderbot.iris.gl.program.ProgramUniforms;
|
||||
import net.coderbot.iris.gl.shader.GlShader;
|
||||
import net.coderbot.iris.gl.shader.ShaderType;
|
||||
import net.coderbot.iris.gl.state.FogMode;
|
||||
import net.coderbot.iris.gl.texture.TextureType;
|
||||
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
|
||||
import net.coderbot.iris.pipeline.PatchedShaderPrinter;
|
||||
import net.coderbot.iris.pipeline.transform.PatchShaderType;
|
||||
import net.coderbot.iris.pipeline.transform.TransformPatcher;
|
||||
import net.coderbot.iris.samplers.IrisSamplers;
|
||||
import net.coderbot.iris.shaderpack.ProgramSource;
|
||||
import net.coderbot.iris.uniforms.CommonUniforms;
|
||||
import net.coderbot.iris.uniforms.builtin.BuiltinReplacementUniforms;
|
||||
import net.coderbot.iris.uniforms.custom.CustomUniforms;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class IrisLodRenderProgram {
|
||||
// Uniforms
|
||||
public final int modelOffsetUniform;
|
||||
public final int worldYOffsetUniform;
|
||||
public final int mircoOffsetUniform;
|
||||
public final int modelViewUniform;
|
||||
public final int modelViewInverseUniform;
|
||||
public final int projectionUniform;
|
||||
public final int projectionInverseUniform;
|
||||
public final int normalMatrix3fUniform;
|
||||
// Fog/Clip Uniforms
|
||||
public final int clipDistanceUniform;
|
||||
private final int id;
|
||||
private final ProgramUniforms uniforms;
|
||||
private final CustomUniforms customUniforms;
|
||||
private final ProgramSamplers samplers;
|
||||
private final ProgramImages images;
|
||||
private final BlendModeOverride blend;
|
||||
private final BufferBlendOverride[] bufferBlendOverrides;
|
||||
private final Matrix4f tempMat4a = new Matrix4f();
|
||||
private final Matrix4f tempMat4b = new Matrix4f();
|
||||
private final Matrix3f tempMat3 = new Matrix3f();
|
||||
|
||||
// This will bind AbstractVertexAttribute
|
||||
private IrisLodRenderProgram(String name, boolean isShadowPass, boolean translucent, BlendModeOverride override, BufferBlendOverride[] bufferBlendOverrides, String vertex, String tessControl, String tessEval, String geometry, String fragment, CustomUniforms customUniforms, DeferredWorldRenderingPipeline pipeline) {
|
||||
id = GLStateManager.glCreateProgram();
|
||||
|
||||
GLStateManager.glBindAttribLocation(this.id, 0, "vPosition");
|
||||
GLStateManager.glBindAttribLocation(this.id, 1, "iris_color");
|
||||
GLStateManager.glBindAttribLocation(this.id, 2, "irisExtra");
|
||||
|
||||
this.bufferBlendOverrides = bufferBlendOverrides;
|
||||
|
||||
GlShader vert = new GlShader(ShaderType.VERTEX, name + ".vsh", vertex);
|
||||
GLStateManager.glAttachShader(id, vert.getHandle());
|
||||
|
||||
GlShader tessCont = null;
|
||||
if (tessControl != null) {
|
||||
tessCont = new GlShader(ShaderType.TESSELATION_CONTROL, name + ".tcs", tessControl);
|
||||
GLStateManager.glAttachShader(id, tessCont.getHandle());
|
||||
}
|
||||
|
||||
GlShader tessE = null;
|
||||
if (tessEval != null) {
|
||||
tessE = new GlShader(ShaderType.TESSELATION_EVAL, name + ".tes", tessEval);
|
||||
GLStateManager.glAttachShader(id, tessE.getHandle());
|
||||
}
|
||||
|
||||
GlShader geom = null;
|
||||
if (geometry != null) {
|
||||
geom = new GlShader(ShaderType.GEOMETRY, name + ".gsh", geometry);
|
||||
GLStateManager.glAttachShader(id, geom.getHandle());
|
||||
}
|
||||
|
||||
GlShader frag = new GlShader(ShaderType.FRAGMENT, name + ".fsh", fragment);
|
||||
GLStateManager.glAttachShader(id, frag.getHandle());
|
||||
|
||||
GLStateManager.glLinkProgram(this.id);
|
||||
int status = GLStateManager.glGetProgrami(this.id, GL20.GL_LINK_STATUS);
|
||||
if (status != 1) {
|
||||
String message = "Shader link error in Iris DH program! Details: " + GLStateManager.glGetProgramInfoLog(this.id, 9999);
|
||||
this.free();
|
||||
throw new RuntimeException(message);
|
||||
} else {
|
||||
GLStateManager.glUseProgram(this.id);
|
||||
}
|
||||
|
||||
vert.destroy();
|
||||
frag.destroy();
|
||||
|
||||
if (tessCont != null) tessCont.destroy();
|
||||
if (tessE != null) tessE.destroy();
|
||||
if (geom != null) geom.destroy();
|
||||
|
||||
blend = override;
|
||||
ProgramUniforms.Builder uniformBuilder = ProgramUniforms.builder(name, id);
|
||||
ProgramSamplers.Builder samplerBuilder = ProgramSamplers.builder(id, IrisSamplers.WORLD_RESERVED_TEXTURE_UNITS);
|
||||
CommonUniforms.addDynamicUniforms(uniformBuilder, FogMode.PER_VERTEX);
|
||||
customUniforms.assignTo(uniformBuilder);
|
||||
BuiltinReplacementUniforms.addBuiltinReplacementUniforms(uniformBuilder);
|
||||
ProgramImages.Builder builder = ProgramImages.builder(id);
|
||||
pipeline.addGbufferOrShadowSamplers(samplerBuilder, builder,
|
||||
isShadowPass ? pipeline::getFlippedBeforeShadow : () -> translucent ? pipeline.getFlippedAfterTranslucent() : pipeline.getFlippedAfterPrepare(),
|
||||
isShadowPass, true, true, false);
|
||||
customUniforms.mapholderToPass(uniformBuilder, this);
|
||||
this.uniforms = uniformBuilder.buildUniforms();
|
||||
this.customUniforms = customUniforms;
|
||||
samplers = samplerBuilder.build();
|
||||
images = builder.build();
|
||||
|
||||
modelOffsetUniform = tryGetUniformLocation2("modelOffset");
|
||||
worldYOffsetUniform = tryGetUniformLocation2("worldYOffset");
|
||||
mircoOffsetUniform = tryGetUniformLocation2("mircoOffset");
|
||||
projectionUniform = tryGetUniformLocation2("iris_ProjectionMatrix");
|
||||
projectionInverseUniform = tryGetUniformLocation2("iris_ProjectionMatrixInverse");
|
||||
modelViewUniform = tryGetUniformLocation2("iris_ModelViewMatrix");
|
||||
modelViewInverseUniform = tryGetUniformLocation2("iris_ModelViewMatrixInverse");
|
||||
normalMatrix3fUniform = tryGetUniformLocation2("iris_NormalMatrix");
|
||||
|
||||
// Fog/Clip Uniforms
|
||||
clipDistanceUniform = tryGetUniformLocation2("clipDistance");
|
||||
}
|
||||
|
||||
public static IrisLodRenderProgram createProgram(String name, boolean isShadowPass, boolean translucent, ProgramSource source, CustomUniforms uniforms, DeferredWorldRenderingPipeline pipeline) {
|
||||
Map<PatchShaderType, String> transformed = TransformPatcher.patchDHTerrain(
|
||||
name,
|
||||
source.getVertexSource().orElseThrow(RuntimeException::new),
|
||||
source.getTessControlSource().orElse(null),
|
||||
source.getTessEvalSource().orElse(null),
|
||||
source.getGeometrySource().orElse(null),
|
||||
source.getFragmentSource().orElseThrow(RuntimeException::new),
|
||||
pipeline.getTextureMap());
|
||||
String vertex = transformed.get(PatchShaderType.VERTEX);
|
||||
String tessControl = transformed.get(PatchShaderType.TESS_CONTROL);
|
||||
String tessEval = transformed.get(PatchShaderType.TESS_EVAL);
|
||||
String geometry = transformed.get(PatchShaderType.GEOMETRY);
|
||||
String fragment = transformed.get(PatchShaderType.FRAGMENT);
|
||||
PatchedShaderPrinter.debugPatchedShaders(source.getName(), vertex, geometry, tessControl, tessEval, fragment);
|
||||
|
||||
List<BufferBlendOverride> bufferOverrides = new ArrayList<>();
|
||||
|
||||
source.getDirectives().getBufferBlendOverrides().forEach(information -> {
|
||||
int index = Ints.indexOf(source.getDirectives().getDrawBuffers(), information.getIndex());
|
||||
if (index > -1) {
|
||||
bufferOverrides.add(new BufferBlendOverride(index, information.getBlendMode()));
|
||||
}
|
||||
});
|
||||
|
||||
return new IrisLodRenderProgram(name, isShadowPass, translucent, source.getDirectives().getBlendModeOverride().orElse(null), bufferOverrides.toArray(BufferBlendOverride[]::new), vertex, tessControl, tessEval, geometry, fragment, uniforms, pipeline);
|
||||
}
|
||||
|
||||
// Noise Uniforms
|
||||
|
||||
public int tryGetUniformLocation2(CharSequence name) {
|
||||
return GLStateManager.glGetUniformLocation(this.id, name);
|
||||
}
|
||||
|
||||
public void setUniform(int index, Matrix4fc matrix) {
|
||||
if (index == -1 || matrix == null) return;
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
FloatBuffer buffer = stack.callocFloat(16);
|
||||
matrix.get(buffer);
|
||||
buffer.rewind();
|
||||
|
||||
GLStateManager.glUniformMatrix4(index, false, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setUniform(int index, Matrix3f matrix) {
|
||||
if (index == -1) return;
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
FloatBuffer buffer = stack.callocFloat(9);
|
||||
matrix.get(buffer);
|
||||
buffer.rewind();
|
||||
|
||||
GLStateManager.glUniformMatrix3(index, false, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Override ShaderProgram.bind()
|
||||
public void bind() {
|
||||
GLStateManager.glUseProgram(id);
|
||||
if (blend != null) blend.apply();
|
||||
|
||||
for (BufferBlendOverride override : bufferBlendOverrides) {
|
||||
override.apply();
|
||||
}
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
GLStateManager.glUseProgram(0);
|
||||
ProgramUniforms.clearActiveUniforms();
|
||||
ProgramSamplers.clearActiveSamplers();
|
||||
BlendModeOverride.restore();
|
||||
}
|
||||
|
||||
public void free() {
|
||||
GLStateManager.glDeleteProgram(id);
|
||||
}
|
||||
|
||||
public void fillUniformData(Matrix4fc projection, Matrix4fc modelView, int worldYOffset, float partialTicks) {
|
||||
GLStateManager.glUseProgram(id);
|
||||
|
||||
GLStateManager.glActiveTexture(GL13.GL_TEXTURE0 + IrisSamplers.LIGHTMAP_TEXTURE_UNIT);
|
||||
DynamicTexture lightmapTexture = ((EntityRendererAccessor) Minecraft.getMinecraft().entityRenderer).getLightmapTexture();
|
||||
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, lightmapTexture.getGlTextureId());
|
||||
setUniform(modelViewUniform, modelView);
|
||||
setUniform(modelViewInverseUniform, modelView.invert(tempMat4a));
|
||||
setUniform(projectionUniform, projection);
|
||||
setUniform(projectionInverseUniform, projection.invert(tempMat4b));
|
||||
setUniform(normalMatrix3fUniform, tempMat4a.set(modelView).invert().transpose3x3(tempMat3));
|
||||
|
||||
setUniform(mircoOffsetUniform, 0.01f); // 0.01 block offset
|
||||
|
||||
// setUniform(skyLightUniform, skyLight);
|
||||
|
||||
if (worldYOffsetUniform != -1) setUniform(worldYOffsetUniform, (float) worldYOffset);
|
||||
|
||||
// Fog/Clip Uniforms
|
||||
float dhNearClipDistance = DhApi.Delayed.renderProxy.getNearClipPlaneDistanceInBlocks(partialTicks);
|
||||
setUniform(clipDistanceUniform, dhNearClipDistance);
|
||||
|
||||
samplers.update();
|
||||
uniforms.update();
|
||||
|
||||
customUniforms.push(this);
|
||||
|
||||
images.update();
|
||||
}
|
||||
|
||||
private void setUniform(int index, float value) {
|
||||
GLStateManager.glUniform1f(index, value);
|
||||
}
|
||||
|
||||
public void setModelPos(DhApiVec3f modelPos) {
|
||||
setUniform(modelOffsetUniform, modelPos);
|
||||
}
|
||||
|
||||
private void setUniform(int index, DhApiVec3f pos) {
|
||||
GLStateManager.glUniform3f(index, pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
package net.coderbot.iris.compat.dh;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.rendering.RenderingState;
|
||||
import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogDrawMode;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeApplyShaderRenderEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeBufferRenderEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDeferredRenderEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericObjectRenderEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderSetupEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderCleanupEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderPassEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderSetupEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeTextureClearEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiColorDepthTextureCreatedEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
||||
import net.coderbot.iris.Iris;
|
||||
import net.coderbot.iris.pipeline.ShadowRenderer;
|
||||
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
|
||||
import net.coderbot.iris.shadows.ShadowRenderingState;
|
||||
import net.coderbot.iris.uniforms.CapturedRenderingState;
|
||||
import net.irisshaders.iris.api.v0.IrisApi;
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class LodRendererEvents {
|
||||
// TODO: Query actual world min height for Cubic Chunks compatibility
|
||||
private static final int WORLD_MIN_Y = 0;
|
||||
|
||||
private static boolean eventHandlersBound = false;
|
||||
|
||||
private static boolean atTranslucent = false;
|
||||
private static int textureWidth;
|
||||
private static int textureHeight;
|
||||
private static final Matrix4f tempMat4 = new Matrix4f();
|
||||
|
||||
|
||||
// constructor //
|
||||
|
||||
public static void setupEventHandlers() {
|
||||
if (!eventHandlersBound) {
|
||||
eventHandlersBound = true;
|
||||
Iris.logger.info("Queuing DH event binding...");
|
||||
|
||||
DhApiAfterDhInitEvent beforeCleanupEvent = new DhApiAfterDhInitEvent() {
|
||||
@Override
|
||||
public void afterDistantHorizonsInit(DhApiEventParam<Void> event) {
|
||||
Iris.logger.info("DH Ready, binding Iris event handlers...");
|
||||
|
||||
Iris.loadShaderpackWhenPossible();
|
||||
|
||||
setupSetDeferredBeforeRenderingEvent();
|
||||
setupReconnectDepthTextureEvent();
|
||||
setupGenericEvent();
|
||||
setupCreateDepthTextureEvent();
|
||||
setupTransparentRendererEventCancling();
|
||||
setupBeforeBufferClearEvent();
|
||||
setupBeforeRenderCleanupEvent();
|
||||
beforeBufferRenderEvent();
|
||||
setupBeforeRenderFrameBufferBinding();
|
||||
setupBeforeRenderPassEvent();
|
||||
setupBeforeApplyShaderEvent();
|
||||
DHCompatInternal.dhEnabled = DhApi.Delayed.configs.graphics().renderingEnabled().getValue();
|
||||
Iris.logger.info("DH Iris events bound.");
|
||||
}
|
||||
};
|
||||
DhApi.events.bind(DhApiAfterDhInitEvent.class, beforeCleanupEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// setup event handlers //
|
||||
|
||||
|
||||
private static void setupSetDeferredBeforeRenderingEvent() {
|
||||
DhApiBeforeRenderEvent beforeRenderEvent = new DhApiBeforeRenderEvent() {
|
||||
// this event is called before DH starts any rendering prep
|
||||
// canceling it will prevent DH from rendering for that frame
|
||||
@Override
|
||||
public void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event) {
|
||||
|
||||
DhApi.Delayed.renderProxy.setDeferTransparentRendering(IrisApi.getInstance().isShaderPackInUse() && getInstance().shouldOverride);
|
||||
DhApi.Delayed.configs.graphics().fog().drawMode().setValue(getInstance().shouldOverride ? EDhApiFogDrawMode.FOG_DISABLED : EDhApiFogDrawMode.FOG_ENABLED);
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeRenderEvent.class, beforeRenderEvent);
|
||||
}
|
||||
|
||||
private static void setupReconnectDepthTextureEvent() {
|
||||
DhApiBeforeTextureClearEvent beforeRenderEvent = new DhApiBeforeTextureClearEvent() {
|
||||
@Override
|
||||
public void beforeClear(DhApiCancelableEventParam<DhApiRenderParam> event) {
|
||||
var getResult = DhApi.Delayed.renderProxy.getDhDepthTextureId();
|
||||
if (getResult.success) {
|
||||
int depthTextureId = getResult.payload;
|
||||
getInstance().reconnectDHTextures(depthTextureId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeTextureClearEvent.class, beforeRenderEvent);
|
||||
}
|
||||
|
||||
private static void setupGenericEvent() {
|
||||
DhApiBeforeGenericRenderSetupEvent beforeRenderEvent = new DhApiBeforeGenericRenderSetupEvent() {
|
||||
@Override
|
||||
public void beforeSetup(DhApiEventParam<DhApiRenderParam> dhApiEventParam) {
|
||||
if (getInstance().getGenericFB() != null) {
|
||||
getInstance().getGenericFB().bind();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DhApiBeforeGenericObjectRenderEvent beforeDrawEvent = new DhApiBeforeGenericObjectRenderEvent() {
|
||||
@Override
|
||||
public void beforeRender(DhApiCancelableEventParam<EventParam> dhApiCancelableEventParam) {
|
||||
if (dhApiCancelableEventParam.value.resourceLocationPath.equalsIgnoreCase("Clouds")) {
|
||||
if (getInstance().avoidRenderingClouds()) {
|
||||
dhApiCancelableEventParam.cancelEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeGenericRenderSetupEvent.class, beforeRenderEvent);
|
||||
DhApi.events.bind(DhApiBeforeGenericObjectRenderEvent.class, beforeDrawEvent);
|
||||
}
|
||||
|
||||
private static DHCompatInternal getInstance() {
|
||||
return Iris.getPipelineManager().getPipeline().map(WorldRenderingPipeline::getDHCompat).map(DHCompat::getInstance).orElse(DHCompatInternal.SHADERLESS);
|
||||
}
|
||||
|
||||
private static void setupCreateDepthTextureEvent() {
|
||||
DhApiColorDepthTextureCreatedEvent beforeRenderEvent = new DhApiColorDepthTextureCreatedEvent() {
|
||||
@Override
|
||||
public void onResize(DhApiEventParam<EventParam> input) {
|
||||
textureWidth = input.value.newWidth;
|
||||
textureHeight = input.value.newHeight;
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiColorDepthTextureCreatedEvent.class, beforeRenderEvent);
|
||||
}
|
||||
|
||||
private static void setupTransparentRendererEventCancling() {
|
||||
DhApiBeforeRenderEvent beforeRenderEvent = new DhApiBeforeRenderEvent() {
|
||||
@Override
|
||||
public void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event) {
|
||||
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered() && (!getInstance().shouldOverrideShadow)) {
|
||||
event.cancelEvent();
|
||||
}
|
||||
}
|
||||
};
|
||||
DhApiBeforeDeferredRenderEvent beforeRenderEvent2 = new DhApiBeforeDeferredRenderEvent() {
|
||||
@Override
|
||||
public void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event) {
|
||||
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered() && (!getInstance().shouldOverrideShadow)) {
|
||||
event.cancelEvent();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeRenderEvent.class, beforeRenderEvent);
|
||||
DhApi.events.bind(DhApiBeforeDeferredRenderEvent.class, beforeRenderEvent2);
|
||||
}
|
||||
|
||||
private static void setupBeforeRenderCleanupEvent() {
|
||||
DhApiBeforeRenderCleanupEvent beforeCleanupEvent = new DhApiBeforeRenderCleanupEvent() {
|
||||
@Override
|
||||
public void beforeCleanup(DhApiEventParam<DhApiRenderParam> event) {
|
||||
if (getInstance().shouldOverride) {
|
||||
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
|
||||
getInstance().getShadowShader().unbind();
|
||||
} else {
|
||||
getInstance().getSolidShader().unbind();
|
||||
if (atTranslucent) {
|
||||
GLStateManager.enableCull();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeRenderCleanupEvent.class, beforeCleanupEvent);
|
||||
}
|
||||
|
||||
private static void setupBeforeBufferClearEvent() {
|
||||
DhApiBeforeTextureClearEvent beforeCleanupEvent = new DhApiBeforeTextureClearEvent() {
|
||||
@Override
|
||||
public void beforeClear(DhApiCancelableEventParam<DhApiRenderParam> event) {
|
||||
if (event.value.renderPass == EDhApiRenderPass.OPAQUE) {
|
||||
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
|
||||
event.cancelEvent();
|
||||
} else if (getInstance().shouldOverride) {
|
||||
GLStateManager.glClear(GL11.GL_DEPTH_BUFFER_BIT);
|
||||
event.cancelEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeTextureClearEvent.class, beforeCleanupEvent);
|
||||
}
|
||||
|
||||
private static void beforeBufferRenderEvent() {
|
||||
DhApiBeforeBufferRenderEvent beforeCleanupEvent = new DhApiBeforeBufferRenderEvent() {
|
||||
@Override
|
||||
public void beforeRender(DhApiEventParam<EventParam> input) {
|
||||
DHCompatInternal instance = getInstance();
|
||||
if (instance.shouldOverride) {
|
||||
DhApiVec3f modelPos = input.value.modelPos;
|
||||
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
|
||||
instance.getShadowShader().bind();
|
||||
instance.getShadowShader().setModelPos(modelPos);
|
||||
} else if (atTranslucent) {
|
||||
instance.getTranslucentShader().bind();
|
||||
instance.getTranslucentShader().setModelPos(modelPos);
|
||||
} else {
|
||||
instance.getSolidShader().bind();
|
||||
instance.getSolidShader().setModelPos(modelPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeBufferRenderEvent.class, beforeCleanupEvent);
|
||||
}
|
||||
|
||||
private static void setupBeforeRenderFrameBufferBinding() {
|
||||
DhApiBeforeRenderSetupEvent beforeRenderPassEvent = new DhApiBeforeRenderSetupEvent() {
|
||||
@Override
|
||||
public void beforeSetup(DhApiEventParam<DhApiRenderParam> event) {
|
||||
DHCompatInternal instance = getInstance();
|
||||
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiShadowCullingFrustum.class, (IDhApiOverrideable) ShadowRenderer.FRUSTUM);
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, instance.getShadowFBWrapper());
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, instance.getSolidFBWrapper());
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiGenericObjectShaderProgram.class, instance.getGenericShader());
|
||||
|
||||
if (instance.shouldOverride) {
|
||||
if (instance.getGenericShader() != null) {
|
||||
OverrideInjector.INSTANCE.bind(IDhApiGenericObjectShaderProgram.class, instance.getGenericShader());
|
||||
}
|
||||
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered() && instance.shouldOverrideShadow) {
|
||||
OverrideInjector.INSTANCE.bind(IDhApiFramebuffer.class, instance.getShadowFBWrapper());
|
||||
OverrideInjector.INSTANCE.bind(IDhApiShadowCullingFrustum.class, (IDhApiOverrideable) ShadowRenderer.FRUSTUM);
|
||||
} else {
|
||||
OverrideInjector.INSTANCE.bind(IDhApiFramebuffer.class, instance.getSolidFBWrapper());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
DhApi.events.bind(DhApiBeforeRenderSetupEvent.class, beforeRenderPassEvent);
|
||||
|
||||
}
|
||||
|
||||
private static void setupBeforeRenderPassEvent() {
|
||||
DhApiBeforeRenderPassEvent beforeCleanupEvent = new DhApiBeforeRenderPassEvent() {
|
||||
@Override
|
||||
public void beforeRender(DhApiEventParam<DhApiRenderParam> event) {
|
||||
DHCompatInternal instance = getInstance();
|
||||
|
||||
// config overrides
|
||||
if (instance.shouldOverride) {
|
||||
DhApi.Delayed.configs.graphics().ambientOcclusion().enabled().setValue(false);
|
||||
DhApi.Delayed.configs.graphics().fog().drawMode().setValue(EDhApiFogDrawMode.FOG_DISABLED);
|
||||
|
||||
if (event.value.renderPass == EDhApiRenderPass.OPAQUE_AND_TRANSPARENT) {
|
||||
Iris.logger.error("Unexpected; somehow the Opaque + Translucent pass ran with shaders on.");
|
||||
}
|
||||
} else {
|
||||
DhApi.Delayed.configs.graphics().ambientOcclusion().enabled().clearValue();
|
||||
DhApi.Delayed.configs.graphics().fog().drawMode().clearValue();
|
||||
}
|
||||
|
||||
|
||||
// cleanup
|
||||
if (event.value.renderPass == EDhApiRenderPass.OPAQUE) {
|
||||
if (instance.shouldOverride) {
|
||||
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
|
||||
instance.getShadowShader().bind();
|
||||
} else {
|
||||
instance.getSolidShader().bind();
|
||||
}
|
||||
atTranslucent = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// opaque
|
||||
if (event.value.renderPass == EDhApiRenderPass.OPAQUE) {
|
||||
float partialTicks = event.value.partialTicks;
|
||||
|
||||
if (instance.shouldOverride) {
|
||||
if (ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
|
||||
instance.getShadowShader().fillUniformData(
|
||||
ShadowRenderer.PROJECTION, ShadowRenderer.MODELVIEW,
|
||||
WORLD_MIN_Y,
|
||||
partialTicks);
|
||||
} else {
|
||||
Matrix4f projection = RenderingState.INSTANCE.getProjectionMatrix();;
|
||||
|
||||
instance.getSolidShader().fillUniformData(
|
||||
tempMat4.setPerspective(projection.perspectiveFov(), projection.m11() / projection.m00(), event.value.nearClipPlane, event.value.farClipPlane),
|
||||
RenderingState.INSTANCE.getModelViewMatrix(),
|
||||
WORLD_MIN_Y,
|
||||
partialTicks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// transparent
|
||||
if (event.value.renderPass == EDhApiRenderPass.TRANSPARENT) {
|
||||
float partialTicks = event.value.partialTicks;
|
||||
int depthTextureId = DhApi.Delayed.renderProxy.getDhDepthTextureId().payload;
|
||||
|
||||
if (instance.shouldOverrideShadow && ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
|
||||
instance.getShadowShader().bind();
|
||||
instance.getShadowFB().bind();
|
||||
atTranslucent = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance.shouldOverride && instance.getTranslucentFB() != null) {
|
||||
instance.copyTranslucents(textureWidth, textureHeight);
|
||||
instance.getTranslucentShader().bind();
|
||||
Matrix4f projection = RenderingState.INSTANCE.getProjectionMatrix();
|
||||
GLStateManager.disableCull();
|
||||
|
||||
instance.getTranslucentShader().fillUniformData(
|
||||
new Matrix4f().setPerspective(projection.perspectiveFov(), projection.m11() / projection.m00(), event.value.nearClipPlane, event.value.farClipPlane),
|
||||
RenderingState.INSTANCE.getModelViewMatrix(),
|
||||
WORLD_MIN_Y,
|
||||
partialTicks);
|
||||
|
||||
instance.getTranslucentFB().bind();
|
||||
}
|
||||
|
||||
atTranslucent = true;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeRenderPassEvent.class, beforeCleanupEvent);
|
||||
}
|
||||
|
||||
private static void setupBeforeApplyShaderEvent() {
|
||||
DhApiBeforeApplyShaderRenderEvent beforeApplyShaderEvent = new DhApiBeforeApplyShaderRenderEvent() {
|
||||
@Override
|
||||
public void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event) {
|
||||
if (IrisApi.getInstance().isShaderPackInUse()) {
|
||||
DHCompatInternal instance = getInstance();
|
||||
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiShadowCullingFrustum.class, (IDhApiOverrideable) ShadowRenderer.FRUSTUM);
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, instance.getShadowFBWrapper());
|
||||
OverrideInjector.INSTANCE.unbind(IDhApiFramebuffer.class, instance.getSolidFBWrapper());
|
||||
|
||||
event.cancelEvent();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DhApi.events.bind(DhApiBeforeApplyShaderRenderEvent.class, beforeApplyShaderEvent);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -33,12 +33,18 @@ public class IrisConfig {
|
||||
*/
|
||||
private boolean disableUpdateMessage;
|
||||
|
||||
/**
|
||||
* If debug features should be enabled. Gives much more detailed OpenGL error outputs at the cost of performance.
|
||||
*/
|
||||
private boolean enableDebugOptions;
|
||||
|
||||
private final Path propertiesPath;
|
||||
|
||||
public IrisConfig(Path propertiesPath) {
|
||||
shaderPackName = null;
|
||||
enableShaders = true;
|
||||
disableUpdateMessage = false;
|
||||
enableDebugOptions = false;
|
||||
this.propertiesPath = propertiesPath;
|
||||
}
|
||||
|
||||
@@ -103,6 +109,10 @@ public class IrisConfig {
|
||||
this.enableShaders = enabled;
|
||||
}
|
||||
|
||||
public boolean areDebugOptionsEnabled() {
|
||||
return enableDebugOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* loads the config file and then populates the string, int, and boolean entries with the parsed entries
|
||||
*
|
||||
@@ -121,6 +131,7 @@ public class IrisConfig {
|
||||
}
|
||||
shaderPackName = properties.getProperty("shaderPack");
|
||||
enableShaders = !"false".equals(properties.getProperty("enableShaders"));
|
||||
enableDebugOptions = "true".equals(properties.getProperty("enableDebugOptions"));
|
||||
disableUpdateMessage = "true".equals(properties.getProperty("disableUpdateMessage"));
|
||||
// TODO: GUI
|
||||
try {
|
||||
@@ -147,6 +158,7 @@ public class IrisConfig {
|
||||
final Properties properties = new Properties();
|
||||
properties.setProperty("shaderPack", getShaderPackName().orElse(""));
|
||||
properties.setProperty("enableShaders", enableShaders ? "true" : "false");
|
||||
properties.setProperty("enableDebugOptions", enableDebugOptions ? "true" : "false");
|
||||
properties.setProperty("disableUpdateMessage", disableUpdateMessage ? "true" : "false");
|
||||
properties.setProperty("maxShadowRenderDistance", String.valueOf(IrisVideoSettings.shadowDistance));
|
||||
// NB: This uses ISO-8859-1 with unicode escapes as the encoding
|
||||
|
||||
@@ -45,6 +45,12 @@ public class GlFramebuffer extends GlResource {
|
||||
this.hasDepthAttachment = true;
|
||||
}
|
||||
|
||||
public void addDepthAttachmentBypass(int texture) {
|
||||
final int fb = getGlId();
|
||||
RenderSystem.framebufferTexture2D(fb, GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, texture, 0);
|
||||
this.hasDepthAttachment = true;
|
||||
}
|
||||
|
||||
public void addColorAttachment(int index, int texture) {
|
||||
final int fb = getGlId();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.gtnewhorizons.angelica.Tags;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import net.coderbot.iris.compat.dh.DHCompat;
|
||||
import net.coderbot.iris.parsing.BiomeCategories;
|
||||
import net.coderbot.iris.pipeline.HandRenderer;
|
||||
import net.coderbot.iris.pipeline.WorldRenderingPhase;
|
||||
@@ -77,10 +78,32 @@ public class StandardMacros {
|
||||
define(standardDefines, "MC_SPECULAR_MAP");
|
||||
define(standardDefines, "MC_RENDER_QUALITY", "1.0");
|
||||
define(standardDefines, "MC_SHADOW_QUALITY", "1.0");
|
||||
define(standardDefines, "IS_ANGELICA");
|
||||
if (AngelicaConfig.defineIsIris) {
|
||||
define(standardDefines, "IS_IRIS");
|
||||
}
|
||||
define(standardDefines, "IS_ANGELICA");
|
||||
if (AngelicaConfig.defineIsIris) {
|
||||
define(standardDefines, "IS_IRIS");
|
||||
}
|
||||
|
||||
if (DHCompat.hasRenderingEnabled()) {
|
||||
define(standardDefines, "DISTANT_HORIZONS");
|
||||
}
|
||||
|
||||
define(standardDefines, "DH_BLOCK_UNKNOWN", String.valueOf(0));
|
||||
define(standardDefines, "DH_BLOCK_LEAVES", String.valueOf(1));
|
||||
define(standardDefines, "DH_BLOCK_STONE", String.valueOf(2));
|
||||
define(standardDefines, "DH_BLOCK_WOOD", String.valueOf(3));
|
||||
define(standardDefines, "DH_BLOCK_METAL", String.valueOf(4));
|
||||
define(standardDefines, "DH_BLOCK_DIRT", String.valueOf(5));
|
||||
define(standardDefines, "DH_BLOCK_LAVA", String.valueOf(6));
|
||||
define(standardDefines, "DH_BLOCK_DEEPSLATE", String.valueOf(7));
|
||||
define(standardDefines, "DH_BLOCK_SNOW", String.valueOf(8));
|
||||
define(standardDefines, "DH_BLOCK_SAND", String.valueOf(9));
|
||||
define(standardDefines, "DH_BLOCK_TERRACOTTA", String.valueOf(10));
|
||||
define(standardDefines, "DH_BLOCK_NETHER_STONE", String.valueOf(11));
|
||||
define(standardDefines, "DH_BLOCK_WATER", String.valueOf(12));
|
||||
define(standardDefines, "DH_BLOCK_GRASS", String.valueOf(13));
|
||||
define(standardDefines, "DH_BLOCK_AIR", String.valueOf(14));
|
||||
define(standardDefines, "DH_BLOCK_ILLUMINATED", String.valueOf(15));
|
||||
|
||||
define(standardDefines, "ANGELICA_VERSION", makeAngelicaVersion());
|
||||
define(standardDefines, "MC_HAND_DEPTH", Float.toString(HandRenderer.DEPTH));
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.coderbot.iris.gl.uniform;
|
||||
import net.coderbot.iris.gl.state.ValueUpdateNotifier;
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.Vector3i;
|
||||
import org.joml.Vector3ic;
|
||||
import org.joml.Vector4f;
|
||||
import org.joml.Vector4i;
|
||||
|
||||
@@ -43,7 +44,7 @@ public interface DynamicLocationalUniformHolder extends LocationalUniformHolder,
|
||||
return this;
|
||||
}
|
||||
|
||||
default DynamicUniformHolder uniform3i(String name, Supplier<Vector3i> value, ValueUpdateNotifier notifier) {
|
||||
default DynamicUniformHolder uniform3i(String name, Supplier<Vector3ic> value, ValueUpdateNotifier notifier) {
|
||||
location(name, UniformType.VEC3I).ifPresent(id -> addDynamicUniform(new Vector3IntegerJomlUniform(id, value, notifier), notifier));
|
||||
|
||||
return this;
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.coderbot.iris.gl.uniform;
|
||||
import net.coderbot.iris.gl.state.ValueUpdateNotifier;
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.Vector3i;
|
||||
import org.joml.Vector3ic;
|
||||
import org.joml.Vector4f;
|
||||
import org.joml.Vector4i;
|
||||
|
||||
@@ -16,7 +17,7 @@ public interface DynamicUniformHolder extends UniformHolder {
|
||||
DynamicUniformHolder uniform1f(String name, DoubleSupplier value, ValueUpdateNotifier notifier);
|
||||
DynamicUniformHolder uniform1i(String name, IntSupplier value, ValueUpdateNotifier notifier);
|
||||
DynamicUniformHolder uniform2i(String name, Supplier<Vector2i> value, ValueUpdateNotifier notifier);
|
||||
DynamicUniformHolder uniform3i(String name, Supplier<Vector3i> value, ValueUpdateNotifier notifier);
|
||||
DynamicUniformHolder uniform3i(String name, Supplier<Vector3ic> value, ValueUpdateNotifier notifier);
|
||||
DynamicUniformHolder uniform4f(String name, Supplier<Vector4f> value, ValueUpdateNotifier notifier);
|
||||
DynamicUniformHolder uniform4fArray(String name, Supplier<float[]> value, ValueUpdateNotifier notifier);
|
||||
DynamicUniformHolder uniform4i(String name, Supplier<Vector4i> value, ValueUpdateNotifier notifier);
|
||||
|
||||
@@ -2,11 +2,14 @@ package net.coderbot.iris.gl.uniform;
|
||||
|
||||
import net.minecraft.util.Vec3;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3fc;
|
||||
import org.joml.Vector3i;
|
||||
import org.joml.Vector3ic;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
@@ -70,14 +73,14 @@ public interface LocationalUniformHolder extends UniformHolder {
|
||||
}
|
||||
|
||||
@Override
|
||||
default LocationalUniformHolder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3f> value) {
|
||||
default LocationalUniformHolder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3fc> value) {
|
||||
location(name, UniformType.VEC3).ifPresent(id -> addUniform(updateFrequency, new Vector3Uniform(id, value)));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default LocationalUniformHolder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3i> value) {
|
||||
default LocationalUniformHolder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3ic> value) {
|
||||
location(name, UniformType.VEC3I).ifPresent(id -> addUniform(updateFrequency, new Vector3IntegerJomlUniform(id, value)));
|
||||
|
||||
return this;
|
||||
@@ -119,7 +122,7 @@ public interface LocationalUniformHolder extends UniformHolder {
|
||||
}
|
||||
|
||||
@Override
|
||||
default LocationalUniformHolder uniformMatrix(UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4f> value) {
|
||||
default LocationalUniformHolder uniformMatrix(UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4fc> value) {
|
||||
location(name, UniformType.MAT4).ifPresent(id -> addUniform(updateFrequency, new MatrixUniform(id, value)));
|
||||
|
||||
return this;
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.coderbot.iris.gl.uniform;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.RenderSystem;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
@@ -10,9 +11,9 @@ import java.util.function.Supplier;
|
||||
public class MatrixUniform extends Uniform {
|
||||
private final FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
|
||||
private Matrix4f cachedValue;
|
||||
private final Supplier<Matrix4f> value;
|
||||
private final Supplier<Matrix4fc> value;
|
||||
|
||||
MatrixUniform(int location, Supplier<Matrix4f> value) {
|
||||
MatrixUniform(int location, Supplier<Matrix4fc> value) {
|
||||
super(location);
|
||||
|
||||
this.cachedValue = null;
|
||||
@@ -21,7 +22,7 @@ public class MatrixUniform extends Uniform {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
final Matrix4f newValue = value.get();
|
||||
final Matrix4fc newValue = value.get();
|
||||
if( newValue == null ){
|
||||
throw new RuntimeException("MatrixUniform value is null");
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package net.coderbot.iris.gl.uniform;
|
||||
|
||||
import net.minecraft.util.Vec3;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3fc;
|
||||
import org.joml.Vector3i;
|
||||
import org.joml.Vector3ic;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
@@ -29,9 +30,9 @@ public interface UniformHolder {
|
||||
|
||||
UniformHolder uniform2i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector2i> value);
|
||||
|
||||
UniformHolder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3f> value);
|
||||
UniformHolder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3fc> value);
|
||||
|
||||
UniformHolder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3i> value);
|
||||
UniformHolder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3ic> value);
|
||||
|
||||
UniformHolder uniformVanilla3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vec3> value);
|
||||
|
||||
@@ -43,7 +44,7 @@ public interface UniformHolder {
|
||||
|
||||
UniformHolder uniform4fArray(UniformUpdateFrequency updateFrequency, String name, Supplier<float[]> value);
|
||||
|
||||
UniformHolder uniformMatrix(UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4f> value);
|
||||
UniformHolder uniformMatrix(UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4fc> value);
|
||||
|
||||
UniformHolder uniformMatrixFromArray(UniformUpdateFrequency updateFrequency, String name, Supplier<float[]> value);
|
||||
|
||||
|
||||
@@ -3,21 +3,22 @@ package net.coderbot.iris.gl.uniform;
|
||||
import com.gtnewhorizons.angelica.glsm.RenderSystem;
|
||||
import net.coderbot.iris.gl.state.ValueUpdateNotifier;
|
||||
import org.joml.Vector3i;
|
||||
import org.joml.Vector3ic;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Vector3IntegerJomlUniform extends Uniform {
|
||||
private Vector3i cachedValue;
|
||||
private final Supplier<Vector3i> value;
|
||||
private final Vector3i cachedValue;
|
||||
private final Supplier<Vector3ic> value;
|
||||
|
||||
Vector3IntegerJomlUniform(int location, Supplier<Vector3i> value) {
|
||||
Vector3IntegerJomlUniform(int location, Supplier<Vector3ic> value) {
|
||||
this(location, value, null);
|
||||
}
|
||||
|
||||
Vector3IntegerJomlUniform(int location, Supplier<Vector3i> value, ValueUpdateNotifier notifier) {
|
||||
Vector3IntegerJomlUniform(int location, Supplier<Vector3ic> value, ValueUpdateNotifier notifier) {
|
||||
super(location, notifier);
|
||||
|
||||
this.cachedValue = null;
|
||||
this.cachedValue = new Vector3i();
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -31,11 +32,11 @@ public class Vector3IntegerJomlUniform extends Uniform {
|
||||
}
|
||||
|
||||
private void updateValue() {
|
||||
Vector3i newValue = value.get();
|
||||
Vector3ic newValue = value.get();
|
||||
|
||||
if (cachedValue == null || !newValue.equals(cachedValue)) {
|
||||
cachedValue = newValue;
|
||||
RenderSystem.uniform3i(this.location, newValue.x, newValue.y, newValue.z);
|
||||
if (!newValue.equals(cachedValue)) {
|
||||
cachedValue.set(newValue.x(), newValue.y(), newValue.z());
|
||||
RenderSystem.uniform3i(this.location, cachedValue.x(), cachedValue.y(), cachedValue.z());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,16 @@ package net.coderbot.iris.gl.uniform;
|
||||
import com.gtnewhorizons.angelica.glsm.RenderSystem;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3fc;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Vector3Uniform extends Uniform {
|
||||
private final Vector3f cachedValue;
|
||||
private final Supplier<Vector3f> value;
|
||||
private final Supplier<Vector3fc> value;
|
||||
|
||||
Vector3Uniform(int location, Supplier<Vector3f> value) {
|
||||
Vector3Uniform(int location, Supplier<Vector3fc> value) {
|
||||
super(location);
|
||||
|
||||
this.cachedValue = new Vector3f();
|
||||
@@ -44,7 +45,7 @@ public class Vector3Uniform extends Uniform {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
Vector3f newValue = value.get();
|
||||
Vector3fc newValue = value.get();
|
||||
|
||||
if (!newValue.equals(cachedValue)) {
|
||||
cachedValue.set(newValue.x(), newValue.y(), newValue.z());
|
||||
|
||||
@@ -29,12 +29,14 @@ import net.coderbot.iris.gl.buffer.ShaderStorageBufferHolder;
|
||||
import net.coderbot.iris.gl.buffer.ShaderStorageInfo;
|
||||
import net.coderbot.iris.gl.framebuffer.GlFramebuffer;
|
||||
import net.coderbot.iris.gl.image.GlImage;
|
||||
import net.coderbot.iris.gl.image.ImageHolder;
|
||||
import net.coderbot.iris.gl.image.ImageInformation;
|
||||
import net.coderbot.iris.gl.program.ComputeProgram;
|
||||
import net.coderbot.iris.gl.program.Program;
|
||||
import net.coderbot.iris.gl.program.ProgramBuilder;
|
||||
import net.coderbot.iris.gl.program.ProgramImages;
|
||||
import net.coderbot.iris.gl.program.ProgramSamplers;
|
||||
import net.coderbot.iris.gl.sampler.SamplerHolder;
|
||||
import net.coderbot.iris.gl.state.FogMode;
|
||||
import net.coderbot.iris.gl.texture.DepthBufferFormat;
|
||||
import net.coderbot.iris.gl.texture.TextureType;
|
||||
@@ -177,6 +179,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
|
||||
private final boolean oldLighting;
|
||||
private final boolean allowConcurrentCompute;
|
||||
private final OptionalInt forcedShadowRenderDistanceChunks;
|
||||
private final CloudSetting dhCloudSetting;
|
||||
|
||||
private Pass current = null;
|
||||
|
||||
@@ -192,6 +195,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
|
||||
private int currentSpecularTexture;
|
||||
private PackDirectives packDirectives;
|
||||
private final Set<FeatureFlags> activeFeatures;
|
||||
private final ProgramFallbackResolver resolver;
|
||||
|
||||
public DeferredWorldRenderingPipeline(ProgramSet programs) {
|
||||
Objects.requireNonNull(programs);
|
||||
@@ -206,7 +210,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
|
||||
.map(DeferredWorldRenderingPipeline::submitCompositeTransform)
|
||||
.orElse(null);
|
||||
|
||||
final ProgramFallbackResolver resolver = new ProgramFallbackResolver(programs);
|
||||
resolver = new ProgramFallbackResolver(programs);
|
||||
final Map<Pair<String, InputAvailability>, CompletableFuture<Map<PatchShaderType, String>>> attributeTransformFutures = submitAttributeTransforms(resolver);
|
||||
|
||||
final Optional<ProgramSource> terrainSource = first(programs.getGbuffersTerrain(), programs.getGbuffersTexturedLit(), programs.getGbuffersTextured(), programs.getGbuffersBasic());
|
||||
@@ -228,6 +232,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
|
||||
this.shouldRenderWeather = programs.getPackDirectives().shouldRenderWeather();
|
||||
this.shouldRenderWeatherParticles = programs.getPackDirectives().shouldRenderWeatherParticles();
|
||||
this.shouldWriteRainAndSnowToDepthBuffer = programs.getPackDirectives().rainDepth();
|
||||
this.dhCloudSetting = programs.getPackDirectives().getDHCloudSetting();
|
||||
this.shouldRenderParticlesBeforeDeferred = programs.getPackDirectives().getParticleRenderingSettings()
|
||||
.map(s -> s == net.coderbot.iris.shaderpack.ParticleRenderingSettings.BEFORE || s == net.coderbot.iris.shaderpack.ParticleRenderingSettings.MIXED)
|
||||
.orElse(false);
|
||||
@@ -587,7 +592,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
|
||||
renderTargets, flippedAfterPrepare, flippedAfterTranslucent,
|
||||
celeritasShadowFb);
|
||||
|
||||
this.dhCompat = new DHCompat();
|
||||
this.dhCompat = new DHCompat(this, shadowDirectives.isDhShadowEnabled().orElse(true));
|
||||
}
|
||||
|
||||
private RenderTargets getRenderTargets() {
|
||||
@@ -916,6 +921,38 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
|
||||
return pass;
|
||||
}
|
||||
|
||||
public void addGbufferOrShadowSamplers(SamplerHolder samplers, ImageHolder images, Supplier<ImmutableSet<Integer>> flipped,
|
||||
boolean isShadowPass, boolean hasTexture, boolean hasLightmap, boolean hasOverlay) {
|
||||
TextureStage textureStage = TextureStage.GBUFFERS_AND_SHADOW;
|
||||
|
||||
ProgramSamplers.CustomTextureSamplerInterceptor customTextureSamplerInterceptor =
|
||||
ProgramSamplers.customTextureSamplerInterceptor(samplers, customTextureManager.getCustomTextureIdMap(textureStage));
|
||||
|
||||
IrisSamplers.addRenderTargetSamplers(customTextureSamplerInterceptor, flipped, renderTargets, false, this);
|
||||
IrisImages.addRenderTargetImages(images, flipped, renderTargets);
|
||||
|
||||
if (!shouldBindPBR) {
|
||||
shouldBindPBR = IrisSamplers.hasPBRSamplers(customTextureSamplerInterceptor);
|
||||
}
|
||||
|
||||
IrisSamplers.addLevelSamplers(customTextureSamplerInterceptor, this, whitePixel, new InputAvailability(hasTexture, hasLightmap));
|
||||
if (!isShadowPass) {
|
||||
IrisSamplers.addWorldDepthSamplers(customTextureSamplerInterceptor, renderTargets);
|
||||
}
|
||||
IrisSamplers.addNoiseSampler(customTextureSamplerInterceptor, customTextureManager.getNoiseTexture());
|
||||
IrisSamplers.addCustomImages(customTextureSamplerInterceptor, customImages);
|
||||
IrisSamplers.addCustomTextures(customTextureSamplerInterceptor, customTextureManager.getIrisCustomTextures());
|
||||
IrisImages.addCustomImages(images, customImages);
|
||||
|
||||
if (IrisSamplers.hasShadowSamplers(customTextureSamplerInterceptor)) {
|
||||
IrisSamplers.addShadowSamplers(customTextureSamplerInterceptor, shadowTargetsSupplier.get(), null, true);
|
||||
}
|
||||
|
||||
if (isShadowPass || IrisImages.hasShadowImages(images)) {
|
||||
IrisImages.addShadowColorImages(images, shadowTargetsSupplier.get(), null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPostChain;
|
||||
private boolean isMainBound = true;
|
||||
|
||||
@@ -947,6 +984,56 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
|
||||
}
|
||||
}
|
||||
|
||||
public CloudSetting getDHCloudSetting() {
|
||||
return dhCloudSetting;
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> getDHTerrainShader() {
|
||||
return resolver.resolve(ProgramId.DhTerrain);
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> getDHGenericShader() {
|
||||
return resolver.resolve(ProgramId.DhGeneric);
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> getDHWaterShader() {
|
||||
return resolver.resolve(ProgramId.DhWater);
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> getDHShadowShader() {
|
||||
return resolver.resolve(ProgramId.DhShadow);
|
||||
}
|
||||
|
||||
public CustomUniforms getCustomUniforms() {
|
||||
return customUniforms;
|
||||
}
|
||||
|
||||
public GlFramebuffer createDHFramebuffer(ProgramSource sources, boolean trans) {
|
||||
return renderTargets.createDHFramebuffer(trans ? flippedAfterTranslucent : flippedAfterPrepare,
|
||||
sources.getDirectives().getDrawBuffers());
|
||||
}
|
||||
|
||||
public ImmutableSet<Integer> getFlippedBeforeShadow() {
|
||||
return flippedBeforeShadow;
|
||||
}
|
||||
|
||||
public ImmutableSet<Integer> getFlippedAfterPrepare() {
|
||||
return flippedAfterPrepare;
|
||||
}
|
||||
|
||||
public ImmutableSet<Integer> getFlippedAfterTranslucent() {
|
||||
return flippedAfterTranslucent;
|
||||
}
|
||||
|
||||
public GlFramebuffer createDHFramebufferShadow(ProgramSource sources) {
|
||||
|
||||
return shadowRenderTargets.createDHFramebuffer(ImmutableSet.of(), new int[]{0, 1});
|
||||
}
|
||||
|
||||
public boolean hasShadowRenderTargets() {
|
||||
return shadowRenderTargets != null;
|
||||
}
|
||||
|
||||
private final class Pass {
|
||||
@Nullable
|
||||
private final Program program;
|
||||
@@ -1094,6 +1181,7 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
|
||||
// While it's possible to just clear them instead and reuse them, we'd need to investigate whether or not this
|
||||
// would help performance.
|
||||
renderTargets.destroy();
|
||||
dhCompat.clearPipeline();
|
||||
|
||||
// destroy the shadow render targets
|
||||
if (shadowRenderTargets != null) {
|
||||
|
||||
@@ -130,7 +130,7 @@ public class FixedFunctionWorldRenderingPipeline implements WorldRenderingPipeli
|
||||
return new FrameUpdateNotifier();
|
||||
}
|
||||
|
||||
private static final DHCompat DH_COMPAT = new DHCompat();
|
||||
private static final DHCompat DH_COMPAT = new DHCompat(null, false);
|
||||
|
||||
@Override
|
||||
public DHCompat getDHCompat() {
|
||||
|
||||
@@ -39,6 +39,9 @@ public class PatchedShaderPrinter {
|
||||
}
|
||||
|
||||
public static void debugPatchedShaders(String name, String vertex, String geometry, String tessControl, String tessEval, String fragment, String compute) {
|
||||
if (!Iris.getIrisConfig().areDebugOptionsEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (prettyPrintShaders) {
|
||||
final Path debugOutDir = Minecraft.getMinecraft().mcDataDir.toPath().resolve("patched_shaders");
|
||||
if (!outputLocationCleared) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.gtnewhorizons.angelica.glsm.RenderSystem;
|
||||
import com.gtnewhorizons.angelica.rendering.RenderingState;
|
||||
import com.gtnewhorizons.angelica.rendering.celeritas.CeleritasWorldRenderer;
|
||||
import net.coderbot.iris.Iris;
|
||||
import net.coderbot.iris.compat.dh.DHCompat;
|
||||
import net.coderbot.iris.gui.option.IrisVideoSettings;
|
||||
import net.coderbot.iris.layer.GbufferPrograms;
|
||||
import net.coderbot.iris.shaderpack.PackDirectives;
|
||||
@@ -43,6 +44,7 @@ import net.minecraft.profiler.Profiler;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
@@ -68,6 +70,8 @@ public class ShadowRenderer {
|
||||
public static final List<TileEntity> globalTileEntities = new ArrayList<>();
|
||||
public static boolean ACTIVE = false;
|
||||
|
||||
public static Frustrum FRUSTUM;
|
||||
|
||||
private static final Comparator<Entity> ENTITY_CLASS_COMPARATOR = Comparator.comparingInt(a -> System.identityHashCode(a.getClass()));
|
||||
private static final NonCullingFrustum NON_CULLING_FRUSTUM = new NonCullingFrustum();
|
||||
private static final CullEverythingFrustum CULL_EVERYTHING_FRUSTUM = new CullEverythingFrustum();
|
||||
@@ -111,12 +115,16 @@ public class ShadowRenderer {
|
||||
private double lastBoxCullerDistance = -1;
|
||||
private double lastAdvancedBoxCullerDistance = -1;
|
||||
private double lastTileEntityCullerDistance = -1;
|
||||
private final boolean shouldRenderDH;
|
||||
private final float nearPlane, farPlane;
|
||||
|
||||
public ShadowRenderer(ProgramSource shadow, PackDirectives directives, ShadowRenderTargets shadowRenderTargets, ShadowCompositeRenderer compositeRenderer) {
|
||||
|
||||
this.profiler = Minecraft.getMinecraft().mcProfiler;
|
||||
|
||||
final PackShadowDirectives shadowDirectives = directives.getShadowDirectives();
|
||||
this.nearPlane = shadowDirectives.getNearPlane();
|
||||
this.farPlane = shadowDirectives.getFarPlane();
|
||||
|
||||
this.halfPlaneLength = shadowDirectives.getDistance();
|
||||
this.voxelDistance = shadowDirectives.getVoxelDistance();
|
||||
@@ -129,6 +137,7 @@ public class ShadowRenderer {
|
||||
this.shouldRenderEntities = shadowDirectives.shouldRenderEntities();
|
||||
this.shouldRenderPlayer = shadowDirectives.shouldRenderPlayer();
|
||||
this.shouldRenderBlockEntities = shadowDirectives.shouldRenderBlockEntities();
|
||||
this.shouldRenderDH = shadowDirectives.isDhShadowEnabled().orElse(false);
|
||||
|
||||
this.compositeRenderer = compositeRenderer;
|
||||
|
||||
@@ -348,14 +357,16 @@ public class ShadowRenderer {
|
||||
shadowLightVectorCache.set(shadowLightPosition.x(), shadowLightPosition.y(), shadowLightPosition.z());
|
||||
shadowLightVectorCache.normalize();
|
||||
|
||||
Matrix4fc projView = ((shouldRenderDH && DHCompat.hasRenderingEnabled()) ? DHCompat.getProjection() : RenderingState.INSTANCE.getProjectionMatrix());
|
||||
|
||||
if (hasSafeZone) {
|
||||
BoxCuller distanceCuller = new BoxCuller(halfPlaneLength * renderMultiplier);
|
||||
SafeZoneCullingFrustum safeZoneFrustum = new SafeZoneCullingFrustum(
|
||||
RenderingState.INSTANCE.getModelViewMatrix(), RenderingState.INSTANCE.getProjectionMatrix(),
|
||||
RenderingState.INSTANCE.getModelViewMatrix(), projView,
|
||||
shadowLightVectorCache, boxCuller, distanceCuller);
|
||||
return holder.setInfo(safeZoneFrustum, distanceInfo, cullingInfo);
|
||||
} else {
|
||||
cachedAdvancedFrustum.init(RenderingState.INSTANCE.getModelViewMatrix(), RenderingState.INSTANCE.getProjectionMatrix(), shadowLightVectorCache, boxCuller);
|
||||
cachedAdvancedFrustum.init(RenderingState.INSTANCE.getModelViewMatrix(), projView, shadowLightVectorCache, boxCuller);
|
||||
return holder.setInfo(cachedAdvancedFrustum, distanceInfo, cullingInfo);
|
||||
}
|
||||
}
|
||||
@@ -630,12 +641,12 @@ public class ShadowRenderer {
|
||||
final MatrixStack modelView = getShadowModelView();
|
||||
MODELVIEW.set(modelView.peek().getModel());
|
||||
|
||||
final Matrix4f shadowProjection;
|
||||
final Matrix4f shadowProjection;
|
||||
if (this.fov != null) {
|
||||
// If FOV is not null, the pack wants a perspective based projection matrix. (This is to support legacy packs)
|
||||
shadowProjection = ShadowMatrices.createPerspectiveMatrix(this.fov);
|
||||
shadowProjection = ShadowMatrices.createPerspectiveMatrix(this.fov);
|
||||
} else {
|
||||
shadowProjection = ShadowMatrices.createOrthoMatrix(halfPlaneLength);
|
||||
shadowProjection = ShadowMatrices.createOrthoMatrix(halfPlaneLength, nearPlane < 0 ? -DHCompat.getRenderDistance() : nearPlane, farPlane < 0 ? DHCompat.getRenderDistance() : farPlane);
|
||||
}
|
||||
|
||||
PROJECTION.set(shadowProjection);
|
||||
@@ -649,6 +660,7 @@ public class ShadowRenderer {
|
||||
profiler.startSection("initialize frustum");
|
||||
|
||||
terrainFrustumHolder = createShadowFrustum(renderDistanceMultiplier, terrainFrustumHolder);
|
||||
FRUSTUM = terrainFrustumHolder.getFrustum();
|
||||
|
||||
// Use the player/entity position for shadow rendering
|
||||
final Vector3d entityPos = playerCamera.getEntityPos();
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package net.coderbot.iris.pipeline.transform;
|
||||
|
||||
import net.coderbot.iris.gl.shader.ShaderType;
|
||||
import net.coderbot.iris.pipeline.transform.parameter.Parameters;
|
||||
import org.taumc.glsl.Transformer;
|
||||
|
||||
public class DHGenericTransformer {
|
||||
public static void transform(Transformer transformer, Parameters parameters, int glslVersion) {
|
||||
CommonTransformer.transform(transformer, parameters, true, glslVersion);
|
||||
|
||||
transformer.replaceExpression("gl_TextureMatrix[0]", "mat4(1.0)");
|
||||
transformer.replaceExpression("gl_TextureMatrix[1]", "mat4(1.0)");
|
||||
transformer.rename("gl_ProjectionMatrix", "iris_ProjectionMatrix");
|
||||
|
||||
if (parameters.type == ShaderType.VERTEX) {
|
||||
// Alias of gl_MultiTexCoord1 on 1.15+ for OptiFine
|
||||
// See https://github.com/IrisShaders/Iris/issues/1149
|
||||
transformer.rename("gl_MultiTexCoord2", "gl_MultiTexCoord1");
|
||||
|
||||
transformer.replaceExpression("gl_MultiTexCoord0", "vec4(0.0, 0.0, 0.0, 1.0)");
|
||||
transformer.replaceExpression("gl_MultiTexCoord1", "vec4(_vert_tex_light_coord, 0.0, 1.0)");
|
||||
|
||||
replaceGlMultiTexCoordBounded(transformer, 4, 7);
|
||||
}
|
||||
|
||||
transformer.rename("gl_Color", "_vert_color");
|
||||
|
||||
if (parameters.type == ShaderType.VERTEX) {
|
||||
transformer.replaceExpression("gl_Normal", "_vert_normal");
|
||||
}
|
||||
|
||||
transformer.replaceExpression("gl_NormalMatrix", "iris_NormalMatrix");
|
||||
addIfNotExists(transformer, "iris_NormalMatrix", "uniform mat3 iris_NormalMatrix;");
|
||||
addIfNotExists(transformer, "iris_ModelViewMatrixInverse", "uniform mat4 iris_ModelViewMatrixInverse;");
|
||||
addIfNotExists(transformer, "iris_ProjectionMatrixInverse", "uniform mat4 iris_ProjectionMatrixInverse;");
|
||||
|
||||
transformer.rename("gl_ModelViewMatrix", "iris_ModelViewMatrix");
|
||||
transformer.rename("gl_ModelViewMatrixInverse", "iris_ModelViewMatrixInverse");
|
||||
transformer.rename("gl_ProjectionMatrixInverse", "iris_ProjectionMatrixInverse");
|
||||
|
||||
if (parameters.type == ShaderType.VERTEX) {
|
||||
if (transformer.containsCall("ftransform")) {
|
||||
transformer.injectFunction("vec4 ftransform() { return gl_ModelViewProjectionMatrix * gl_Vertex; }");
|
||||
}
|
||||
|
||||
addIfNotExists(transformer, "iris_ProjectionMatrix", "uniform mat4 iris_ProjectionMatrix;");
|
||||
addIfNotExists(transformer, "iris_ModelViewMatrix", "uniform mat4 iris_ModelViewMatrix;");
|
||||
transformer.injectFunction("vec4 getVertexPosition() { return vec4(_vert_position, 1.0); }");
|
||||
transformer.replaceExpression("gl_Vertex", "getVertexPosition()");
|
||||
|
||||
injectVertInit(transformer);
|
||||
} else {
|
||||
addIfNotExists(transformer, "iris_ModelViewMatrix", "uniform mat4 iris_ModelViewMatrix;");
|
||||
addIfNotExists(transformer, "iris_ProjectionMatrix", "uniform mat4 iris_ProjectionMatrix;");
|
||||
}
|
||||
|
||||
transformer.replaceExpression("gl_ModelViewProjectionMatrix", "(iris_ProjectionMatrix * iris_ModelViewMatrix)");
|
||||
ShaderTransformer.applyIntelHd4000Workaround(transformer);
|
||||
}
|
||||
|
||||
public static void injectVertInit(Transformer transformer) {
|
||||
addIfNotExists(transformer, "_vert_position", "vec3 _vert_position;");
|
||||
addIfNotExists(transformer, "_vert_tex_light_coord", "vec2 _vert_tex_light_coord;");
|
||||
addIfNotExists(transformer, "dhMaterialId", "int dhMaterialId;");
|
||||
addIfNotExists(transformer, "_vert_color", "vec4 _vert_color;");
|
||||
addIfNotExists(transformer, "_vert_normal", "vec3 _vert_normal;");
|
||||
addIfNotExists(transformer, "uOffsetChunk", "uniform ivec3 uOffsetChunk;");
|
||||
addIfNotExists(transformer, "uOffsetSubChunk", "uniform vec3 uOffsetSubChunk;");
|
||||
addIfNotExists(transformer, "uCameraPosChunk", "uniform ivec3 uCameraPosChunk;");
|
||||
addIfNotExists(transformer, "uCameraPosSubChunk", "uniform vec3 uCameraPosSubChunk;");
|
||||
addIfNotExists(transformer, "uSkyLight", "uniform int uSkyLight;");
|
||||
addIfNotExists(transformer, "uBlockLight", "uniform int uBlockLight;");
|
||||
addIfNotExists(transformer, "iris_color", "in vec4 iris_color;");
|
||||
addIfNotExists(transformer, "aScale", "in vec3 aScale;");
|
||||
addIfNotExists(transformer, "aTranslateChunk", "in ivec3 aTranslateChunk;");
|
||||
addIfNotExists(transformer, "aTranslateSubChunk", "in vec3 aTranslateSubChunk;");
|
||||
addIfNotExists(transformer, "aMaterial", "in int aMaterial;");
|
||||
addIfNotExists(transformer, "vPosition", "in vec3 vPosition;");
|
||||
|
||||
transformer.injectFunction("const vec3 irisNormals[6] = vec3[](vec3(0,0,-1), vec3(0,0,1), vec3(-1,0,0), vec3(1,0,0), vec3(0,-1,0), vec3(0,1,0));");
|
||||
transformer.injectFunction(
|
||||
"void _vert_init() {"
|
||||
+ " vec3 trans = vec3(aTranslateChunk + uOffsetChunk - uCameraPosChunk) * 16.0;"
|
||||
+ " trans += (aTranslateSubChunk + uOffsetSubChunk - uCameraPosSubChunk);"
|
||||
+ " mat4 transform = mat4("
|
||||
+ " aScale.x, 0.0, 0.0, 0.0,"
|
||||
+ " 0.0, aScale.y, 0.0, 0.0,"
|
||||
+ " 0.0, 0.0, aScale.z, 0.0,"
|
||||
+ " trans.x, trans.y, trans.z, 1.0"
|
||||
+ " );"
|
||||
+ " _vert_position = (transform * vec4(vPosition, 1.0)).xyz;"
|
||||
+ " _vert_normal = irisNormals[int(floor(float(gl_VertexID) / 4.0))];"
|
||||
+ " float blockLight = (float(uBlockLight) + 0.5) / 16.0;"
|
||||
+ " float skyLight = (float(uSkyLight) + 0.5) / 16.0;"
|
||||
+ " _vert_tex_light_coord = vec2(blockLight, skyLight);"
|
||||
+ " dhMaterialId = aMaterial;"
|
||||
+ " _vert_color = iris_color;"
|
||||
+ " }"
|
||||
);
|
||||
transformer.prependMain("_vert_init();");
|
||||
}
|
||||
|
||||
private static void addIfNotExists(Transformer transformer, String name, String code) {
|
||||
if (!transformer.hasVariable(name)) {
|
||||
transformer.injectVariable(code);
|
||||
}
|
||||
}
|
||||
|
||||
private static void replaceGlMultiTexCoordBounded(Transformer transformer, int from, int to) {
|
||||
for (int i = from; i <= to; i++) {
|
||||
transformer.replaceExpression("gl_MultiTexCoord" + i, "vec4(0.0, 0.0, 0.0, 1.0)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package net.coderbot.iris.pipeline.transform;
|
||||
|
||||
import net.coderbot.iris.gl.shader.ShaderType;
|
||||
import net.coderbot.iris.pipeline.transform.parameter.Parameters;
|
||||
import org.taumc.glsl.Transformer;
|
||||
|
||||
public class DHTerrainTransformer {
|
||||
public static void transform(Transformer transformer, Parameters parameters, int glslVersion) {
|
||||
CommonTransformer.transform(transformer, parameters, true, glslVersion);
|
||||
|
||||
transformer.replaceExpression("gl_TextureMatrix[0]", "mat4(1.0)");
|
||||
transformer.replaceExpression("gl_TextureMatrix[1]", "mat4(1.0)");
|
||||
transformer.rename("gl_ProjectionMatrix", "iris_ProjectionMatrix");
|
||||
|
||||
if (parameters.type == ShaderType.VERTEX) {
|
||||
// Alias of gl_MultiTexCoord1 on 1.15+ for OptiFine
|
||||
// See https://github.com/IrisShaders/Iris/issues/1149
|
||||
transformer.rename("gl_MultiTexCoord2", "gl_MultiTexCoord1");
|
||||
|
||||
transformer.replaceExpression("gl_MultiTexCoord0", "vec4(0.0, 0.0, 0.0, 1.0)");
|
||||
transformer.replaceExpression("gl_MultiTexCoord1", "vec4(_vert_tex_light_coord, 0.0, 1.0)");
|
||||
|
||||
replaceGlMultiTexCoordBounded(transformer, 4, 7);
|
||||
}
|
||||
|
||||
transformer.rename("gl_Color", "_vert_color");
|
||||
|
||||
if (parameters.type == ShaderType.VERTEX) {
|
||||
transformer.replaceExpression("gl_Normal", "_vert_normal");
|
||||
}
|
||||
|
||||
transformer.replaceExpression("gl_NormalMatrix", "iris_NormalMatrix");
|
||||
addIfNotExists(transformer, "iris_NormalMatrix", "uniform mat3 iris_NormalMatrix;");
|
||||
addIfNotExists(transformer, "iris_ModelViewMatrixInverse", "uniform mat4 iris_ModelViewMatrixInverse;");
|
||||
addIfNotExists(transformer, "iris_ProjectionMatrixInverse", "uniform mat4 iris_ProjectionMatrixInverse;");
|
||||
|
||||
transformer.rename("gl_ModelViewMatrix", "iris_ModelViewMatrix");
|
||||
transformer.rename("gl_ModelViewMatrixInverse", "iris_ModelViewMatrixInverse");
|
||||
transformer.rename("gl_ProjectionMatrixInverse", "iris_ProjectionMatrixInverse");
|
||||
|
||||
if (parameters.type == ShaderType.VERTEX) {
|
||||
if (transformer.containsCall("ftransform")) {
|
||||
transformer.injectFunction("vec4 ftransform() { return gl_ModelViewProjectionMatrix * gl_Vertex; }");
|
||||
}
|
||||
|
||||
addIfNotExists(transformer, "iris_ProjectionMatrix", "uniform mat4 iris_ProjectionMatrix;");
|
||||
addIfNotExists(transformer, "iris_ModelViewMatrix", "uniform mat4 iris_ModelViewMatrix;");
|
||||
transformer.injectFunction("vec4 getVertexPosition() { return vec4(modelOffset + _vert_position, 1.0); }");
|
||||
transformer.replaceExpression("gl_Vertex", "getVertexPosition()");
|
||||
|
||||
injectVertInit(transformer);
|
||||
} else {
|
||||
addIfNotExists(transformer, "iris_ModelViewMatrix", "uniform mat4 iris_ModelViewMatrix;");
|
||||
addIfNotExists(transformer, "iris_ProjectionMatrix", "uniform mat4 iris_ProjectionMatrix;");
|
||||
}
|
||||
|
||||
transformer.replaceExpression("gl_ModelViewProjectionMatrix", "(iris_ProjectionMatrix * iris_ModelViewMatrix)");
|
||||
ShaderTransformer.applyIntelHd4000Workaround(transformer);
|
||||
}
|
||||
|
||||
public static void injectVertInit(Transformer transformer) {
|
||||
addIfNotExists(transformer, "_vert_position", "vec3 _vert_position;");
|
||||
addIfNotExists(transformer, "_vert_tex_light_coord", "vec2 _vert_tex_light_coord;");
|
||||
addIfNotExists(transformer, "dhMaterialId", "int dhMaterialId;");
|
||||
addIfNotExists(transformer, "_vert_color", "vec4 _vert_color;");
|
||||
addIfNotExists(transformer, "_vert_normal", "vec3 _vert_normal;");
|
||||
addIfNotExists(transformer, "mircoOffset", "uniform float mircoOffset;");
|
||||
addIfNotExists(transformer, "modelOffset", "uniform vec3 modelOffset;");
|
||||
addIfNotExists(transformer, "iris_color", "in vec4 iris_color;");
|
||||
addIfNotExists(transformer, "vPosition", "in uvec4 vPosition;");
|
||||
addIfNotExists(transformer, "irisExtra", "in uvec4 irisExtra;");
|
||||
|
||||
transformer.injectFunction("const vec3 irisNormals[6] = vec3[](vec3(0,-1,0), vec3(0,1,0), vec3(0,0,-1), vec3(0,0,1), vec3(-1,0,0), vec3(1,0,0));");
|
||||
transformer.injectFunction(
|
||||
"void _vert_init() {"
|
||||
+ " uint meta = vPosition.a;"
|
||||
+ " uint mirco = (meta & 0xFF00u) >> 8u;"
|
||||
+ " float mx = (mirco & 1u) != 0u ? mircoOffset : 0.0;"
|
||||
+ " mx = (mirco & 2u) != 0u ? -mx : mx;"
|
||||
+ " float my = (mirco & 4u) != 0u ? mircoOffset : 0.0;"
|
||||
+ " my = (mirco & 8u) != 0u ? -my : my;"
|
||||
+ " float mz = (mirco & 16u) != 0u ? mircoOffset : 0.0;"
|
||||
+ " mz = (mirco & 32u) != 0u ? -mz : mz;"
|
||||
+ " uint lights = meta & 0xFFu;"
|
||||
+ " _vert_position = (vPosition.xyz + vec3(mx, my, mz));"
|
||||
+ " _vert_normal = irisNormals[int(irisExtra.y)];"
|
||||
+ " dhMaterialId = int(irisExtra.x);"
|
||||
+ " _vert_tex_light_coord = vec2((float(lights / 16u) + 0.5) / 16.0, (mod(float(lights), 16.0) + 0.5) / 16.0);"
|
||||
+ " _vert_color = iris_color;"
|
||||
+ " }"
|
||||
);
|
||||
transformer.prependMain("_vert_init();");
|
||||
}
|
||||
|
||||
private static void addIfNotExists(Transformer transformer, String name, String code) {
|
||||
if (!transformer.hasVariable(name)) {
|
||||
transformer.injectVariable(code);
|
||||
}
|
||||
}
|
||||
|
||||
private static void replaceGlMultiTexCoordBounded(Transformer transformer, int from, int to) {
|
||||
for (int i = from; i <= to; i++) {
|
||||
transformer.replaceExpression("gl_MultiTexCoord" + i, "vec4(0.0, 0.0, 0.0, 1.0)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,7 @@ public enum Patch {
|
||||
ATTRIBUTES,
|
||||
CELERITAS_TERRAIN,
|
||||
COMPOSITE,
|
||||
COMPUTE
|
||||
COMPUTE,
|
||||
DH_TERRAIN,
|
||||
DH_GENERIC
|
||||
}
|
||||
@@ -439,6 +439,12 @@ public class ShaderTransformer {
|
||||
case COMPUTE:
|
||||
ComputeTransformer.transform(transformer, parameters, versionInt);
|
||||
break;
|
||||
case DH_TERRAIN:
|
||||
DHTerrainTransformer.transform(transformer, parameters, versionInt);
|
||||
break;
|
||||
case DH_GENERIC:
|
||||
DHGenericTransformer.transform(transformer, parameters, versionInt);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown patch type: " + patchType.name());
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.coderbot.iris.helpers.Tri;
|
||||
import net.coderbot.iris.pipeline.transform.parameter.AttributeParameters;
|
||||
import net.coderbot.iris.pipeline.transform.parameter.CeleritasTerrainParameters;
|
||||
import net.coderbot.iris.pipeline.transform.parameter.ComputeParameters;
|
||||
import net.coderbot.iris.pipeline.transform.parameter.DHParameters;
|
||||
import net.coderbot.iris.pipeline.transform.parameter.Parameters;
|
||||
import net.coderbot.iris.pipeline.transform.parameter.TextureStageParameters;
|
||||
import net.coderbot.iris.shaderpack.texture.TextureStage;
|
||||
@@ -127,6 +128,23 @@ public class TransformPatcher {
|
||||
return transform(vertex, geometry, tessControl, tessEval, fragment, new TextureStageParameters(Patch.COMPOSITE, stage, textureMap));
|
||||
}
|
||||
|
||||
|
||||
public static Map<PatchShaderType, String> patchDHTerrain(
|
||||
String name, String vertex, String tessControl, String tessEval, String geometry, String fragment,
|
||||
Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
|
||||
return transform(vertex, geometry, tessControl, tessEval, fragment,
|
||||
new DHParameters(Patch.DH_TERRAIN, textureMap));
|
||||
}
|
||||
|
||||
|
||||
public static Map<PatchShaderType, String> patchDHGeneric(
|
||||
String name, String vertex, String tessControl, String tessEval, String geometry, String fragment,
|
||||
Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
|
||||
return transform(vertex, geometry, tessControl, tessEval, fragment,
|
||||
new DHParameters(Patch.DH_GENERIC, textureMap));
|
||||
|
||||
}
|
||||
|
||||
public static Map<PatchShaderType, String> patchComposite(String vertex, String geometry, String fragment, TextureStage stage, Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
|
||||
return patchComposite(vertex, geometry, null, null, fragment, stage, textureMap);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.coderbot.iris.pipeline.transform.parameter;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import net.coderbot.iris.gl.texture.TextureType;
|
||||
import net.coderbot.iris.helpers.Tri;
|
||||
import net.coderbot.iris.pipeline.transform.Patch;
|
||||
import net.coderbot.iris.shaderpack.texture.TextureStage;
|
||||
|
||||
public class DHParameters extends Parameters {
|
||||
public DHParameters(Patch patch, Object2ObjectMap<Tri<String, TextureType, TextureStage>, String> textureMap) {
|
||||
super(patch, textureMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureStage getTextureStage() {
|
||||
return TextureStage.GBUFFERS_AND_SHADOW;
|
||||
}
|
||||
}
|
||||
@@ -248,6 +248,16 @@ public class RenderTargets {
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
public GlFramebuffer createDHFramebuffer(ImmutableSet<Integer> stageWritesToAlt, int[] drawBuffers) {
|
||||
if (drawBuffers.length == 0) {
|
||||
return createEmptyFramebuffer();
|
||||
}
|
||||
|
||||
ImmutableSet<Integer> stageWritesToMain = invert(stageWritesToAlt, drawBuffers);
|
||||
|
||||
return createColorFramebuffer(stageWritesToMain, drawBuffers);
|
||||
}
|
||||
|
||||
public GlFramebuffer createGbufferFramebuffer(ImmutableSet<Integer> stageWritesToAlt, int[] drawBuffers) {
|
||||
if (drawBuffers.length == 0) {
|
||||
return createEmptyFramebuffer();
|
||||
|
||||
@@ -28,7 +28,7 @@ public class PackDirectives {
|
||||
@Getter private float eyeBrightnessHalfLife;
|
||||
@Getter private float centerDepthHalfLife;
|
||||
@Getter private CloudSetting cloudSetting;
|
||||
@Getter private CloudSetting dhCloudSetting;
|
||||
private CloudSetting dhCloudSetting;
|
||||
private boolean underwaterOverlay;
|
||||
private boolean vignette;
|
||||
private boolean sun;
|
||||
@@ -181,6 +181,10 @@ public class PackDirectives {
|
||||
return concurrentCompute;
|
||||
}
|
||||
|
||||
public CloudSetting getDHCloudSetting() {
|
||||
return dhCloudSetting;
|
||||
}
|
||||
|
||||
private static float clamp(float val, float lo, float hi) {
|
||||
return Math.max(lo, Math.min(hi, val));
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ public class PackShadowDirectives {
|
||||
private final boolean shouldRenderPlayer;
|
||||
private final boolean shouldRenderBlockEntities;
|
||||
@Getter private final ShadowCullState cullingState;
|
||||
private final OptionalBoolean dhShadowEnabled;
|
||||
private float nearPlane, farPlane;
|
||||
|
||||
private final ImmutableList<DepthSamplingSettings> depthSamplingSettings;
|
||||
private final ImmutableList<SamplingSettings> colorSamplingSettings;
|
||||
@@ -53,6 +55,8 @@ public class PackShadowDirectives {
|
||||
// shadowRenderDistanceMul to a nonzero value, since having a high shadow render distance will impact
|
||||
// performance quite heavily on most systems.
|
||||
this.distance = 160.0f;
|
||||
this.nearPlane = 0.05f;
|
||||
this.farPlane = 256.0f;
|
||||
this.voxelDistance = 0.0f;
|
||||
|
||||
// By default, shadows are not culled based on distance from the player. However, pack authors may
|
||||
@@ -81,6 +85,7 @@ public class PackShadowDirectives {
|
||||
this.shouldRenderBlockEntities = properties.getShadowBlockEntities().orElse(true);
|
||||
this.cullingState = properties.getShadowCulling();
|
||||
this.shadowEnabled = properties.getShadowEnabled();
|
||||
this.dhShadowEnabled = properties.getDhShadowEnabled();
|
||||
|
||||
this.depthSamplingSettings = ImmutableList.of(new DepthSamplingSettings(), new DepthSamplingSettings());
|
||||
|
||||
@@ -97,6 +102,8 @@ public class PackShadowDirectives {
|
||||
this.resolution = shadowDirectives.resolution;
|
||||
this.fov = shadowDirectives.fov;
|
||||
this.distance = shadowDirectives.distance;
|
||||
this.nearPlane = shadowDirectives.nearPlane;
|
||||
this.farPlane = shadowDirectives.farPlane;
|
||||
this.voxelDistance = shadowDirectives.voxelDistance;
|
||||
this.distanceRenderMul = shadowDirectives.distanceRenderMul;
|
||||
this.entityShadowDistanceMul = shadowDirectives.entityShadowDistanceMul;
|
||||
@@ -111,6 +118,7 @@ public class PackShadowDirectives {
|
||||
this.depthSamplingSettings = shadowDirectives.depthSamplingSettings;
|
||||
this.colorSamplingSettings = shadowDirectives.colorSamplingSettings;
|
||||
this.shadowEnabled = shadowDirectives.shadowEnabled;
|
||||
this.dhShadowEnabled = shadowDirectives.dhShadowEnabled;
|
||||
}
|
||||
|
||||
public int getResolution() {
|
||||
@@ -125,6 +133,18 @@ public class PackShadowDirectives {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public float getNearPlane() {
|
||||
return nearPlane;
|
||||
}
|
||||
|
||||
public float getFarPlane() {
|
||||
return farPlane;
|
||||
}
|
||||
|
||||
public OptionalBoolean isDhShadowEnabled() {
|
||||
return dhShadowEnabled;
|
||||
}
|
||||
|
||||
public float getVoxelDistance() {
|
||||
return voxelDistance;
|
||||
}
|
||||
@@ -186,7 +206,8 @@ public class PackShadowDirectives {
|
||||
|
||||
directives.acceptCommentFloatDirective("SHADOWHPL", distance -> this.distance = distance);
|
||||
directives.acceptConstFloatDirective("shadowDistance", distance -> this.distance = distance);
|
||||
|
||||
directives.acceptConstFloatDirective("shadowNearPlane", nearPlane -> this.nearPlane = nearPlane);
|
||||
directives.acceptConstFloatDirective("shadowFarPlane", farPlane -> this.farPlane = farPlane);
|
||||
directives.acceptConstFloatDirective("entityShadowDistanceMul", distance -> this.entityShadowDistanceMul = distance);
|
||||
|
||||
directives.acceptConstFloatDirective("shadowDistanceRenderMul", distanceRenderMul -> {
|
||||
|
||||
@@ -56,7 +56,10 @@ public class ProgramSet {
|
||||
private final ComputeSource[][] compositeCompute;
|
||||
private final ProgramSource compositeFinal;
|
||||
private final ComputeSource[] finalCompute;
|
||||
|
||||
private final ProgramSource dhTerrain;
|
||||
private final ProgramSource dhGeneric;
|
||||
private final ProgramSource dhWater;
|
||||
private final ProgramSource dhShadow;
|
||||
|
||||
private final ShaderPack pack;
|
||||
|
||||
@@ -119,6 +122,10 @@ public class ProgramSet {
|
||||
this.gbuffersBlock = readProgramSource(directory, sourceProvider, "gbuffers_block", this, shaderProperties);
|
||||
this.gbuffersBlockTrans = readProgramSource(directory, sourceProvider, "gbuffers_block_translucent", this, shaderProperties);
|
||||
this.gbuffersHand = readProgramSource(directory, sourceProvider, "gbuffers_hand", this, shaderProperties);
|
||||
this.dhTerrain = readProgramSource(directory, sourceProvider, "dh_terrain", this, shaderProperties);
|
||||
this.dhGeneric = readProgramSource(directory, sourceProvider, "dh_generic", this, shaderProperties);
|
||||
this.dhWater = readProgramSource(directory, sourceProvider, "dh_water", this, shaderProperties);
|
||||
this.dhShadow = readProgramSource(directory, sourceProvider, "dh_shadow", this, shaderProperties);
|
||||
|
||||
this.deferred = readProgramArray(directory, sourceProvider, "deferred", shaderProperties);
|
||||
this.deferredCompute = new ComputeSource[deferred.length][];
|
||||
@@ -219,7 +226,7 @@ public class ProgramSet {
|
||||
gbuffersBasic, gbuffersBeaconBeam, gbuffersTextured, gbuffersTexturedLit, gbuffersTerrain,
|
||||
gbuffersDamagedBlock, gbuffersSkyBasic, gbuffersSkyTextured, gbuffersClouds, gbuffersWeather,
|
||||
gbuffersEntities, gbuffersEntitiesTrans, gbuffersEntitiesGlowing, gbuffersGlint, gbuffersEntityEyes, gbuffersBlock, gbuffersBlockTrans,
|
||||
gbuffersHand
|
||||
gbuffersHand, dhShadow, dhTerrain, dhGeneric, dhWater
|
||||
));
|
||||
|
||||
for (ComputeSource[] computeSources : compositeCompute) {
|
||||
@@ -387,33 +394,53 @@ public class ProgramSet {
|
||||
return gbuffersHand.requireValid();
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> getDhTerrain() {
|
||||
return dhTerrain.requireValid();
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> getDhGeneric() {
|
||||
return dhGeneric.requireValid();
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> getDhWater() {
|
||||
return dhWater.requireValid();
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> getDhShadow() {
|
||||
return dhShadow.requireValid();
|
||||
}
|
||||
|
||||
public Optional<ProgramSource> get(ProgramId programId) {
|
||||
return switch (programId) {
|
||||
case Shadow -> getShadow();
|
||||
case Basic -> getGbuffersBasic();
|
||||
case Line -> gbuffersLine.requireValid();
|
||||
case Textured -> getGbuffersTextured();
|
||||
case TexturedLit -> getGbuffersTexturedLit();
|
||||
case SkyBasic -> getGbuffersSkyBasic();
|
||||
case SkyTextured -> getGbuffersSkyTextured();
|
||||
case Clouds -> getGbuffersClouds();
|
||||
case Terrain -> getGbuffersTerrain();
|
||||
case DamagedBlock -> getGbuffersDamagedBlock();
|
||||
case Block -> getGbuffersBlock();
|
||||
return switch (programId) {
|
||||
case Shadow -> getShadow();
|
||||
case Basic -> getGbuffersBasic();
|
||||
case Line -> gbuffersLine.requireValid();
|
||||
case Textured -> getGbuffersTextured();
|
||||
case TexturedLit -> getGbuffersTexturedLit();
|
||||
case SkyBasic -> getGbuffersSkyBasic();
|
||||
case SkyTextured -> getGbuffersSkyTextured();
|
||||
case Clouds -> getGbuffersClouds();
|
||||
case Terrain -> getGbuffersTerrain();
|
||||
case DamagedBlock -> getGbuffersDamagedBlock();
|
||||
case Block -> getGbuffersBlock();
|
||||
case BlockTrans -> getGbuffersBlockTrans();
|
||||
case BeaconBeam -> getGbuffersBeaconBeam();
|
||||
case Entities -> getGbuffersEntities();
|
||||
case EntitiesTrans -> getGbuffersEntitiesTrans();
|
||||
case EntitiesGlowing -> getGbuffersEntitiesGlowing();
|
||||
case ArmorGlint -> getGbuffersGlint();
|
||||
case SpiderEyes -> getGbuffersEntityEyes();
|
||||
case Hand -> getGbuffersHand();
|
||||
case Weather -> getGbuffersWeather();
|
||||
case Water -> getGbuffersWater();
|
||||
case HandWater -> getGbuffersHandWater();
|
||||
case Final -> getCompositeFinal();
|
||||
default -> Optional.empty();
|
||||
};
|
||||
case BeaconBeam -> getGbuffersBeaconBeam();
|
||||
case Entities -> getGbuffersEntities();
|
||||
case EntitiesTrans -> getGbuffersEntitiesTrans();
|
||||
case EntitiesGlowing -> getGbuffersEntitiesGlowing();
|
||||
case ArmorGlint -> getGbuffersGlint();
|
||||
case SpiderEyes -> getGbuffersEntityEyes();
|
||||
case Hand -> getGbuffersHand();
|
||||
case Weather -> getGbuffersWeather();
|
||||
case Water -> getGbuffersWater();
|
||||
case HandWater -> getGbuffersHandWater();
|
||||
case Final -> getCompositeFinal();
|
||||
case DhTerrain -> getDhTerrain();
|
||||
case DhGeneric -> getDhGeneric();
|
||||
case DhWater -> getDhWater();
|
||||
case DhShadow -> getDhShadow();
|
||||
default -> Optional.empty();
|
||||
};
|
||||
}
|
||||
|
||||
public ProgramSource[] getDeferred() {
|
||||
|
||||
@@ -495,15 +495,15 @@ public class ShaderProperties {
|
||||
customUniforms.addVariable(parts[0], parts[1], value, false);
|
||||
});
|
||||
|
||||
handlePassDirective("uniform.", key, value, pass -> {
|
||||
String[] parts = pass.split("\\.");
|
||||
if (parts.length != 2) {
|
||||
Iris.logger.warn("Custom uniforms sould take the form of `uniform.<type>.<name> = <expression>. Ignoring " + key);
|
||||
return;
|
||||
}
|
||||
handlePassDirective("uniform.", key, value, pass -> {
|
||||
String[] parts = pass.split("\\.");
|
||||
if (parts.length != 2) {
|
||||
Iris.logger.warn("Custom uniforms sould take the form of `uniform.<type>.<name> = <expression>. Ignoring " + key);
|
||||
return;
|
||||
}
|
||||
|
||||
customUniforms.addVariable(parts[0], parts[1], value, true);
|
||||
});
|
||||
customUniforms.addVariable(parts[0], parts[1], value, true);
|
||||
});
|
||||
|
||||
// TODO: Buffer size directives
|
||||
// TODO: Conditional program enabling directives
|
||||
|
||||
@@ -7,7 +7,8 @@ public enum ProgramGroup {
|
||||
Gbuffers("gbuffers"),
|
||||
Deferred("deferred"),
|
||||
Composite("composite"),
|
||||
Final("final")
|
||||
Final("final"),
|
||||
Dh("dh")
|
||||
;
|
||||
|
||||
private final String baseName;
|
||||
|
||||
@@ -47,6 +47,10 @@ public enum ProgramId {
|
||||
Weather(ProgramGroup.Gbuffers, "weather", TexturedLit),
|
||||
Water(ProgramGroup.Gbuffers, "water", Terrain),
|
||||
HandWater(ProgramGroup.Gbuffers, "hand_water", Hand),
|
||||
DhTerrain(ProgramGroup.Dh, "terrain"),
|
||||
DhWater(ProgramGroup.Dh, "water", DhTerrain),
|
||||
DhGeneric(ProgramGroup.Dh, "generic", DhTerrain),
|
||||
DhShadow(ProgramGroup.Dh, "shadow"),
|
||||
|
||||
Final(ProgramGroup.Final, ""),
|
||||
;
|
||||
|
||||
@@ -11,16 +11,16 @@ public class ShadowMatrices {
|
||||
|
||||
// NB: These matrices are in column-major order, not row-major order like what you'd expect!
|
||||
|
||||
public static Matrix4f createOrthoMatrix(float halfPlaneLength) {
|
||||
public static Matrix4f createOrthoMatrix(float halfPlaneLength, float nearPlane, float farPlane) {
|
||||
return new Matrix4f(
|
||||
// column 1
|
||||
1.0f / halfPlaneLength, 0f, 0f, 0f,
|
||||
// column 2
|
||||
0f, 1.0f / halfPlaneLength, 0f, 0f,
|
||||
// column 3
|
||||
0f, 0f, 2.0f / (NEAR - FAR), 0f,
|
||||
0f, 0f, 2.0f / (nearPlane - farPlane), 0f,
|
||||
// column 4
|
||||
0f, 0f, -(FAR + NEAR) / (FAR - NEAR), 1f
|
||||
0f, 0f, -(farPlane + nearPlane) / (farPlane - nearPlane), 1f
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class ShadowMatrices {
|
||||
0f, 0f, -1.000390648841858f, 1f
|
||||
);
|
||||
|
||||
test("ortho projection hpl=32", expected, createOrthoMatrix(32.0f));
|
||||
test("ortho projection hpl=32", expected, createOrthoMatrix(32.0f, 0.05f, 256.0f));
|
||||
|
||||
// const float shadowDistance = 110.0;
|
||||
// /* SHADOWHPL:110.0 */
|
||||
@@ -115,7 +115,7 @@ public class ShadowMatrices {
|
||||
0, 0, -1.000390648841858f, 1
|
||||
);
|
||||
|
||||
test("ortho projection hpl=110", expected110, createOrthoMatrix(110.0f));
|
||||
test("ortho projection hpl=110", expected110, createOrthoMatrix(110.0f, 0.05f, 256.0f));
|
||||
|
||||
Matrix4f expected90Proj = new Matrix4f(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
|
||||
@@ -206,6 +206,20 @@ public class ShadowRenderTargets {
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
public GlFramebuffer createDHFramebuffer(ImmutableSet<Integer> stageWritesToAlt, int[] drawBuffers) {
|
||||
if (drawBuffers.length == 0) {
|
||||
return createEmptyFramebuffer();
|
||||
}
|
||||
|
||||
ImmutableSet<Integer> stageWritesToMain = invert(stageWritesToAlt, drawBuffers);
|
||||
|
||||
GlFramebuffer framebuffer = createColorFramebuffer(stageWritesToMain, drawBuffers);
|
||||
|
||||
framebuffer.addDepthAttachment(mainDepth.getTextureId());
|
||||
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
public GlFramebuffer createShadowFramebuffer(ImmutableSet<Integer> stageWritesToAlt, int[] drawBuffers) {
|
||||
if (drawBuffers.length == 0) {
|
||||
return createEmptyFramebuffer();
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package net.coderbot.iris.shadows.frustum;
|
||||
|
||||
import cpw.mods.fml.common.Optional;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
|
||||
import net.minecraft.client.renderer.culling.Frustrum;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import org.embeddedt.embeddium.impl.render.viewport.Viewport;
|
||||
@@ -7,7 +10,8 @@ import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
|
||||
import org.embeddedt.embeddium.impl.render.viewport.frustum.Frustum;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
public class CullEverythingFrustum extends Frustrum implements ViewportProvider, Frustum {
|
||||
@Optional.Interface(modid = "distanthorizons", iface = "com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum")
|
||||
public class CullEverythingFrustum extends Frustrum implements ViewportProvider, Frustum, IDhApiShadowCullingFrustum {
|
||||
private final Vector3d position = new Vector3d();
|
||||
|
||||
@Override
|
||||
@@ -24,4 +28,16 @@ public class CullEverythingFrustum extends Frustrum implements ViewportProvider,
|
||||
public Viewport sodium$createViewport() {
|
||||
return new Viewport(this, position.set(xPosition, yPosition, zPosition));
|
||||
}
|
||||
|
||||
@Optional.Method(modid = "distanthorizons")
|
||||
@Override
|
||||
public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection) {
|
||||
|
||||
}
|
||||
|
||||
@Optional.Method(modid = "distanthorizons")
|
||||
@Override
|
||||
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+22
-2
@@ -1,5 +1,8 @@
|
||||
package net.coderbot.iris.shadows.frustum.advanced;
|
||||
|
||||
import cpw.mods.fml.common.Optional;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
|
||||
import net.coderbot.iris.shadows.frustum.BoxCuller;
|
||||
import net.minecraft.client.renderer.culling.Frustrum;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
@@ -8,6 +11,7 @@ import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
|
||||
import org.embeddedt.embeddium.impl.render.viewport.frustum.Frustum;
|
||||
import org.joml.Math;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
@@ -32,7 +36,8 @@ import org.joml.Vector4f;
|
||||
* are not sensitive to the specific internal ordering of planes and corners, in order to avoid potential bugs at the
|
||||
* cost of slightly more computations.</p>
|
||||
*/
|
||||
public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportProvider, Frustum {
|
||||
@Optional.Interface(modid = "distanthorizons", iface = "com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum")
|
||||
public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportProvider, Frustum, IDhApiShadowCullingFrustum {
|
||||
private static final int MAX_CLIPPING_PLANES = 13;
|
||||
|
||||
/**
|
||||
@@ -79,6 +84,8 @@ public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportPr
|
||||
|
||||
private final BaseClippingPlanes baseClippingPlanes = new BaseClippingPlanes();
|
||||
private final boolean[] isBackArray = new boolean[6];
|
||||
private int worldMinYDH;
|
||||
private int worldMaxYDH;
|
||||
|
||||
public AdvancedShadowCullingFrustum() {
|
||||
for (int i = 0; i < MAX_CLIPPING_PLANES; i++) {
|
||||
@@ -86,7 +93,7 @@ public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportPr
|
||||
}
|
||||
}
|
||||
|
||||
public void init(Matrix4f playerView, Matrix4f playerProjection, Vector3f shadowLightVector, BoxCuller boxCuller) {
|
||||
public void init(Matrix4fc playerView, Matrix4fc playerProjection, Vector3f shadowLightVector, BoxCuller boxCuller) {
|
||||
this.shadowLightVectorFromOrigin.set(shadowLightVector);
|
||||
this.boxCuller = boxCuller;
|
||||
this.planeCount = 0;
|
||||
@@ -298,4 +305,17 @@ public class AdvancedShadowCullingFrustum extends Frustrum implements ViewportPr
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Optional.Method(modid = "distanthorizons")
|
||||
@Override
|
||||
public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection) {
|
||||
this.worldMinYDH = worldMinBlockY;
|
||||
this.worldMaxYDH = worldMaxBlockY;
|
||||
}
|
||||
|
||||
@Optional.Method(modid = "distanthorizons")
|
||||
@Override
|
||||
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) {
|
||||
return this.isVisible(lodBlockPosMinX, this.worldMinYDH, lodBlockPosMinZ, lodBlockPosMinX + lodBlockWidth, this.worldMaxYDH, lodBlockPosMinZ + lodBlockWidth);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.coderbot.iris.shadows.frustum.advanced;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
public class BaseClippingPlanes {
|
||||
@@ -13,7 +14,7 @@ public class BaseClippingPlanes {
|
||||
}
|
||||
}
|
||||
|
||||
public void init(Matrix4f view, Matrix4f projection) {
|
||||
public void init(Matrix4fc view, Matrix4fc projection) {
|
||||
// Transform = Transpose(Projection x View)
|
||||
transformScratch.set(projection);
|
||||
transformScratch.mul(view);
|
||||
|
||||
+2
-1
@@ -3,12 +3,13 @@ package net.coderbot.iris.shadows.frustum.advanced;
|
||||
import net.coderbot.iris.shadows.frustum.BoxCuller;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class SafeZoneCullingFrustum extends AdvancedShadowCullingFrustum {
|
||||
private final BoxCuller distanceCuller;
|
||||
|
||||
public SafeZoneCullingFrustum(Matrix4f playerView, Matrix4f playerProjection, Vector3f shadowLightVector, BoxCuller voxelCuller, BoxCuller distanceCuller) {
|
||||
public SafeZoneCullingFrustum(Matrix4fc playerView, Matrix4fc playerProjection, Vector3f shadowLightVector, BoxCuller voxelCuller, BoxCuller distanceCuller) {
|
||||
super();
|
||||
init(playerView, playerProjection, shadowLightVector, voxelCuller);
|
||||
this.distanceCuller = distanceCuller;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package net.coderbot.iris.shadows.frustum.fallback;
|
||||
|
||||
import cpw.mods.fml.common.Optional;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
|
||||
import net.coderbot.iris.shadows.frustum.BoxCuller;
|
||||
import net.minecraft.client.renderer.culling.Frustrum;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
@@ -8,9 +11,12 @@ import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
|
||||
import org.embeddedt.embeddium.impl.render.viewport.frustum.Frustum;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
public class BoxCullingFrustum extends Frustrum implements ViewportProvider, Frustum {
|
||||
@Optional.Interface(modid = "distanthorizons", iface = "com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum")
|
||||
public class BoxCullingFrustum extends Frustrum implements ViewportProvider, Frustum, IDhApiShadowCullingFrustum {
|
||||
private final BoxCuller boxCuller;
|
||||
private final Vector3d position = new Vector3d();
|
||||
private int worldMinYDH;
|
||||
private int worldMaxYDH;
|
||||
|
||||
public BoxCullingFrustum(BoxCuller boxCuller) {
|
||||
this.boxCuller = boxCuller;
|
||||
@@ -36,4 +42,17 @@ public class BoxCullingFrustum extends Frustrum implements ViewportProvider, Fru
|
||||
public Viewport sodium$createViewport() {
|
||||
return new Viewport(this, position.set(xPosition, yPosition, zPosition));
|
||||
}
|
||||
|
||||
@Optional.Method(modid = "distanthorizons")
|
||||
@Override
|
||||
public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection) {
|
||||
this.worldMinYDH = worldMinBlockY;
|
||||
this.worldMaxYDH = worldMaxBlockY;
|
||||
}
|
||||
|
||||
@Optional.Method(modid = "distanthorizons")
|
||||
@Override
|
||||
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) {
|
||||
return !boxCuller.isCulled(lodBlockPosMinX, this.worldMinYDH, lodBlockPosMinZ, lodBlockPosMinX + lodBlockWidth, this.worldMaxYDH, lodBlockPosMinZ + lodBlockWidth);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package net.coderbot.iris.shadows.frustum.fallback;
|
||||
|
||||
import cpw.mods.fml.common.Optional;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
|
||||
import net.minecraft.client.renderer.culling.Frustrum;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import org.embeddedt.embeddium.impl.render.viewport.Viewport;
|
||||
@@ -7,7 +10,8 @@ import org.embeddedt.embeddium.impl.render.viewport.ViewportProvider;
|
||||
import org.embeddedt.embeddium.impl.render.viewport.frustum.Frustum;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
public class NonCullingFrustum extends Frustrum implements ViewportProvider, Frustum {
|
||||
@Optional.Interface(modid = "distanthorizons", iface = "com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum")
|
||||
public class NonCullingFrustum extends Frustrum implements ViewportProvider, Frustum, IDhApiShadowCullingFrustum {
|
||||
private final Vector3d position = new Vector3d();
|
||||
|
||||
@Override
|
||||
@@ -24,4 +28,17 @@ public class NonCullingFrustum extends Frustrum implements ViewportProvider, Fru
|
||||
public Viewport sodium$createViewport() {
|
||||
return new Viewport(this, position.set(xPosition, yPosition, zPosition));
|
||||
}
|
||||
|
||||
@Optional.Method(modid = "distanthorizons")
|
||||
@Override
|
||||
public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection) {
|
||||
|
||||
}
|
||||
|
||||
@Optional.Method(modid = "distanthorizons")
|
||||
@Override
|
||||
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,8 +4,12 @@ import com.gtnewhorizons.angelica.rendering.RenderingState;
|
||||
import lombok.Getter;
|
||||
import net.coderbot.iris.gl.uniform.UniformHolder;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3dc;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3fc;
|
||||
import org.joml.Vector3i;
|
||||
import org.joml.Vector3ic;
|
||||
|
||||
import static net.coderbot.iris.gl.uniform.UniformUpdateFrequency.ONCE;
|
||||
import static net.coderbot.iris.gl.uniform.UniformUpdateFrequency.PER_FRAME;
|
||||
@@ -15,6 +19,8 @@ import static net.coderbot.iris.gl.uniform.UniformUpdateFrequency.PER_FRAME;
|
||||
*/
|
||||
public class CameraUniforms {
|
||||
private static final Minecraft client = Minecraft.getMinecraft();
|
||||
private static final Vector3f tempVec3f = new Vector3f();
|
||||
private static final Vector3i tempVec3i = new Vector3i();
|
||||
|
||||
private CameraUniforms() {
|
||||
}
|
||||
@@ -27,7 +33,27 @@ public class CameraUniforms {
|
||||
.uniform1f(PER_FRAME, "far", CameraUniforms::getRenderDistanceInBlocks)
|
||||
.uniform3d(PER_FRAME, "cameraPosition", tracker::getCurrentCameraPosition)
|
||||
.uniform1f(PER_FRAME, "eyeAltitude", tracker::getCurrentCameraPositionY)
|
||||
.uniform3d(PER_FRAME, "previousCameraPosition", tracker::getPreviousCameraPosition);
|
||||
.uniform3d(PER_FRAME, "previousCameraPosition", tracker::getPreviousCameraPosition)
|
||||
.uniform3i(PER_FRAME, "cameraPositionInt", () -> getCameraPositionInt(getUnshiftedCameraPosition()))
|
||||
.uniform3f(PER_FRAME, "cameraPositionFract", () -> getCameraPositionFract(getUnshiftedCameraPosition()))
|
||||
.uniform3i(PER_FRAME, "previousCameraPositionInt", () -> getCameraPositionInt(tracker.getPreviousCameraPositionUnshifted()))
|
||||
.uniform3f(PER_FRAME, "previousCameraPositionFract", () -> getCameraPositionFract(tracker.getPreviousCameraPositionUnshifted()));
|
||||
}
|
||||
|
||||
public static Vector3fc getCameraPositionFract(Vector3d originalPos) {
|
||||
return tempVec3f.set(
|
||||
(float) (originalPos.x - Math.floor(originalPos.x)),
|
||||
(float) (originalPos.y - Math.floor(originalPos.y)),
|
||||
(float) (originalPos.z - Math.floor(originalPos.z))
|
||||
);
|
||||
}
|
||||
|
||||
public static Vector3ic getCameraPositionInt(Vector3d originalPos) {
|
||||
return tempVec3i.set(
|
||||
(int) Math.floor(originalPos.x),
|
||||
(int) Math.floor(originalPos.y),
|
||||
(int) Math.floor(originalPos.z)
|
||||
);
|
||||
}
|
||||
|
||||
private static int getRenderDistanceInBlocks() {
|
||||
@@ -35,7 +61,7 @@ public class CameraUniforms {
|
||||
return client.gameSettings.renderDistanceChunks * 16;
|
||||
}
|
||||
|
||||
public static Vector3dc getUnshiftedCameraPosition() {
|
||||
public static Vector3d getUnshiftedCameraPosition() {
|
||||
return RenderingState.INSTANCE.getCameraPosition();
|
||||
}
|
||||
|
||||
@@ -50,10 +76,12 @@ public class CameraUniforms {
|
||||
private static final double TP_RANGE = 1000;
|
||||
|
||||
@Getter
|
||||
private Vector3d previousCameraPosition = new Vector3d();
|
||||
private Vector3d previousCameraPosition = new Vector3d();
|
||||
@Getter
|
||||
private Vector3d currentCameraPosition = new Vector3d();
|
||||
private Vector3d currentCameraPosition = new Vector3d();
|
||||
private final Vector3d shift = new Vector3d();
|
||||
private Vector3d previousCameraPositionUnshifted = new Vector3d();
|
||||
private Vector3d currentCameraPositionUnshifted = new Vector3d();
|
||||
|
||||
CameraPositionTracker(FrameUpdateNotifier notifier) {
|
||||
notifier.addListener(this::update);
|
||||
@@ -61,7 +89,9 @@ public class CameraUniforms {
|
||||
|
||||
private void update() {
|
||||
previousCameraPosition.set(currentCameraPosition);
|
||||
previousCameraPositionUnshifted = currentCameraPositionUnshifted;
|
||||
currentCameraPosition.set(getUnshiftedCameraPosition()).add(shift);
|
||||
currentCameraPositionUnshifted.set(getUnshiftedCameraPosition());
|
||||
|
||||
updateShift();
|
||||
}
|
||||
@@ -104,8 +134,12 @@ public class CameraUniforms {
|
||||
previousCameraPosition.z += dZ;
|
||||
}
|
||||
|
||||
public double getCurrentCameraPositionY() {
|
||||
public double getCurrentCameraPositionY() {
|
||||
return currentCameraPosition.y;
|
||||
}
|
||||
|
||||
public Vector3d getPreviousCameraPositionUnshifted() {
|
||||
return previousCameraPositionUnshifted;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.gtnewhorizons.angelica.glsm.texture.TextureInfo;
|
||||
import com.gtnewhorizons.angelica.glsm.texture.TextureInfoCache;
|
||||
import com.gtnewhorizons.angelica.client.rendering.TextureTracker;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.EntityRendererAccessor;
|
||||
import net.coderbot.iris.compat.dh.DHCompat;
|
||||
import net.coderbot.iris.gl.state.FogMode;
|
||||
import net.coderbot.iris.gl.state.ValueUpdateNotifier;
|
||||
import net.coderbot.iris.gl.uniform.DynamicUniformHolder;
|
||||
@@ -137,7 +138,10 @@ public final class CommonUniforms {
|
||||
.uniform1f(PER_TICK, "rainStrength", CommonUniforms::getRainStrength)
|
||||
.uniform1f(PER_TICK, "wetness", new SmoothedFloat(directives.getWetnessHalfLife(), directives.getDrynessHalfLife(), CommonUniforms::getRainStrength, updateNotifier))
|
||||
.uniform3d(PER_FRAME, "skyColor", CommonUniforms::getSkyColor)
|
||||
.uniform3d(PER_FRAME, "fogColor", GLStateManager::getFogColor);
|
||||
.uniform3d(PER_FRAME, "fogColor", GLStateManager::getFogColor)
|
||||
.uniform1f(PER_FRAME, "dhFarPlane", DHCompat::getFarPlane)
|
||||
.uniform1f(PER_FRAME, "dhNearPlane", DHCompat::getNearPlane)
|
||||
.uniform1i(PER_FRAME, "dhRenderDistance", DHCompat::getRenderDistance);
|
||||
}
|
||||
|
||||
private static boolean isOnGround() {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package net.coderbot.iris.uniforms;
|
||||
|
||||
import com.gtnewhorizons.angelica.rendering.RenderingState;
|
||||
import net.coderbot.iris.compat.dh.DHCompat;
|
||||
import net.coderbot.iris.gl.uniform.UniformHolder;
|
||||
import net.coderbot.iris.pipeline.ShadowRenderer;
|
||||
import net.coderbot.iris.shaderpack.PackDirectives;
|
||||
import net.coderbot.iris.shadow.ShadowMatrices;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -20,27 +22,37 @@ public final class MatrixUniforms {
|
||||
// TODO: In some cases, gbufferProjectionInverse takes on a value much different than OptiFine...
|
||||
// We need to audit Mojang's linear algebra.
|
||||
addMatrix(uniforms, "Projection", RenderingState.INSTANCE::getProjectionMatrix);
|
||||
addDHMatrix(uniforms, "Projection", DHCompat::getProjection);
|
||||
addShadowMatrix(uniforms, "ModelView", () -> ShadowRenderer.createShadowModelView(directives.getSunPathRotation(), directives.getShadowDirectives().getIntervalSize()).peek().getModel());
|
||||
addShadowMatrix(uniforms, "Projection", () -> ShadowMatrices.createOrthoMatrix(directives.getShadowDirectives().getDistance()));
|
||||
addShadowMatrix(uniforms, "Projection", () -> ShadowMatrices.createOrthoMatrix(directives.getShadowDirectives().getDistance(), directives.getShadowDirectives().getNearPlane() < 0 ? -DHCompat.getRenderDistance() : directives.getShadowDirectives().getNearPlane(),
|
||||
directives.getShadowDirectives().getFarPlane() < 0 ? DHCompat.getRenderDistance() : directives.getShadowDirectives().getFarPlane()));
|
||||
}
|
||||
|
||||
private static void addMatrix(UniformHolder uniforms, String name, Supplier<Matrix4f> supplier) {
|
||||
private static void addMatrix(UniformHolder uniforms, String name, Supplier<Matrix4fc> supplier) {
|
||||
uniforms
|
||||
.uniformMatrix(PER_FRAME, "gbuffer" + name, supplier)
|
||||
.uniformMatrix(PER_FRAME, "gbuffer" + name + "Inverse", new Inverted(supplier))
|
||||
.uniformMatrix(PER_FRAME, "gbufferPrevious" + name, new Previous(supplier));
|
||||
}
|
||||
|
||||
private static void addShadowMatrix(UniformHolder uniforms, String name, Supplier<Matrix4f> supplier) {
|
||||
private static void addDHMatrix(UniformHolder uniforms, String name, Supplier<Matrix4fc> supplier) {
|
||||
uniforms
|
||||
.uniformMatrix(PER_FRAME, "dh" + name, supplier)
|
||||
.uniformMatrix(PER_FRAME, "dh" + name + "Inverse", new Inverted(supplier))
|
||||
.uniformMatrix(PER_FRAME, "dhPrevious" + name, new Previous(supplier));
|
||||
}
|
||||
|
||||
|
||||
private static void addShadowMatrix(UniformHolder uniforms, String name, Supplier<Matrix4fc> supplier) {
|
||||
uniforms
|
||||
.uniformMatrix(PER_FRAME, "shadow" + name, supplier)
|
||||
.uniformMatrix(PER_FRAME, "shadow" + name + "Inverse", new Inverted(supplier));
|
||||
}
|
||||
|
||||
private static class Inverted implements Supplier<Matrix4f> {
|
||||
private final Supplier<Matrix4f> parent;
|
||||
private static class Inverted implements Supplier<Matrix4fc> {
|
||||
private final Supplier<Matrix4fc> parent;
|
||||
|
||||
Inverted(Supplier<Matrix4f> parent) {
|
||||
Inverted(Supplier<Matrix4fc> parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@@ -56,11 +68,11 @@ public final class MatrixUniforms {
|
||||
}
|
||||
|
||||
|
||||
private static class Previous implements Supplier<Matrix4f> {
|
||||
private final Supplier<Matrix4f> parent;
|
||||
private Matrix4f previous;
|
||||
private static class Previous implements Supplier<Matrix4fc> {
|
||||
private final Supplier<Matrix4fc> parent;
|
||||
private Matrix4fc previous;
|
||||
|
||||
Previous(Supplier<Matrix4f> parent) {
|
||||
Previous(Supplier<Matrix4fc> parent) {
|
||||
this.parent = parent;
|
||||
this.previous = new Matrix4f();
|
||||
}
|
||||
|
||||
+5
-4
@@ -25,7 +25,8 @@ import org.joml.Vector2f;
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3i;
|
||||
import org.joml.Vector3fc;
|
||||
import org.joml.Vector3ic;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -116,12 +117,12 @@ public class CustomUniformFixedInputUniformsHolder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3f> value) {
|
||||
public Builder uniform3f(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3fc> value) {
|
||||
return this.put(name, new Float3VectorCachedUniform(name, updateFrequency, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3i> value) {
|
||||
public Builder uniform3i(UniformUpdateFrequency updateFrequency, String name, Supplier<Vector3ic> value) {
|
||||
return this.put(name, new Int3VectorCachedUniform(name, updateFrequency, value));
|
||||
}
|
||||
|
||||
@@ -172,7 +173,7 @@ public class CustomUniformFixedInputUniformsHolder {
|
||||
|
||||
@Override
|
||||
public UniformHolder uniformMatrix(
|
||||
UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4f> value) {
|
||||
UniformUpdateFrequency updateFrequency, String name, Supplier<Matrix4fc> value) {
|
||||
return this.put(name, new Float4MatrixCachedUniform(name, updateFrequency, value));
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -4,23 +4,24 @@ import net.coderbot.iris.gl.uniform.UniformUpdateFrequency;
|
||||
import net.coderbot.iris.parsing.VectorType;
|
||||
import org.joml.Vector3f;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import org.joml.Vector3fc;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Float3VectorCachedUniform extends VectorCachedUniform<Vector3f> {
|
||||
public class Float3VectorCachedUniform extends VectorCachedUniform<Vector3fc> {
|
||||
|
||||
public Float3VectorCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Vector3f> supplier) {
|
||||
public Float3VectorCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Vector3fc> supplier) {
|
||||
super(name, updateFrequency, new Vector3f(), supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setFrom(Vector3f other) {
|
||||
this.cached.set(other);
|
||||
protected void setFrom(Vector3fc other) {
|
||||
((Vector3f)this.cached).set(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(int location) {
|
||||
GLStateManager.glUniform3f(location, this.cached.x, this.cached.y, this.cached.z);
|
||||
GLStateManager.glUniform3f(location, this.cached.x(), this.cached.y(), this.cached.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-3
@@ -4,21 +4,22 @@ import net.coderbot.iris.gl.uniform.UniformUpdateFrequency;
|
||||
import net.coderbot.iris.parsing.MatrixType;
|
||||
import org.joml.Matrix4f;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Float4MatrixCachedUniform extends VectorCachedUniform<Matrix4f> {
|
||||
public class Float4MatrixCachedUniform extends VectorCachedUniform<Matrix4fc> {
|
||||
final private FloatBuffer buffer = ByteBuffer.allocateDirect(16 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
||||
|
||||
public Float4MatrixCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Matrix4f> supplier) {
|
||||
public Float4MatrixCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Matrix4fc> supplier) {
|
||||
super(name, updateFrequency, new Matrix4f(), supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setFrom(Matrix4f other) {
|
||||
protected void setFrom(Matrix4fc other) {
|
||||
((Matrix4f) this.cached).set(other);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,23 +4,24 @@ import net.coderbot.iris.gl.uniform.UniformUpdateFrequency;
|
||||
import net.coderbot.iris.parsing.VectorType;
|
||||
import org.joml.Vector3i;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import org.joml.Vector3ic;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Int3VectorCachedUniform extends VectorCachedUniform<Vector3i> {
|
||||
public class Int3VectorCachedUniform extends VectorCachedUniform<Vector3ic> {
|
||||
|
||||
public Int3VectorCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Vector3i> supplier) {
|
||||
public Int3VectorCachedUniform(String name, UniformUpdateFrequency updateFrequency, Supplier<Vector3ic> supplier) {
|
||||
super(name, updateFrequency, new Vector3i(), supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setFrom(Vector3i other) {
|
||||
this.cached.set(other);
|
||||
protected void setFrom(Vector3ic other) {
|
||||
((Vector3i)this.cached).set(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(int location) {
|
||||
GLStateManager.glUniform3i(location, this.cached.x, this.cached.y, this.cached.z);
|
||||
GLStateManager.glUniform3i(location, this.cached.x(), this.cached.y(), this.cached.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
@@ -7,6 +7,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Share;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
import net.coderbot.iris.Iris;
|
||||
import net.coderbot.iris.compat.dh.DHCompat;
|
||||
import net.coderbot.iris.gl.program.Program;
|
||||
import net.coderbot.iris.pipeline.HandRenderer;
|
||||
import net.coderbot.iris.pipeline.WorldRenderingPhase;
|
||||
@@ -35,6 +36,9 @@ public abstract class MixinEntityRenderer implements IResourceManagerReloadListe
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/culling/ClippingHelperImpl;getInstance()Lnet/minecraft/client/renderer/culling/ClippingHelper;", shift = At.Shift.AFTER, ordinal = 0), method = "renderWorld(FJ)V")
|
||||
private void iris$beginRender(float partialTicks, long startTime, CallbackInfo ci, @Share("pipeline") LocalRef<WorldRenderingPipeline> pipeline) {
|
||||
DHCompat.checkFrame();
|
||||
Iris.tryLoadShaderpackWhenPossible();
|
||||
|
||||
CapturedRenderingState.INSTANCE.setTickDelta(partialTicks);
|
||||
SystemTimeUniforms.COUNTER.beginFrame();
|
||||
SystemTimeUniforms.TIMER.beginFrame(System.nanoTime());
|
||||
|
||||
Reference in new issue
Block a user