Fix height fog
This commit is contained in:
+13
-4
@@ -25,7 +25,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
* EXPONENTIAL_SQUARED <br>
|
||||
*
|
||||
* @author Leetom
|
||||
* @version 2022-6-30
|
||||
* @version 2024-11-09
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiFogFalloff
|
||||
@@ -35,8 +35,17 @@ public enum EDhApiFogFalloff
|
||||
// when removing items up the API major version
|
||||
|
||||
|
||||
LINEAR,
|
||||
EXPONENTIAL,
|
||||
EXPONENTIAL_SQUARED,
|
||||
LINEAR(0),
|
||||
EXPONENTIAL(1),
|
||||
EXPONENTIAL_SQUARED(2);
|
||||
|
||||
|
||||
/**
|
||||
* Stable version of {@link EDhApiFogFalloff#ordinal()}
|
||||
* @since API 4.0.0
|
||||
*/
|
||||
public final int value;
|
||||
|
||||
EDhApiFogFalloff(int value) { this.value = value; }
|
||||
|
||||
}
|
||||
|
||||
+12
-12
@@ -31,28 +31,28 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
* @version 2024-4-6
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiHeightFogMode
|
||||
public enum EDhApiHeightFogDirection
|
||||
{
|
||||
// Reminder:
|
||||
// when adding items up the API minor version
|
||||
// when removing items up the API major version
|
||||
|
||||
|
||||
ABOVE_CAMERA(true, true, false),
|
||||
BELOW_CAMERA(true, false, true),
|
||||
ABOVE_AND_BELOW_CAMERA(true, true, true),
|
||||
ABOVE_SET_HEIGHT(false, true, false),
|
||||
BELOW_SET_HEIGHT(false, false, true),
|
||||
ABOVE_AND_BELOW_SET_HEIGHT(false, true, true);
|
||||
ABOVE_CAMERA (true, true, false),
|
||||
BELOW_CAMERA (true, false, true),
|
||||
ABOVE_AND_BELOW_CAMERA (true, true, true),
|
||||
ABOVE_SET_HEIGHT (false, true, false),
|
||||
BELOW_SET_HEIGHT (false, false, true),
|
||||
ABOVE_AND_BELOW_SET_HEIGHT (false, true, true);
|
||||
|
||||
public final boolean basedOnCamera;
|
||||
public final boolean above;
|
||||
public final boolean below;
|
||||
public final boolean fogAppliesUp;
|
||||
public final boolean fogAppliesDown;
|
||||
|
||||
EDhApiHeightFogMode(boolean basedOnCamera, boolean above, boolean below)
|
||||
EDhApiHeightFogDirection(boolean basedOnCamera, boolean fogAppliesUp, boolean fogAppliesDown)
|
||||
{
|
||||
this.basedOnCamera = basedOnCamera;
|
||||
this.above = above;
|
||||
this.below = below;
|
||||
this.fogAppliesUp = fogAppliesUp;
|
||||
this.fogAppliesDown = fogAppliesDown;
|
||||
}
|
||||
}
|
||||
+36
-13
@@ -20,10 +20,11 @@
|
||||
package com.seibel.distanthorizons.api.enums.rendering;
|
||||
|
||||
/**
|
||||
* BASIC <br>
|
||||
* IGNORE_HEIGHT <br>
|
||||
* ADDITION <br>
|
||||
* SPHERICAL <br>
|
||||
* CYLINDRICAL <br>
|
||||
* <br>
|
||||
* MAX <br>
|
||||
* ADDITION <br>
|
||||
* MULTIPLY <br>
|
||||
* INVERSE_MULTIPLY <br>
|
||||
* LIMITED_ADDITION <br>
|
||||
@@ -37,14 +38,36 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
*/
|
||||
public enum EDhApiHeightFogMixMode
|
||||
{
|
||||
BASIC,
|
||||
IGNORE_HEIGHT,
|
||||
ADDITION,
|
||||
MAX,
|
||||
MULTIPLY,
|
||||
INVERSE_MULTIPLY,
|
||||
LIMITED_ADDITION,
|
||||
MULTIPLY_ADDITION,
|
||||
INVERSE_MULTIPLY_ADDITION,
|
||||
AVERAGE,
|
||||
/**
|
||||
* Basic just means the fog will be based on the fragment depth
|
||||
* not on any special height calculation IE spherical fog. <br><br>
|
||||
*
|
||||
* Not to be confused with {@link EDhApiHeightFogMixMode#CYLINDRICAL}
|
||||
* which causes fog to only apply based on horizontal distance.
|
||||
*/
|
||||
SPHERICAL(0),
|
||||
/**
|
||||
* Fog is applied based on horizontal distance from the camera,
|
||||
* IE cylindrical fog.
|
||||
*/
|
||||
CYLINDRICAL(1),
|
||||
|
||||
MAX(2),
|
||||
ADDITION(3),
|
||||
MULTIPLY(4),
|
||||
INVERSE_MULTIPLY(5),
|
||||
LIMITED_ADDITION(6),
|
||||
MULTIPLY_ADDITION(7),
|
||||
INVERSE_MULTIPLY_ADDITION(8),
|
||||
AVERAGE(9);
|
||||
|
||||
|
||||
/**
|
||||
* Stable version of {@link EDhApiFogFalloff#ordinal()}
|
||||
* @since API 4.0.0
|
||||
*/
|
||||
public final int value;
|
||||
|
||||
EDhApiHeightFogMixMode(int value) { this.value = value; }
|
||||
|
||||
}
|
||||
|
||||
+7
-4
@@ -21,7 +21,7 @@ package com.seibel.distanthorizons.api.interfaces.config.client;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogFalloff;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMode;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.IDhApiConfigGroup;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.IDhApiConfigValue;
|
||||
|
||||
@@ -42,11 +42,14 @@ public interface IDhApiHeightFogConfig extends IDhApiConfigGroup
|
||||
/** Defines how the height fog mixes. */
|
||||
IDhApiConfigValue<EDhApiHeightFogMixMode> heightFogMixMode();
|
||||
|
||||
/** Defines how the height fog is drawn relative to the camera or world. */
|
||||
IDhApiConfigValue<EDhApiHeightFogMode> heightFogMode();
|
||||
/**
|
||||
* Defines which direction height fog is drawn relative to the world.
|
||||
* @since API 4.0.0
|
||||
*/
|
||||
IDhApiConfigValue<EDhApiHeightFogDirection> heightFogDirection();
|
||||
|
||||
/**
|
||||
* Defines the height fog's base height if {@link IDhApiHeightFogConfig#heightFogMode()}
|
||||
* Defines the height fog's base height if {@link IDhApiHeightFogConfig#heightFogDirection()}
|
||||
* is set to use a specific height.
|
||||
*/
|
||||
IDhApiConfigValue<Double> heightFogBaseHeight();
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ package com.seibel.distanthorizons.core.api.external.methods.config.client;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogFalloff;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMode;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.IDhApiConfigValue;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.client.IDhApiHeightFogConfig;
|
||||
import com.seibel.distanthorizons.api.objects.config.DhApiConfigValue;
|
||||
@@ -40,8 +40,8 @@ public class DhApiHeightFogConfig implements IDhApiHeightFogConfig
|
||||
{ return new DhApiConfigValue<EDhApiHeightFogMixMode, EDhApiHeightFogMixMode>(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMixMode); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiHeightFogMode> heightFogMode()
|
||||
{ return new DhApiConfigValue<EDhApiHeightFogMode, EDhApiHeightFogMode>(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMode); }
|
||||
public IDhApiConfigValue<EDhApiHeightFogDirection> heightFogDirection()
|
||||
{ return new DhApiConfigValue<EDhApiHeightFogDirection, EDhApiHeightFogDirection>(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDirection); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> heightFogBaseHeight()
|
||||
|
||||
@@ -39,7 +39,6 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
@@ -549,40 +548,40 @@ public class Config
|
||||
public static class HeightFog
|
||||
{
|
||||
public static ConfigEntry<EDhApiHeightFogMixMode> heightFogMixMode = new ConfigEntry.Builder<EDhApiHeightFogMixMode>()
|
||||
.set(EDhApiHeightFogMixMode.BASIC)
|
||||
.set(EDhApiHeightFogMixMode.SPHERICAL)
|
||||
.comment(""
|
||||
+ "How should height effect the fog thickness? \n"
|
||||
+ "Note: height fog is combined with the other fog settings. \n"
|
||||
+ "\n"
|
||||
+ EDhApiHeightFogMixMode.BASIC + ": No special height fog effect. Fog is calculated based on camera distance \n"
|
||||
+ EDhApiHeightFogMixMode.IGNORE_HEIGHT + ": Ignore height completely. Fog is only calculated with horizontal distance \n"
|
||||
+ EDhApiHeightFogMixMode.ADDITION + ": heightFog + farFog \n"
|
||||
+ EDhApiHeightFogMixMode.SPHERICAL + ": Fog is calculated based on camera distance. \n"
|
||||
+ EDhApiHeightFogMixMode.CYLINDRICAL + ": Ignore height, fog is calculated based on horizontal distance. \n"
|
||||
+ "\n"
|
||||
+ EDhApiHeightFogMixMode.MAX + ": max(heightFog, farFog) \n"
|
||||
+ EDhApiHeightFogMixMode.ADDITION + ": heightFog + farFog \n"
|
||||
+ EDhApiHeightFogMixMode.MULTIPLY + ": heightFog * farFog \n"
|
||||
+ EDhApiHeightFogMixMode.INVERSE_MULTIPLY + ": 1 - (1-heightFog) * (1-farFog) \n"
|
||||
+ EDhApiHeightFogMixMode.LIMITED_ADDITION + ": farFog + max(farFog, heightFog) \n"
|
||||
+ EDhApiHeightFogMixMode.MULTIPLY_ADDITION + ": farFog + farFog * heightFog \n"
|
||||
+ EDhApiHeightFogMixMode.INVERSE_MULTIPLY_ADDITION + ": farFog + 1 - (1-heightFog) * (1-farFog) \n"
|
||||
+ EDhApiHeightFogMixMode.AVERAGE + ": farFog*0.5 + heightFog*0.5 \n"
|
||||
+ "\n"
|
||||
+ "Note: height fog settings are ignored if '" + EDhApiHeightFogMixMode.BASIC + "' or '" + EDhApiHeightFogMixMode.IGNORE_HEIGHT + "' are selected.")
|
||||
+ "\n")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiHeightFogMode> heightFogMode = new ConfigEntry.Builder<EDhApiHeightFogMode>()
|
||||
.set(EDhApiHeightFogMode.ABOVE_AND_BELOW_CAMERA)
|
||||
public static ConfigEntry<EDhApiHeightFogDirection> heightFogDirection = new ConfigEntry.Builder<EDhApiHeightFogDirection>()
|
||||
.set(EDhApiHeightFogDirection.BELOW_SET_HEIGHT)
|
||||
.comment(""
|
||||
+ "Where should the height fog start? \n"
|
||||
+ "\n"
|
||||
+ EDhApiHeightFogMode.ABOVE_CAMERA + ": Height fog starts at the camera and goes towards the sky \n"
|
||||
+ EDhApiHeightFogMode.BELOW_CAMERA + ": Height fog starts at the camera and goes towards the void \n"
|
||||
+ EDhApiHeightFogMode.ABOVE_AND_BELOW_CAMERA + ": Height fog starts from the camera to goes towards both the sky and void \n"
|
||||
+ EDhApiHeightFogMode.ABOVE_SET_HEIGHT + ": Height fog starts from a set height and goes towards the sky \n"
|
||||
+ EDhApiHeightFogMode.BELOW_SET_HEIGHT + ": Height fog starts from a set height and goes towards the void \n"
|
||||
+ EDhApiHeightFogMode.ABOVE_AND_BELOW_SET_HEIGHT + ": Height fog starts from a set height and goes towards both the sky and void")
|
||||
+ EDhApiHeightFogDirection.ABOVE_CAMERA + ": Height fog starts at the camera and goes towards the sky \n"
|
||||
+ EDhApiHeightFogDirection.BELOW_CAMERA + ": Height fog starts at the camera and goes towards the void \n"
|
||||
+ EDhApiHeightFogDirection.ABOVE_AND_BELOW_CAMERA + ": Height fog starts from the camera to goes towards both the sky and void \n"
|
||||
+ EDhApiHeightFogDirection.ABOVE_SET_HEIGHT + ": Height fog starts from a set height and goes towards the sky \n"
|
||||
+ EDhApiHeightFogDirection.BELOW_SET_HEIGHT + ": Height fog starts from a set height and goes towards the void \n"
|
||||
+ EDhApiHeightFogDirection.ABOVE_AND_BELOW_SET_HEIGHT + ": Height fog starts from a set height and goes towards both the sky and void")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Double> heightFogBaseHeight = new ConfigEntry.Builder<Double>()
|
||||
.setMinDefaultMax(-4096.0, 70.0, 4096.0)
|
||||
.setMinDefaultMax(-4096.0, 80.0, 4096.0)
|
||||
.comment("If the height fog is calculated around a set height, what is that height position?")
|
||||
.build();
|
||||
|
||||
@@ -596,7 +595,7 @@ public class Config
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Double> heightFogEnd = new ConfigEntry.Builder<Double>()
|
||||
.setMinDefaultMax(FOG_RANGE_MIN, 1.0, FOG_RANGE_MAX)
|
||||
.setMinDefaultMax(FOG_RANGE_MIN, 0.6, FOG_RANGE_MAX)
|
||||
.comment(""
|
||||
+ "Should the end of the height fog be offset? \n"
|
||||
+ "\n"
|
||||
@@ -605,7 +604,7 @@ public class Config
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Double> heightFogMin = new ConfigEntry.Builder<Double>()
|
||||
.setMinDefaultMax(-5.0, 0.0, FOG_RANGE_MAX)
|
||||
.setMinDefaultMax(0.0, 0.0, FOG_RANGE_MAX)
|
||||
.comment(""
|
||||
+ "What is the minimum fog thickness? \n"
|
||||
+ "\n"
|
||||
@@ -633,7 +632,7 @@ public class Config
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Double> heightFogDensity = new ConfigEntry.Builder<Double>()
|
||||
.setMinDefaultMax(0.01, 2.5, 50.0)
|
||||
.setMinDefaultMax(0.01, 20.0, 50.0)
|
||||
.comment("What is the height fog's density?")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -1,420 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.fog;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.*;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.Shader;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This holds fog related settings and
|
||||
* creates the fog related shader code.
|
||||
*
|
||||
* @author Leetom
|
||||
* @author James Seibel
|
||||
* @version 2022-11-24
|
||||
*/
|
||||
// TODO: Move lots out of here, there should be a listener hooked onto the config to update the shader
|
||||
public class LodFogConfig
|
||||
{
|
||||
private static final IOptifineAccessor OPTIFINE = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
||||
|
||||
public static final boolean DEBUG_DUMP_GENERATED_CODE = false;
|
||||
|
||||
public final FogSettings farFogSetting;
|
||||
public final FogSettings heightFogSetting;
|
||||
public final EDhApiHeightFogMixMode heightFogMixMode;
|
||||
public final EDhApiHeightFogMode heightFogMode;
|
||||
public final float heightFogHeight;
|
||||
|
||||
// TODO: Move these out of here
|
||||
public final int earthCurveRatio;
|
||||
|
||||
// Noise Values
|
||||
public final boolean noiseEnable;
|
||||
public final int noiseSteps;
|
||||
public final float noiseIntensity;
|
||||
public final int noiseDropoff;
|
||||
|
||||
|
||||
public static LodFogConfig generateFogConfig() { return new LodFogConfig(); }
|
||||
|
||||
/** sets all fog options from the config */
|
||||
private LodFogConfig()
|
||||
{
|
||||
// TODO: Move these out of here
|
||||
this.earthCurveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get();
|
||||
|
||||
this.noiseEnable = Config.Client.Advanced.Graphics.NoiseTexture.enableNoiseTexture.get();
|
||||
this.noiseSteps = Config.Client.Advanced.Graphics.NoiseTexture.noiseSteps.get();
|
||||
this.noiseIntensity = Config.Client.Advanced.Graphics.NoiseTexture.noiseIntensity.get().floatValue();
|
||||
this.noiseDropoff = Config.Client.Advanced.Graphics.NoiseTexture.noiseDropoff.get();
|
||||
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get())
|
||||
{
|
||||
// fog should be drawn
|
||||
|
||||
this.farFogSetting = new FogSettings(
|
||||
Config.Client.Advanced.Graphics.Fog.farFogStart.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.farFogEnd.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.farFogMin.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.farFogMax.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.farFogDensity.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.farFogFalloff.get()
|
||||
);
|
||||
|
||||
this.heightFogMixMode = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMixMode.get();
|
||||
if (this.heightFogMixMode == EDhApiHeightFogMixMode.IGNORE_HEIGHT
|
||||
|| this.heightFogMixMode == EDhApiHeightFogMixMode.BASIC)
|
||||
{
|
||||
// basic fog mixing
|
||||
|
||||
this.heightFogSetting = null;
|
||||
this.heightFogMode = null;
|
||||
this.heightFogHeight = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// advanced fog mixing
|
||||
|
||||
this.heightFogSetting = new FogSettings(
|
||||
Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDensity.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogEnd.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMin.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMax.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDensity.get(),
|
||||
Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogFalloff.get()
|
||||
);
|
||||
|
||||
this.heightFogMode = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMode.get();
|
||||
|
||||
if (this.heightFogMode.basedOnCamera)
|
||||
{
|
||||
this.heightFogHeight = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.heightFogHeight = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogBaseHeight.get().floatValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// fog disabled
|
||||
|
||||
this.farFogSetting = null;
|
||||
this.heightFogMixMode = null;
|
||||
this.heightFogMode = null;
|
||||
this.heightFogSetting = null;
|
||||
this.heightFogHeight = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
public StringBuilder loadAndProcessFragShader(String path, boolean absoluteFilePath)
|
||||
{
|
||||
StringBuilder stringBuilder = this.makeRuntimeDefine();
|
||||
this.generateRuntimeShaderCode(Shader.loadFile(path, absoluteFilePath, stringBuilder));
|
||||
|
||||
if (DEBUG_DUMP_GENERATED_CODE)
|
||||
{
|
||||
try (FileOutputStream file = new FileOutputStream("debugGenerated.frag", false))
|
||||
{
|
||||
file.write(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
|
||||
GLProxy.GL_LOGGER.info("Debug dumped generated code to debugGenerated.frag for {}", path);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
GLProxy.GL_LOGGER.warn("Failed to debug dump generated code to file for {}", path);
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuilder;
|
||||
}
|
||||
|
||||
/** Generates the necessary constants for a fragment shader */
|
||||
private void generateRuntimeShaderCode(StringBuilder str)
|
||||
{
|
||||
str.append("// =======RUNTIME GENERATED CODE SECTION======== //\n");
|
||||
|
||||
// Generate method: float getNearFogThickness(float dist);
|
||||
str.append("" +
|
||||
"float getNearFogThickness(float dist) \n" +
|
||||
"{ \n" +
|
||||
" return linearFog(dist, uNearFogStart, uNearFogLength, 0.0, 1.0); \n" +
|
||||
"} \n");
|
||||
|
||||
|
||||
if (this.farFogSetting == null)
|
||||
{
|
||||
str.append("\n" +
|
||||
"float getFarFogThickness(float dist) { return 0.0; } \n" +
|
||||
"float getHeightFogThickness(float dist) { return 0.0; } \n" +
|
||||
"float calculateFarFogDepth(float horizontal, float dist, float uNearFogStart) { return 0.0; } \n" +
|
||||
"float calculateHeightFogDepth(float vertical, float realY) { return 0.0; } \n" +
|
||||
"float mixFogThickness(float near, float far, float height) \n" +
|
||||
"{ \n" +
|
||||
" return 0.0; \n" +
|
||||
"} \n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generate method: float getFarFogThickness(float dist);
|
||||
str.append("" +
|
||||
"float getFarFogThickness(float dist) \n" +
|
||||
"{ \n" +
|
||||
getFarFogMethod(this.farFogSetting.fogType) + "\n" +
|
||||
"} \n");
|
||||
|
||||
|
||||
// Generate method: float getHeightFogThickness(float dist);
|
||||
str.append("" +
|
||||
"float getHeightFogThickness(float dist) \n" +
|
||||
"{ \n" +
|
||||
(this.heightFogSetting != null ? getHeightFogMethod(this.heightFogSetting.fogType) : " return 0.0;") + "\n" +
|
||||
"} \n");
|
||||
|
||||
|
||||
// Generate method: float calculateHeightFogDepth(float vertical, float realY);
|
||||
str.append("" +
|
||||
"float calculateHeightFogDepth(float vertical, float realY) \n" +
|
||||
"{ \n" +
|
||||
(this.heightFogSetting != null ? getHeightDepthMethod(this.heightFogMode, this.heightFogHeight) : " return 0.0;") + "\n" +
|
||||
"} \n");
|
||||
|
||||
|
||||
// Generate method: calculateFarFogDepth(float horizontal, float dist, float uNearFogStart);
|
||||
str.append("" +
|
||||
"float calculateFarFogDepth(float horizontal, float dist, float uNearFogStart) \n" +
|
||||
"{ \n" +
|
||||
" return " + (this.heightFogMixMode == EDhApiHeightFogMixMode.BASIC ?
|
||||
"(dist - uNearFogStart)/(1.0 - uNearFogStart);" :
|
||||
"(horizontal - uNearFogStart)/(1.0 - uNearFogStart);") +
|
||||
"} \n");
|
||||
|
||||
// Generate method: float mixFogThickness(float near, float far, float height);
|
||||
str.append("" +
|
||||
"float mixFogThickness(float near, float far, float height) \n" +
|
||||
"{ \n" +
|
||||
getMixFogLine(this.heightFogMixMode) + "\n" +
|
||||
"} \n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// shader creation //
|
||||
// helper methods //
|
||||
//=================//
|
||||
|
||||
private StringBuilder makeRuntimeDefine()
|
||||
{
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("// =======RUNTIME GENERATED DEFINE SECTION======== //\n");
|
||||
str.append("#version 150 core\n");
|
||||
|
||||
FogSettings activeFarFogSetting = this.farFogSetting != null ? this.farFogSetting : FogSettings.EMPTY;
|
||||
FogSettings activeHeightFogSetting = this.heightFogSetting != null ? this.heightFogSetting : FogSettings.EMPTY;
|
||||
|
||||
str.append("\n" +
|
||||
"#define farFogStart " + activeFarFogSetting.start + "\n" +
|
||||
"#define farFogLength " + (activeFarFogSetting.end - activeFarFogSetting.start) + "\n" +
|
||||
"#define farFogMin " + activeFarFogSetting.min + "\n" +
|
||||
"#define farFogRange " + (activeFarFogSetting.max - activeFarFogSetting.min) + "\n" +
|
||||
"#define farFogDensity " + activeFarFogSetting.density + "\n" +
|
||||
"\n" +
|
||||
"#define heightFogStart " + activeHeightFogSetting.start + "\n" +
|
||||
"#define heightFogLength " + (activeHeightFogSetting.end - activeHeightFogSetting.start) + "\n" +
|
||||
"#define heightFogMin " + activeHeightFogSetting.min + "\n" +
|
||||
"#define heightFogRange " + (activeHeightFogSetting.max - activeHeightFogSetting.min) + "\n" +
|
||||
"#define heightFogDensity " + activeHeightFogSetting.density + "\n" +
|
||||
"\n");
|
||||
|
||||
str.append("// =======RUNTIME END======== //\n");
|
||||
return str;
|
||||
}
|
||||
|
||||
private static String getFarFogMethod(EDhApiFogFalloff fogType)
|
||||
{
|
||||
switch (fogType)
|
||||
{
|
||||
case LINEAR:
|
||||
return "return linearFog(dist, farFogStart, farFogLength, farFogMin, farFogRange);\n";
|
||||
case EXPONENTIAL:
|
||||
return "return exponentialFog(dist, farFogStart, farFogLength, farFogMin, farFogRange, farFogDensity);\n";
|
||||
case EXPONENTIAL_SQUARED:
|
||||
return "return exponentialSquaredFog(dist, farFogStart, farFogLength, farFogMin, farFogRange, farFogDensity);\n";
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("FogType [" + fogType + "] not implemented for [getFarFogMethod].");
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHeightDepthMethod(EDhApiHeightFogMode heightMode, float heightFogHeight)
|
||||
{
|
||||
String str = "";
|
||||
if (!heightMode.basedOnCamera)
|
||||
{
|
||||
str = " vertical = realY - (" + heightFogHeight + ");\n";
|
||||
}
|
||||
|
||||
if (heightMode.below && heightMode.above)
|
||||
{
|
||||
str += " return abs(vertical);\n";
|
||||
}
|
||||
else if (heightMode.below)
|
||||
{
|
||||
str += " return -vertical;\n";
|
||||
}
|
||||
else if (heightMode.above)
|
||||
{
|
||||
str += " return vertical;\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
str += " return 0;\n";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the method call for the given fog type. <br>
|
||||
* Example: <br>
|
||||
* <code>" return linearFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange);"</code>
|
||||
*/
|
||||
private static String getHeightFogMethod(EDhApiFogFalloff fogType)
|
||||
{
|
||||
switch (fogType)
|
||||
{
|
||||
case LINEAR:
|
||||
return " return linearFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange);\n";
|
||||
case EXPONENTIAL:
|
||||
return " return exponentialFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange, heightFogDensity);\n";
|
||||
case EXPONENTIAL_SQUARED:
|
||||
return " return exponentialSquaredFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange, heightFogDensity);\n";
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("FogType [" + fogType + "] not implemented for [getHeightFogMethod].");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a line in the format <br>
|
||||
* <code>" return max(1.0-near, far);" </code>
|
||||
*/
|
||||
private static String getMixFogLine(EDhApiHeightFogMixMode heightFogMode)
|
||||
{
|
||||
String str = " return ";
|
||||
|
||||
switch (heightFogMode)
|
||||
{
|
||||
case BASIC:
|
||||
case IGNORE_HEIGHT:
|
||||
str += "near * far;\n";
|
||||
break;
|
||||
|
||||
case ADDITION:
|
||||
str += "near * (far + height);\n";
|
||||
break;
|
||||
|
||||
case MAX:
|
||||
str += "near * max(far, height);\n";
|
||||
break;
|
||||
|
||||
case INVERSE_MULTIPLY:
|
||||
str += "near * (1.0 - (1.0-far)*(1.0-height));\n";
|
||||
break;
|
||||
|
||||
case MULTIPLY:
|
||||
str += "near * far * height;\n";
|
||||
break;
|
||||
|
||||
case LIMITED_ADDITION:
|
||||
str += "near * (far + max(far, height));\n";
|
||||
break;
|
||||
|
||||
case MULTIPLY_ADDITION:
|
||||
str += "near * (far + far*height);\n";
|
||||
break;
|
||||
|
||||
case INVERSE_MULTIPLY_ADDITION:
|
||||
str += "near * (far + 1.0 - (1.0-far)*(1.0-height));\n";
|
||||
break;
|
||||
|
||||
case AVERAGE:
|
||||
str += "near * (far*0.5 + height*0.5);\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("FogType [" + heightFogMode + "] not implemented for [getMixFogMethod].");
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//========================//
|
||||
// default object methods //
|
||||
//========================//
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if (this == other)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (other == null || this.getClass() != other.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LodFogConfig that = (LodFogConfig) other;
|
||||
return Float.compare(that.heightFogHeight, this.heightFogHeight) == 0 &&
|
||||
Objects.equals(this.farFogSetting, that.farFogSetting) &&
|
||||
Objects.equals(this.heightFogSetting, that.heightFogSetting) && this.heightFogMixMode == that.heightFogMixMode &&
|
||||
this.heightFogMode == that.heightFogMode
|
||||
// TODO: Move these out of here
|
||||
&& this.earthCurveRatio == that.earthCurveRatio
|
||||
&& this.noiseEnable == that.noiseEnable && this.noiseSteps == that.noiseSteps && this.noiseIntensity == that.noiseIntensity && this.noiseDropoff == that.noiseDropoff;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hash(this.farFogSetting, this.heightFogSetting, this.heightFogMixMode, this.heightFogMode, this.heightFogHeight, this.earthCurveRatio, this.noiseEnable, this.noiseSteps, this.noiseIntensity, this.noiseDropoff);
|
||||
}
|
||||
|
||||
}
|
||||
+58
-61
@@ -49,6 +49,8 @@ public class ShaderProgram
|
||||
/** Stores the handle of the program. */
|
||||
public final int id;
|
||||
|
||||
|
||||
|
||||
// TODO: A better way to set the fragData output name
|
||||
/**
|
||||
* Creates a shader program.
|
||||
@@ -73,20 +75,20 @@ public class ShaderProgram
|
||||
}
|
||||
|
||||
|
||||
public ShaderProgram(List<Supplier<String>> vert, List<Supplier<String>> frag, String[] attributes)
|
||||
public ShaderProgram(List<Supplier<String>> vertSupplierList, List<Supplier<String>> fragSupplierList, String[] attributes)
|
||||
{
|
||||
id = GL32.glCreateProgram();
|
||||
this.id = GL32.glCreateProgram();
|
||||
|
||||
for (Supplier<String> v : vert)
|
||||
for (Supplier<String> vertSupplier : vertSupplierList)
|
||||
{
|
||||
Shader vertShader = new Shader(GL32.GL_VERTEX_SHADER, v.get());
|
||||
Shader vertShader = new Shader(GL32.GL_VERTEX_SHADER, vertSupplier.get());
|
||||
GL32.glAttachShader(this.id, vertShader.id);
|
||||
vertShader.free(); // important!
|
||||
}
|
||||
|
||||
for (Supplier<String> f : frag)
|
||||
for (Supplier<String> fragSupplier : fragSupplierList)
|
||||
{
|
||||
Shader fragShader = new Shader(GL32.GL_FRAGMENT_SHADER, f.get());
|
||||
Shader fragShader = new Shader(GL32.GL_FRAGMENT_SHADER, fragSupplier.get());
|
||||
GL32.glAttachShader(this.id, fragShader.id);
|
||||
fragShader.free(); // important!
|
||||
}
|
||||
@@ -101,28 +103,22 @@ public class ShaderProgram
|
||||
if (status != GL32.GL_TRUE)
|
||||
{
|
||||
String message = "Shader Link Error. Details: " + GL32.glGetProgramInfoLog(this.id);
|
||||
free(); // important!
|
||||
this.free(); // important!
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
GL32.glUseProgram(id); // This HAVE to be a direct call to prevent calling the overloaded version
|
||||
GL32.glUseProgram(this.id); // This HAVE to be a direct call to prevent calling the overloaded version
|
||||
}
|
||||
|
||||
/** This will bind ShaderProgram */
|
||||
public void bind()
|
||||
{
|
||||
GL32.glUseProgram(id);
|
||||
}
|
||||
/** This will unbind ShaderProgram */
|
||||
public void unbind()
|
||||
{
|
||||
GL32.glUseProgram(0);
|
||||
}
|
||||
|
||||
// REMEMBER to always free the resource!
|
||||
public void free()
|
||||
{
|
||||
GL32.glDeleteProgram(id);
|
||||
}
|
||||
|
||||
|
||||
public void bind() { GL32.glUseProgram(this.id); }
|
||||
public void unbind() { GL32.glUseProgram(0); }
|
||||
|
||||
public void free() { GL32.glDeleteProgram(this.id); }
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* WARNING: Slow native call! Cache it if possible!
|
||||
@@ -139,12 +135,12 @@ public class ShaderProgram
|
||||
if (i == -1) throw new RuntimeException("Attribute name not found: " + name);
|
||||
return i;
|
||||
}
|
||||
// Same as above but without throwing errors.
|
||||
// Return -1 if attribute doesn't exist or has been optimized out
|
||||
/**
|
||||
* Same as above but without throwing errors. <br>
|
||||
* Returns -1 if the attribute doesn't exist or has been optimized out.
|
||||
*/
|
||||
public int tryGetAttributeLocation(CharSequence name)
|
||||
{
|
||||
return GL32.glGetAttribLocation(id, name);
|
||||
}
|
||||
{ return GL32.glGetAttribLocation(this.id, name); }
|
||||
|
||||
/**
|
||||
* WARNING: Slow native call! Cache it if possible!
|
||||
@@ -168,41 +164,34 @@ public class ShaderProgram
|
||||
// Same as above but without throwing errors.
|
||||
// Return -1 if uniform doesn't exist or has been optimized out
|
||||
public int tryGetUniformLocation(CharSequence name)
|
||||
{
|
||||
return GL32.glGetUniformLocation(id, name);
|
||||
}
|
||||
{ return GL32.glGetUniformLocation(this.id, name); }
|
||||
|
||||
/** Requires ShaderProgram binded. */
|
||||
public void setUniform(int location, boolean value)
|
||||
{
|
||||
// This use -1 for false as that equals all one set
|
||||
GL32.glUniform1i(location, value ? 1 : 0);
|
||||
}
|
||||
/** Requires a bound ShaderProgram. */
|
||||
public void setUniform(int location, boolean value) { GL32.glUniform1i(location, value ? 1 : 0); }
|
||||
/** @see ShaderProgram#setUniform(int, boolean) */
|
||||
public void trySetUniform(int location, boolean value) { if (location != -1) { this.setUniform(location, value); } }
|
||||
|
||||
/** Requires ShaderProgram binded. */
|
||||
public void setUniform(int location, int value)
|
||||
{
|
||||
GL32.glUniform1i(location, value);
|
||||
}
|
||||
/** Requires a bound ShaderProgram. */
|
||||
public void setUniform(int location, int value) { GL32.glUniform1i(location, value); }
|
||||
/** @see ShaderProgram#setUniform(int, int) */
|
||||
public void trySetUniform(int location, int value) { if (location != -1) { this.setUniform(location, value); } }
|
||||
|
||||
/** Requires ShaderProgram binded. */
|
||||
public void setUniform(int location, float value)
|
||||
{
|
||||
GL32.glUniform1f(location, value);
|
||||
}
|
||||
/** Requires a bound ShaderProgram. */
|
||||
public void setUniform(int location, float value) { GL32.glUniform1f(location, value); }
|
||||
/** @see ShaderProgram#setUniform(int, float) */
|
||||
public void trySetUniform(int location, float value) { if (location != -1) { this.setUniform(location, value); } }
|
||||
|
||||
/** Requires ShaderProgram binded. */
|
||||
public void setUniform(int location, Vec3f value)
|
||||
{
|
||||
GL32.glUniform3f(location, value.x, value.y, value.z);
|
||||
}
|
||||
/** Requires ShaderProgram binded. */
|
||||
public void setUniform(int location, DhApiVec3i value)
|
||||
{
|
||||
GL32.glUniform3i(location, value.x, value.y, value.z);
|
||||
}
|
||||
/** Requires a bound ShaderProgram. */
|
||||
public void setUniform(int location, Vec3f value) { GL32.glUniform3f(location, value.x, value.y, value.z); }
|
||||
/** @see ShaderProgram#setUniform(int, Vec3f) */
|
||||
public void trySetUniform(int location, Vec3f value) { if (location != -1) { this.setUniform(location, value); } }
|
||||
|
||||
/** Requires ShaderProgram binded. */
|
||||
/** Requires a bound ShaderProgram. */
|
||||
public void setUniform(int location, DhApiVec3i value) { GL32.glUniform3i(location, value.x, value.y, value.z); }
|
||||
/** @see ShaderProgram#setUniform(int, Mat4f) */
|
||||
public void trySetUniform(int location, DhApiVec3i value) { if (location != -1) { this.setUniform(location, value); } }
|
||||
|
||||
/** Requires a bound ShaderProgram. */
|
||||
public void setUniform(int location, Mat4f value)
|
||||
{
|
||||
try (MemoryStack stack = MemoryStack.stackPush())
|
||||
@@ -212,14 +201,22 @@ public class ShaderProgram
|
||||
GL32.glUniformMatrix4fv(location, false, buffer);
|
||||
}
|
||||
}
|
||||
/** @see ShaderProgram#setUniform(int, Mat4f) */
|
||||
public void trySetUniform(int location, Mat4f value) { if (location != -1) { this.setUniform(location, value); } }
|
||||
|
||||
/**
|
||||
* Converts the color's RGBA values into values between 0 and 1.
|
||||
* Requires ShaderProgram binded.
|
||||
* Converts the color's RGBA values into values between 0 and 1. <br>
|
||||
* Requires a bound ShaderProgram.
|
||||
*/
|
||||
public void setUniform(int location, Color value)
|
||||
{
|
||||
GL32.glUniform4f(location, value.getRed() / 256.0f, value.getGreen() / 256.0f, value.getBlue() / 256.0f, value.getAlpha() / 256.0f);
|
||||
GL32.glUniform4f(location,
|
||||
value.getRed() / 256.0f,
|
||||
value.getGreen() / 256.0f,
|
||||
value.getBlue() / 256.0f,
|
||||
value.getAlpha() / 256.0f);
|
||||
}
|
||||
/** @see ShaderProgram#setUniform(int, Color) */
|
||||
public void trySetUniform(int location, Color value) { if (location != -1) { this.setUniform(location, value); } }
|
||||
|
||||
}
|
||||
|
||||
+1
-19
@@ -44,7 +44,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRen
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogColorMode;
|
||||
import com.seibel.distanthorizons.core.render.fog.LodFogConfig;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
@@ -104,8 +103,7 @@ public class LodRenderer
|
||||
|
||||
|
||||
// The shader program
|
||||
IDhApiShaderProgram lodRenderProgram = null;
|
||||
LodFogConfig fogConfig;
|
||||
private IDhApiShaderProgram lodRenderProgram = null;
|
||||
public QuadElementBuffer quadIBO = null;
|
||||
public boolean isSetupComplete = false;
|
||||
|
||||
@@ -634,22 +632,6 @@ public class LodRenderer
|
||||
}
|
||||
else
|
||||
{
|
||||
LodFogConfig newFogConfig = LodFogConfig.generateFogConfig(); // TODO use a config listener instead
|
||||
if (this.fogConfig == null)
|
||||
{
|
||||
this.fogConfig = newFogConfig;
|
||||
}
|
||||
|
||||
if (!this.fogConfig.equals(newFogConfig))
|
||||
{
|
||||
this.fogConfig = newFogConfig;
|
||||
|
||||
this.lodRenderProgram.free();
|
||||
this.lodRenderProgram = new DhTerrainShaderProgram();
|
||||
|
||||
FogShader.INSTANCE.free();
|
||||
FogShader.INSTANCE = new FogShader(newFogConfig);
|
||||
}
|
||||
this.lodRenderProgram.bind();
|
||||
}
|
||||
|
||||
|
||||
+118
-31
@@ -20,11 +20,11 @@
|
||||
package com.seibel.distanthorizons.core.render.renderer.shaders;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogColorMode;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.fog.LodFogConfig;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.Shader;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.ScreenQuad;
|
||||
@@ -38,7 +38,7 @@ import java.awt.*;
|
||||
|
||||
public class FogShader extends AbstractShaderRenderer
|
||||
{
|
||||
public static FogShader INSTANCE = new FogShader(LodFogConfig.generateFogConfig());
|
||||
public static final FogShader INSTANCE = new FogShader();
|
||||
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final IVersionConstants VERSION_CONSTANTS = SingletonInjector.INSTANCE.get(IVersionConstants.class);
|
||||
@@ -46,21 +46,46 @@ public class FogShader extends AbstractShaderRenderer
|
||||
|
||||
public int frameBuffer;
|
||||
|
||||
private final LodFogConfig fogConfig;
|
||||
private Mat4f inverseMvmProjMatrix;
|
||||
|
||||
|
||||
// Uniforms
|
||||
//==========//
|
||||
// Uniforms //
|
||||
//==========//
|
||||
|
||||
public int uDepthMap;
|
||||
/** Inverted Model View Projection matrix */
|
||||
public int uInvMvmProj;
|
||||
|
||||
// fog uniforms
|
||||
public int uFogColor;
|
||||
public int uFogScale;
|
||||
public int uFogVerticalScale;
|
||||
public int uNearFogStart;
|
||||
public int uNearFogLength;
|
||||
public int uFullFogMode;
|
||||
|
||||
/** Inverted Model View Projection matrix */
|
||||
public int uInvMvmProj;
|
||||
public int uDepthMap;
|
||||
// far fog
|
||||
public int uFarFogStart;
|
||||
public int uFarFogLength;
|
||||
public int uFarFogMin;
|
||||
public int uFarFogRange;
|
||||
public int uFarFogDensity;
|
||||
|
||||
// height fog
|
||||
public int uHeightFogStart;
|
||||
public int uHeightFogLength;
|
||||
public int uHeightFogMin;
|
||||
public int uHeightFogRange;
|
||||
public int uHeightFogDensity;
|
||||
|
||||
public int uHeightFogEnabled;
|
||||
public int uHeightFogFalloffType;
|
||||
public int uHeightBasedOnCamera;
|
||||
public int uHeightFogBaseHeight;
|
||||
public int uHeightFogAppliesUp;
|
||||
public int uHeightFogAppliesDown;
|
||||
public int uUseSphericalFog;
|
||||
public int uHeightFogMixingMode;
|
||||
public int uCameraBlockYPos;
|
||||
|
||||
|
||||
|
||||
@@ -68,15 +93,13 @@ public class FogShader extends AbstractShaderRenderer
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public FogShader(LodFogConfig fogConfig) { this.fogConfig = fogConfig; }
|
||||
|
||||
public FogShader() { }
|
||||
|
||||
@Override
|
||||
public void onInit()
|
||||
{
|
||||
this.shader = new ShaderProgram(
|
||||
// TODO rename normal.vert to something like "postProcess.vert"
|
||||
() -> Shader.loadFile("shaders/normal.vert", false, new StringBuilder()).toString(),
|
||||
() -> this.fogConfig.loadAndProcessFragShader("shaders/fog/fog.frag", false).toString(),
|
||||
"shaders/normal.vert", "shaders/fog/fog.frag",
|
||||
"fragColor", new String[]{"vPosition"}
|
||||
);
|
||||
|
||||
@@ -87,15 +110,35 @@ public class FogShader extends AbstractShaderRenderer
|
||||
this.uInvMvmProj = this.shader.getUniformLocation("uInvMvmProj");
|
||||
|
||||
// Fog uniforms
|
||||
this.uFogScale = this.shader.tryGetUniformLocation("uFogScale");
|
||||
this.uFogVerticalScale = this.shader.tryGetUniformLocation("uFogVerticalScale");
|
||||
this.uFogColor = this.shader.tryGetUniformLocation("uFogColor");
|
||||
this.uFullFogMode = this.shader.tryGetUniformLocation("uFullFogMode");
|
||||
this.uFogScale = this.shader.getUniformLocation("uFogScale");
|
||||
this.uFogVerticalScale = this.shader.getUniformLocation("uFogVerticalScale");
|
||||
this.uFogColor = this.shader.getUniformLocation("uFogColor");
|
||||
this.uFullFogMode = this.shader.getUniformLocation("uFullFogMode");
|
||||
|
||||
// near fog
|
||||
this.uNearFogStart = this.shader.tryGetUniformLocation("uNearFogStart");
|
||||
this.uNearFogLength = this.shader.tryGetUniformLocation("uNearFogLength");
|
||||
// fog config
|
||||
this.uFarFogStart = this.shader.getUniformLocation("uFarFogStart");
|
||||
this.uFarFogLength = this.shader.getUniformLocation("uFarFogLength");
|
||||
this.uFarFogMin = this.shader.getUniformLocation("uFarFogMin");
|
||||
this.uFarFogRange = this.shader.getUniformLocation("uFarFogRange");
|
||||
this.uFarFogDensity = this.shader.getUniformLocation("uFarFogDensity");
|
||||
|
||||
// height fog
|
||||
this.uHeightFogStart = this.shader.getUniformLocation("uHeightFogStart");
|
||||
this.uHeightFogLength = this.shader.getUniformLocation("uHeightFogLength");
|
||||
this.uHeightFogMin = this.shader.getUniformLocation("uHeightFogMin");
|
||||
this.uHeightFogRange = this.shader.getUniformLocation("uHeightFogRange");
|
||||
this.uHeightFogDensity = this.shader.getUniformLocation("uHeightFogDensity");
|
||||
|
||||
this.uHeightFogEnabled = this.shader.getUniformLocation("uHeightFogEnabled");
|
||||
this.uHeightFogFalloffType = this.shader.getUniformLocation("uHeightFogFalloffType");
|
||||
this.uHeightBasedOnCamera = this.shader.getUniformLocation("uHeightBasedOnCamera");
|
||||
this.uHeightFogBaseHeight = this.shader.getUniformLocation("uHeightFogBaseHeight");
|
||||
this.uHeightFogAppliesUp = this.shader.getUniformLocation("uHeightFogAppliesUp");
|
||||
this.uHeightFogAppliesDown = this.shader.getUniformLocation("uHeightFogAppliesDown");
|
||||
this.uUseSphericalFog = this.shader.getUniformLocation("uUseSphericalFog");
|
||||
this.uHeightFogMixingMode = this.shader.getUniformLocation("uHeightFogMixingMode");
|
||||
this.uCameraBlockYPos = this.shader.getUniformLocation("uCameraBlockYPos");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -107,22 +150,66 @@ public class FogShader extends AbstractShaderRenderer
|
||||
@Override
|
||||
protected void onApplyUniforms(float partialTicks)
|
||||
{
|
||||
int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH;
|
||||
|
||||
|
||||
|
||||
if (this.inverseMvmProjMatrix != null)
|
||||
{
|
||||
this.shader.setUniform(this.uInvMvmProj, this.inverseMvmProjMatrix);
|
||||
}
|
||||
|
||||
int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH;
|
||||
|
||||
// Fog
|
||||
if (this.uFullFogMode != -1) this.shader.setUniform(this.uFullFogMode, MC_RENDER.isFogStateSpecial() ? 1 : 0);
|
||||
if (this.uFogColor != -1) this.shader.setUniform(this.uFogColor, MC_RENDER.isFogStateSpecial() ? this.getSpecialFogColor(partialTicks) : this.getFogColor(partialTicks));
|
||||
// Fog uniforms
|
||||
this.shader.setUniform(this.uFogColor, MC_RENDER.isFogStateSpecial() ? this.getSpecialFogColor(partialTicks) : this.getFogColor(partialTicks));
|
||||
this.shader.setUniform(this.uFogScale, 1.f / lodDrawDistance);
|
||||
this.shader.setUniform(this.uFogVerticalScale, 1.f / MC.getWrappedClientLevel().getMaxHeight());
|
||||
this.shader.setUniform(this.uFullFogMode, MC_RENDER.isFogStateSpecial() ? 1 : 0);
|
||||
|
||||
|
||||
// fog config
|
||||
float farFogStart = Config.Client.Advanced.Graphics.Fog.farFogStart.get().floatValue();
|
||||
float farFogEnd = Config.Client.Advanced.Graphics.Fog.farFogEnd.get().floatValue();
|
||||
float farFogMin = Config.Client.Advanced.Graphics.Fog.farFogMin.get().floatValue();
|
||||
float farFogMax = Config.Client.Advanced.Graphics.Fog.farFogMax.get().floatValue();
|
||||
float farFogDensity = Config.Client.Advanced.Graphics.Fog.farFogDensity.get().floatValue();
|
||||
|
||||
this.shader.setUniform(this.uFarFogStart, farFogStart);
|
||||
this.shader.setUniform(this.uFarFogLength, farFogEnd - farFogStart);
|
||||
this.shader.setUniform(this.uFarFogMin, farFogMin);
|
||||
this.shader.setUniform(this.uFarFogRange, farFogMax - farFogMin);
|
||||
this.shader.setUniform(this.uFarFogDensity, farFogDensity);
|
||||
|
||||
|
||||
// height config
|
||||
EDhApiHeightFogMixMode heightFogMixingMode = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMixMode.get();
|
||||
boolean heightFogEnabled = heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL && heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL;
|
||||
boolean useSphericalFog = heightFogMixingMode == EDhApiHeightFogMixMode.SPHERICAL;
|
||||
EDhApiHeightFogDirection heightFogCameraDirection = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDirection.get();
|
||||
|
||||
float heightFogStart = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogStart.get().floatValue();
|
||||
float heightFogEnd = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogEnd.get().floatValue();
|
||||
float heightFogMin = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMin.get().floatValue();
|
||||
float heightFogMax = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMax.get().floatValue();
|
||||
float heightFogDensity = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDensity.get().floatValue();
|
||||
|
||||
this.shader.setUniform(this.uHeightFogStart, heightFogStart);
|
||||
this.shader.setUniform(this.uHeightFogLength, heightFogEnd - heightFogStart);
|
||||
this.shader.setUniform(this.uHeightFogMin, heightFogMin);
|
||||
this.shader.setUniform(this.uHeightFogRange, heightFogMax - heightFogMin);
|
||||
this.shader.setUniform(this.uHeightFogDensity, heightFogDensity);
|
||||
|
||||
|
||||
this.shader.setUniform(this.uHeightFogEnabled, heightFogEnabled);
|
||||
this.shader.setUniform(this.uHeightFogFalloffType, Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogFalloff.get().value);
|
||||
this.shader.setUniform(this.uHeightFogBaseHeight, Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogBaseHeight.get().floatValue());
|
||||
this.shader.setUniform(this.uHeightBasedOnCamera, heightFogCameraDirection.basedOnCamera);
|
||||
this.shader.setUniform(this.uHeightFogAppliesUp, heightFogCameraDirection.fogAppliesUp);
|
||||
this.shader.setUniform(this.uHeightFogAppliesDown, heightFogCameraDirection.fogAppliesDown);
|
||||
this.shader.setUniform(this.uUseSphericalFog, useSphericalFog);
|
||||
this.shader.setUniform(this.uHeightFogMixingMode, heightFogMixingMode.value);
|
||||
this.shader.setUniform(this.uCameraBlockYPos, (float)MC_RENDER.getCameraExactPosition().y);
|
||||
|
||||
float nearFogStart = (VERSION_CONSTANTS.isVanillaRenderedChunkSquare() ? (float) Math.sqrt(2.0) : 1.0f) / lodDrawDistance;
|
||||
if (this.uNearFogStart != -1) this.shader.setUniform(this.uNearFogStart, nearFogStart);
|
||||
if (this.uNearFogLength != -1) this.shader.setUniform(this.uNearFogLength, 0.0f);
|
||||
if (this.uFogScale != -1) this.shader.setUniform(this.uFogScale, 1.f / lodDrawDistance);
|
||||
if (this.uFogVerticalScale != -1) this.shader.setUniform(this.uFogVerticalScale, 1.f / MC.getWrappedClientLevel().getMaxHeight());
|
||||
}
|
||||
private Color getFogColor(float partialTicks)
|
||||
{
|
||||
|
||||
@@ -269,10 +269,10 @@
|
||||
"distanthorizons.config.client.advanced.graphics.fog.heightFog.heightFogMixMode":
|
||||
"Height Fog Mix Mode",
|
||||
"distanthorizons.config.client.advanced.graphics.fog.heightFog.heightFogMixMode.@tooltip":
|
||||
"How the height should effect the fog thickness combined with the normal function? \n\nBASIC: No special height fog effect. Fog is calculated based on camera distance \nIGNORE_HEIGHT: Ignore height completely. Fog is calculated based on horizontal distance \nADDITION: heightFog + farFog \nMAX: max(heightFog, farFog) \nMULTIPLY: heightFog * farFog \nINVERSE_MULTIPLY: 1 - (1-heightFog) * (1-farFog) \nLIMITED_ADDITION: farFog + max(farFog, heightFog) \nMULTIPLY_ADDITION: farFog + farFog * heightFog \nINVERSE_MULTIPLY_ADDITION: farFog + 1 - (1-heightFog) * (1-farFog) \nAVERAGE: farFog*0.5 + heightFog*0.5 \n\nNote that for 'BASIC' mode and 'IGNORE_HEIGHT' mode, fog settings for height fog has no effect.\n",
|
||||
"distanthorizons.config.client.advanced.graphics.fog.heightFog.heightFogMode":
|
||||
"Height Fog Mode",
|
||||
"distanthorizons.config.client.advanced.graphics.fog.heightFog.heightFogMode.@tooltip":
|
||||
"Defines how height effects fog. \nWhen in doubt start with SPHERICAL, ADDITION, or MAX. \n\nSPHERICAL: Fog is calculated based on camera distance. \nCYLINDRICAL: Ignore height, fog is calculated based on horizontal distance. \nMAX: max(heightFog, farFog) \nADDITION: heightFog + farFog \nMULTIPLY: heightFog * farFog \nINVERSE_MULTIPLY: 1 - (1-heightFog) * (1-farFog) \nLIMITED_ADDITION: farFog + max(farFog, heightFog) \nMULTIPLY_ADDITION: farFog + farFog * heightFog \nINVERSE_MULTIPLY_ADDITION: farFog + 1 - (1-heightFog) * (1-farFog) \nAVERAGE: farFog*0.5 + heightFog*0.5",
|
||||
"distanthorizons.config.client.advanced.graphics.fog.heightFog.heightFogDirection":
|
||||
"Height Fog Direction",
|
||||
"distanthorizons.config.client.advanced.graphics.fog.heightFog.heightFogDirection.@tooltip":
|
||||
"Where should the height fog be located? \n\nABOVE_CAMERA: Height fog starts from camera to the sky \nBELOW_CAMERA: Height fog starts from camera to the void \nABOVE_AND_BELOW_CAMERA: Height fog starts from camera to both the sky and the void \nABOVE_SET_HEIGHT: Height fog starts from a set height to the sky \nBELOW_SET_HEIGHT: Height fog starts from a set height to the void \nABOVE_AND_BELOW_SET_HEIGHT: Height fog starts from a set height to both the sky and the void \n",
|
||||
"distanthorizons.config.client.advanced.graphics.fog.heightFog.heightFogBaseHeight":
|
||||
"Height Fog Base Height",
|
||||
@@ -805,10 +805,10 @@
|
||||
"distanthorizons.config.enum.EDhApiFogFalloff.EXPONENTIAL_SQUARED":
|
||||
"Exponential squared",
|
||||
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMixMode.BASIC":
|
||||
"Basic",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMixMode.IGNORE_HEIGHT":
|
||||
"Ignore Height",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMixMode.SPHERICAL":
|
||||
"Spherical",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMixMode.CYLINDRICAL":
|
||||
"Cylindrical",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMixMode.ADDITION":
|
||||
"Addition",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMixMode.MAX":
|
||||
@@ -826,17 +826,17 @@
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMixMode.AVERAGE":
|
||||
"Average",
|
||||
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMode.ABOVE_CAMERA":
|
||||
"distanthorizons.config.enum.EDhApiHeightFogDirection.ABOVE_CAMERA":
|
||||
"Above Camera",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMode.BELOW_CAMERA":
|
||||
"distanthorizons.config.enum.EDhApiHeightFogDirection.BELOW_CAMERA":
|
||||
"Below Camera",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMode.ABOVE_AND_BELOW_CAMERA":
|
||||
"distanthorizons.config.enum.EDhApiHeightFogDirection.ABOVE_AND_BELOW_CAMERA":
|
||||
"Above And Below Camera",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMode.ABOVE_SET_HEIGHT":
|
||||
"distanthorizons.config.enum.EDhApiHeightFogDirection.ABOVE_SET_HEIGHT":
|
||||
"Above Set Height",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMode.BELOW_SET_HEIGHT":
|
||||
"distanthorizons.config.enum.EDhApiHeightFogDirection.BELOW_SET_HEIGHT":
|
||||
"Below Set Height",
|
||||
"distanthorizons.config.enum.EDhApiHeightFogMode.ABOVE_AND_BELOW_SET_HEIGHT":
|
||||
"distanthorizons.config.enum.EDhApiHeightFogDirection.ABOVE_AND_BELOW_SET_HEIGHT":
|
||||
"Above And Below Set Height",
|
||||
|
||||
"distanthorizons.config.enum.EDhApiVanillaOverdraw.NEVER":
|
||||
|
||||
@@ -1,99 +1,120 @@
|
||||
#version 150 core
|
||||
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
|
||||
|
||||
uniform sampler2D uDepthMap;
|
||||
// inverted model view matrix and projection matrix
|
||||
uniform mat4 uInvMvmProj;
|
||||
|
||||
// fog uniforms
|
||||
uniform vec4 uFogColor;
|
||||
uniform float uFogScale;
|
||||
uniform float uFogVerticalScale;
|
||||
uniform vec4 uFogColor;
|
||||
uniform int uFullFogMode;
|
||||
uniform int uFogFalloffType;
|
||||
|
||||
uniform float uNearFogStart;
|
||||
uniform float uNearFogLength;
|
||||
// fog config
|
||||
uniform float uFarFogStart;
|
||||
uniform float uFarFogLength;
|
||||
uniform float uFarFogMin;
|
||||
uniform float uFarFogRange;
|
||||
uniform float uFarFogDensity;
|
||||
|
||||
// height fog config
|
||||
uniform float uHeightFogStart;
|
||||
uniform float uHeightFogLength;
|
||||
uniform float uHeightFogMin;
|
||||
uniform float uHeightFogRange;
|
||||
uniform float uHeightFogDensity;
|
||||
|
||||
|
||||
/* ========MARCO DEFINED BY RUNTIME CODE GEN=========
|
||||
uniform bool uHeightFogEnabled;
|
||||
uniform int uHeightFogFalloffType;
|
||||
uniform bool uHeightBasedOnCamera;
|
||||
uniform float uHeightFogBaseHeight;
|
||||
uniform bool uHeightFogAppliesUp;
|
||||
uniform bool uHeightFogAppliesDown;
|
||||
uniform bool uUseSphericalFog;
|
||||
uniform int uHeightFogMixingMode;
|
||||
uniform float uCameraBlockYPos;
|
||||
|
||||
float farFogStart;
|
||||
float farFogLength;
|
||||
float farFogMin;
|
||||
float farFogRange;
|
||||
float farFogDensity;
|
||||
|
||||
float heightFogStart;
|
||||
float heightFogLength;
|
||||
float heightFogMin;
|
||||
float heightFogRange;
|
||||
float heightFogDensity;
|
||||
*/
|
||||
|
||||
// method definitions
|
||||
// ==== The below 5 methods will be run-time generated. ====
|
||||
float getNearFogThickness(float dist);
|
||||
float getFarFogThickness(float dist);
|
||||
float getHeightFogThickness(float dist);
|
||||
float calculateFarFogDepth(float horizontal, float dist, float nearFogStart);
|
||||
float calculateHeightFogDepth(float vertical, float realY);
|
||||
float mixFogThickness(float near, float far, float height);
|
||||
// =========================================================
|
||||
|
||||
|
||||
const vec3 MAGIC = vec3(0.06711056, 0.00583715, 52.9829189);
|
||||
|
||||
float InterleavedGradientNoise(const in vec2 pixel) {
|
||||
float x = dot(pixel, MAGIC.xy);
|
||||
return fract(MAGIC.z * fract(x));
|
||||
}
|
||||
|
||||
vec3 calcViewPosition(float fragmentDepth) {
|
||||
vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0);
|
||||
ndc.xyz = ndc.xyz * 2.0 - 1.0;
|
||||
|
||||
vec4 eyeCoord = uInvMvmProj * ndc;
|
||||
return eyeCoord.xyz / eyeCoord.w;
|
||||
}
|
||||
//====================//
|
||||
// method definitions //
|
||||
//====================//
|
||||
|
||||
float InterleavedGradientNoise(const in vec2 pixel);
|
||||
vec3 calcViewPosition(float fragmentDepth);
|
||||
|
||||
float getFarFogThickness(float dist);
|
||||
float getHeightFogThickness(float dist);
|
||||
float calculateHeightFogDepth(float worldYPos);
|
||||
float mixFogThickness(float far, float height);
|
||||
|
||||
|
||||
|
||||
//======//
|
||||
// main //
|
||||
//======//
|
||||
|
||||
/**
|
||||
* Fragment shader for fog.
|
||||
* This should be passed last so it applies above other affects like AO
|
||||
*
|
||||
* version: 2023-6-21
|
||||
* This should be run last so it applies above other affects like Ambient Occlusioning
|
||||
*/
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
float vertexYPos = 100.0f;
|
||||
float fragmentDepth = texture(uDepthMap, TexCoord).r;
|
||||
fragColor = vec4(uFogColor.rgb, 0.0);
|
||||
|
||||
// a fragment depth of "1" means the fragment wasn't drawn to,
|
||||
// we only want to apply Fog to LODs, not to the sky outside the LODs
|
||||
if (fragmentDepth < 1.0) {
|
||||
if (uFullFogMode == 0) {
|
||||
if (fragmentDepth < 1.0)
|
||||
{
|
||||
int fogMode = uFullFogMode;
|
||||
if (fogMode == 0)
|
||||
{
|
||||
// render fog based on distance from the camera
|
||||
vec3 vertexWorldPos = calcViewPosition(fragmentDepth);
|
||||
|
||||
float horizontalDist = length(vertexWorldPos.xz) * uFogScale;
|
||||
float heightDist = calculateHeightFogDepth(vertexWorldPos.y, vertexYPos) * uFogVerticalScale;
|
||||
float farDist = calculateFarFogDepth(horizontalDist, length(vertexWorldPos.xyz) * uFogScale, uNearFogStart);
|
||||
float horizontalWorldDistance = length(vertexWorldPos.xz) * uFogScale;
|
||||
float worldDistance = length(vertexWorldPos.xyz) * uFogScale;
|
||||
float activeDistance = uUseSphericalFog ? worldDistance : horizontalWorldDistance;
|
||||
|
||||
float nearFogThickness = getNearFogThickness(horizontalDist);
|
||||
float farFogThickness = getFarFogThickness(farDist);
|
||||
float heightFogThickness = getHeightFogThickness(heightDist);
|
||||
float mixedFogThickness = mixFogThickness(nearFogThickness, farFogThickness, heightFogThickness);
|
||||
|
||||
// far fog
|
||||
float farFogThickness = getFarFogThickness(activeDistance);
|
||||
|
||||
// height fog
|
||||
float heightFogDepth = calculateHeightFogDepth(vertexWorldPos.y);
|
||||
float heightFogThickness = getHeightFogThickness(heightFogDepth);
|
||||
|
||||
// combined fog
|
||||
float mixedFogThickness = mixFogThickness(farFogThickness, heightFogThickness);
|
||||
fragColor.a = clamp(mixedFogThickness, 0.0, 1.0);
|
||||
|
||||
float dither = InterleavedGradientNoise(gl_FragCoord.xy) - 0.5;
|
||||
fragColor.a += dither / 255.0;
|
||||
// test
|
||||
//fragColor.a = heightFogThickness;
|
||||
|
||||
// dither fog (to smooth out aliasing)
|
||||
//float dither = InterleavedGradientNoise(gl_FragCoord.xy) - 0.5;
|
||||
//fragColor.a += dither / 255.0;
|
||||
}
|
||||
else if (uFullFogMode == 1) {
|
||||
else if (fogMode == 1)
|
||||
{
|
||||
// render everything with the fog color
|
||||
fragColor.a = 1.0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// test code.
|
||||
|
||||
// this can be fired by manually changing the fullFogMode to a (normally)
|
||||
@@ -108,22 +129,174 @@ void main()
|
||||
}
|
||||
}
|
||||
|
||||
// Are these still needed?
|
||||
float linearFog(float x, float fogStart, float fogLength, float fogMin, float fogRange) {
|
||||
x = clamp((x-fogStart)/fogLength, 0.0, 1.0);
|
||||
return fogMin + fogRange * x;
|
||||
|
||||
//
|
||||
// methods //
|
||||
//
|
||||
|
||||
float InterleavedGradientNoise(const in vec2 pixel)
|
||||
{
|
||||
float x = dot(pixel, MAGIC.xy);
|
||||
return fract(MAGIC.z * fract(x));
|
||||
}
|
||||
|
||||
vec3 calcViewPosition(float fragmentDepth)
|
||||
{
|
||||
vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0);
|
||||
ndc.xyz = ndc.xyz * 2.0 - 1.0;
|
||||
|
||||
vec4 eyeCoord = uInvMvmProj * ndc;
|
||||
return eyeCoord.xyz / eyeCoord.w;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float linearFog(float worldDist, float fogStart, float fogLength, float fogMin, float fogRange)
|
||||
{
|
||||
worldDist = (worldDist - fogStart) / fogLength;
|
||||
worldDist = clamp(worldDist, 0.0, 1.0);
|
||||
return fogMin + fogRange * worldDist;
|
||||
}
|
||||
|
||||
float exponentialFog(float x, float fogStart, float fogLength,
|
||||
float fogMin, float fogRange, float fogDensity)
|
||||
float fogMin, float fogRange, float fogDensity)
|
||||
{
|
||||
x = max((x-fogStart)/fogLength, 0.0) * fogDensity;
|
||||
return fogMin + fogRange - fogRange/exp(x);
|
||||
}
|
||||
|
||||
float exponentialSquaredFog(float x, float fogStart, float fogLength,
|
||||
float fogMin, float fogRange, float fogDensity)
|
||||
float fogMin, float fogRange, float fogDensity)
|
||||
{
|
||||
x = max((x-fogStart)/fogLength, 0.0) * fogDensity;
|
||||
return fogMin + fogRange - fogRange/exp(x*x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// generated methods //
|
||||
//
|
||||
|
||||
float getFarFogThickness(float dist)
|
||||
{
|
||||
if (uFogFalloffType == 0) // LINEAR
|
||||
{
|
||||
return linearFog(dist, uFarFogStart, uFarFogLength, uFarFogMin, uFarFogRange);
|
||||
}
|
||||
else if (uFogFalloffType == 1) // EXPONENTIAL
|
||||
{
|
||||
return exponentialFog(dist, uFarFogStart, uFarFogLength, uFarFogMin, uFarFogRange, uFarFogDensity);
|
||||
}
|
||||
else // EXPONENTIAL_SQUARED
|
||||
{
|
||||
return exponentialSquaredFog(dist, uFarFogStart, uFarFogLength, uFarFogMin, uFarFogRange, uFarFogDensity);
|
||||
}
|
||||
}
|
||||
|
||||
float getHeightFogThickness(float dist)
|
||||
{
|
||||
if (!uHeightFogEnabled)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (uHeightFogFalloffType == 0) // LINEAR
|
||||
{
|
||||
return linearFog(dist, uHeightFogStart, uHeightFogLength, uHeightFogMin, uHeightFogRange);
|
||||
}
|
||||
else if (uHeightFogFalloffType == 1) // EXPONENTIAL
|
||||
{
|
||||
return exponentialFog(dist, uHeightFogStart, uHeightFogLength, uHeightFogMin, uHeightFogRange, uHeightFogDensity);
|
||||
}
|
||||
else // EXPONENTIAL_SQUARED
|
||||
{
|
||||
return exponentialSquaredFog(dist, uHeightFogStart, uHeightFogLength, uHeightFogMin, uHeightFogRange, uHeightFogDensity);
|
||||
}
|
||||
}
|
||||
|
||||
/** 1 = full fog, 0 = no fog */
|
||||
float calculateHeightFogDepth(float worldYPos)
|
||||
{
|
||||
// worldYPos -65 - 384
|
||||
|
||||
|
||||
//worldYPos = worldYPos * -1; // negative, fog below height; positive, fog above height
|
||||
//return worldYPos * uFogVerticalScale; // "* uFogVerticalScale" is done to convert world position to a percent of the world height;
|
||||
|
||||
if (!uHeightFogEnabled)
|
||||
{
|
||||
// ignore the height
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
if (!uHeightBasedOnCamera)
|
||||
{
|
||||
worldYPos -= (uHeightFogBaseHeight - uCameraBlockYPos);
|
||||
}
|
||||
|
||||
|
||||
if (uHeightFogAppliesDown && uHeightFogAppliesUp)
|
||||
{
|
||||
// TODO this aint right
|
||||
return abs(worldYPos) * uFogVerticalScale;
|
||||
}
|
||||
else if (uHeightFogAppliesDown)
|
||||
{
|
||||
// apploy fog below given height
|
||||
return -worldYPos * uFogVerticalScale;
|
||||
}
|
||||
else if (uHeightFogAppliesUp)
|
||||
{
|
||||
// apply fog above given height
|
||||
return worldYPos * uFogVerticalScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldn't happen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float mixFogThickness(float far, float height)
|
||||
{
|
||||
switch (uHeightFogMixingMode)
|
||||
{
|
||||
case 0: // BASIC
|
||||
case 1: // IGNORE_HEIGHT
|
||||
return far;
|
||||
|
||||
case 2: // MAX
|
||||
return max(far, height);
|
||||
|
||||
case 3: // ADDITION
|
||||
return (far + height);
|
||||
|
||||
case 4: // MULTIPLY
|
||||
return far * height;
|
||||
|
||||
case 5: // INVERSE_MULTIPLY
|
||||
return (1.0 - (1.0-far)*(1.0-height));
|
||||
|
||||
case 6: // LIMITED_ADDITION
|
||||
return (far + max(far, height));
|
||||
|
||||
case 7: // MULTIPLY_ADDITION
|
||||
return (far + far*height);
|
||||
|
||||
case 8: // INVERSE_MULTIPLY_ADDITION
|
||||
return (far + 1.0 - (1.0-far)*(1.0-height));
|
||||
|
||||
case 9: // AVERAGE
|
||||
return (far*0.5 + height*0.5);
|
||||
}
|
||||
|
||||
// shouldn't happen, but default to BASIC / IGNORE_HEIGHT
|
||||
// if an invalid option is selected
|
||||
return far;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user