[1.12.2] add support for 3.0.0b

This commit is contained in:
Vojtěch Šokala
2026-03-15 15:42:08 +01:00
parent 6b32ab02d3
commit 8991338be1
73 changed files with 1712 additions and 269 deletions
+31 -20
View File
@@ -48,6 +48,8 @@ configurations {
runtimeOnly.extendsFrom(modRuntimeOnly)
}
String remapTaskName = "remapShadowJar"
unimined.minecraft {
version "1.12.2"
@@ -64,10 +66,12 @@ unimined.minecraft {
runs.auth.username = "Developer"
runs.all {
systemProperty("crl.dev.mixin", "${mod_id}.default.mixin.json,${mod_id}.mod.mixin.json")
def extraArgs = ''
if (extraArgs != null && !extraArgs.trim().isEmpty()) {
jvmArgs += extraArgs.split { "\\s+" }.toList()
}
jvmArgs += ['-Xmx4G']
jvmArgs += [
'-XX:+UseZGC',
'-XX:-UseG1GC'
]
jvmArgs += ['-XX:+ZGenerational']
println "Classpath size BEFORE: ${classpath.files.size()}"
@@ -115,7 +119,8 @@ unimined.minecraft {
defaultRemapJar = false
if (propertyBool('enable_shadow')) {
//propertyBool('enable_shadow')
if (true) {
remap(tasks.shadowJar) {
mixinRemap {
enableBaseMixin()
@@ -149,11 +154,11 @@ processResources {
inputs.property 'mod_name', propertyString('mod_name')
inputs.property 'mod_version', propertyString('mod_version')
inputs.property 'mod_description', propertyString('mod_description')
inputs.property 'mod_authors', "${propertyStringList('mod_authors', ',').join(', ')}"
inputs.property 'mod_authors', propertyString('mod_authors').replace('[', '').replace(']', '').split(',').collect { it.trim().replace('"', '') }.join('", "')
inputs.property 'mod_credits', propertyString('mod_credits')
inputs.property 'mod_url', propertyString('mod_url')
inputs.property 'mod_url', propertyString('mod_homepage')
inputs.property 'mod_update_json', propertyString('mod_update_json')
inputs.property 'mod_logo_path', propertyString('mod_logo_path')
inputs.property 'mod_logo_path', "assets/distanthorizons/icon.png"
def filterList = ['mcmod.info', 'pack.mcmeta']
@@ -163,11 +168,11 @@ processResources {
'mod_name': propertyString('mod_name'),
'mod_version': propertyString('mod_version'),
'mod_description': propertyString('mod_description'),
'mod_authors': "${propertyStringList('mod_authors', ',').join(', ')}",
'mod_authors': propertyString('mod_authors').replace('[', '').replace(']', '').split(',').collect { it.trim().replace('"', '') }.join('", "'),
'mod_credits': propertyString('mod_credits'),
'mod_url': propertyString('mod_url'),
'mod_url': propertyString('mod_homepage'),
'mod_update_json': propertyString('mod_update_json'),
'mod_logo_path': propertyString('mod_logo_path'),
'mod_logo_path': "assets/distanthorizons/icon.png",
)
}
@@ -186,8 +191,8 @@ sourceSets {
}
}
}
if (!propertyBool('enable_shadow')) {
//propertyBool('enable_shadow')
if (!true) {
shadowJar.enabled = false
}
@@ -230,19 +235,25 @@ jar {
attributes(attribute_map)
}
}
if (propertyBool('enable_shadow')) {
finalizedBy(tasks.named("remapShadowJar"))
} else {
finalizedBy(tasks.named("remapJar"))
}
finalizedBy(tasks.named(remapTaskName).get())
}
shadowJar {
configurations = [project.configurations.shadow]
configurations = [project.configurations.shadowMe, project.configurations.shadowCommon]
archiveClassifier = "shadow"
manifest {
def attribute_map = [:]
attribute_map['ModType'] = "CRL"
attribute_map['MixinConfigs'] = "${mod_id}.default.mixin.json,${mod_id}.mod.mixin.json"
attribute_map['FMLCorePlugin'] = "com.seibel.distanthorizons.cleanroom.DistantHorizonsLoadingPlugin"
attribute_map['FMLCorePluginContainsFMLMod'] = true
attribute_map['FMLAT'] = "1_12_2_distanthorizons_at.cfg"
attributes(attribute_map)
}
}
remapJar {
tasks.named(remapTaskName).configure {
doFirst {
logging.captureStandardOutput LogLevel.INFO
}
@@ -49,6 +49,7 @@ import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
@@ -78,13 +79,8 @@ public class CleanroomClientProxy implements AbstractModInitializer.IEventProxy
public void registerEvents()
{
MinecraftForge.EVENT_BUS.register(this);
// handles singleplayer, LAN, and connecting to a server
PACKET_SENDER.setPacketHandler((IServerPlayerWrapper player, @NotNull AbstractNetworkMessage message) ->
{
ClientApi.INSTANCE.pluginMessageReceived(message);
ServerApi.INSTANCE.pluginMessageReceived(player, message);
});
MinecraftForge.EVENT_BUS.register(FMLCommonHandler.instance());
CleanroomPluginPacketSender.setPacketHandler(ClientApi.INSTANCE::pluginMessageReceived);
}
@@ -21,19 +21,24 @@ package com.seibel.distanthorizons.cleanroom;
import com.seibel.distanthorizons.cleanroom.modAccessor.ModChecker;
import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.commands.CommandInitializer;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.InternalServerGenerator;
import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent;
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
import net.minecraftforge.fml.common.event.*;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import java.util.List;
import java.util.function.Consumer;
/**
@@ -47,6 +52,13 @@ public class CleanroomMain extends AbstractModInitializer
@Mod.Instance
public static CleanroomMain instance;
@Mod.EventHandler
public void preinit(FMLPreInitializationEvent event)
{
Configurator.setLevel("org.sqlite", Level.INFO);
ForgeChunkManager.setForcedChunkLoadingCallback(CleanroomMain.instance, (tickets, world) -> { });
}
@Mod.EventHandler
public void init(FMLInitializationEvent event)
{
@@ -93,6 +105,12 @@ public class CleanroomMain extends AbstractModInitializer
eventHandler.run();
}
@Mod.EventHandler
public void onServerStarting(FMLServerStartingEvent event)
{
event.registerServerCommand(CommandInitializer.initCommands());
}
@Mod.EventHandler
public void onServerAboutToStart(FMLServerAboutToStartEvent event)
{
@@ -1,6 +1,8 @@
package com.seibel.distanthorizons.cleanroom;
import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.commands.CommandInitializer;
import com.seibel.distanthorizons.common.commonMixins.MixinChunkMapCommon;
import com.seibel.distanthorizons.common.util.ProxyUtil;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
@@ -22,14 +24,18 @@ import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.ChunkDataEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
import java.lang.reflect.Field;
import static com.seibel.distanthorizons.cleanroom.CleanroomMain.instance;
public class CleanroomServerProxy implements AbstractModInitializer.IEventProxy
{
private static final CleanroomPluginPacketSender PACKET_SENDER = (CleanroomPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
@@ -45,6 +51,7 @@ public class CleanroomServerProxy implements AbstractModInitializer.IEventProxy
public void registerEvents()
{
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
if (this.isDedicated)
{
PACKET_SENDER.setPacketHandler(ServerApi.INSTANCE::pluginMessageReceived);
@@ -65,25 +72,15 @@ public class CleanroomServerProxy implements AbstractModInitializer.IEventProxy
// events //
//========//
// ServerLevelLoadEvent
@SubscribeEvent
public void serverLevelLoadEvent(WorldEvent.Load event)
{
if (GetEventLevel(event) instanceof WorldServer)
{
InternalServerGenerator.DH_SERVER_GEN_TICKET_MAP.put(event.getWorld(), ForgeChunkManager.requestTicket(instance, event.getWorld(), ForgeChunkManager.Type.NORMAL));
this.serverApi.serverLevelLoadEvent(getServerLevelWrapper((WorldServer) GetEventLevel(event)));
InternalServerGenerator.DH_SERVER_GEN_TICKET = ForgeChunkManager.requestTicket(CleanroomMain.instance, event.getWorld(), ForgeChunkManager.Type.NORMAL);
//increase chunk limit
try
{
Field maxDepthField = InternalServerGenerator.DH_SERVER_GEN_TICKET.getClass().getDeclaredField("maxDepth");
maxDepthField.setAccessible(true);
maxDepthField.setInt(InternalServerGenerator.DH_SERVER_GEN_TICKET, 1000);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
@@ -105,6 +102,15 @@ public class CleanroomServerProxy implements AbstractModInitializer.IEventProxy
this.serverApi.serverChunkLoadEvent(chunk, levelWrapper);
}
@SubscribeEvent
public void serverChunkSaveEvent(ChunkDataEvent.Save event)
{
if (event.getWorld() instanceof WorldServer worldServer)
{
MixinChunkMapCommon.onChunkSave(worldServer, event.getChunk());
}
}
@SubscribeEvent
public void playerLoggedInEvent(PlayerEvent.PlayerLoggedInEvent event)
{ this.serverApi.serverPlayerJoinEvent(getServerPlayerWrapper(event)); }
@@ -115,9 +121,9 @@ public class CleanroomServerProxy implements AbstractModInitializer.IEventProxy
public void playerChangedDimensionEvent(PlayerEvent.PlayerChangedDimensionEvent event)
{
this.serverApi.serverPlayerLevelChangeEvent(
getServerPlayerWrapper(event),
getServerLevelWrapper(event.fromDim, event),
getServerLevelWrapper(event.toDim, event)
getServerPlayerWrapper(event),
getServerLevelWrapper(event.fromDim, event),
getServerLevelWrapper(event.toDim, event)
);
}
@@ -1,26 +0,0 @@
package com.seibel.distanthorizons.cleanroom.mixins.common;
import com.seibel.distanthorizons.common.commonMixins.MixinChunkMapCommon;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.ChunkProviderServer;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ChunkProviderServer.class)
public class MixinChunkProviderServer
{
@Shadow
@Final
public WorldServer world;
@Inject(method = "saveChunkData", at = @At("RETURN"))
private void onSaveChunkData(Chunk chunk, CallbackInfo ci)
{
MixinChunkMapCommon.onChunkSave(world, chunk);
}
}
@@ -0,0 +1,27 @@
#version 150 core
in vec2 TexCoord;
out vec4 fragColor;
uniform sampler2D uSourceColorTexture;
uniform sampler2D uSourceDepthTexture;
// DH apply frag
void main()
{
fragColor = vec4(0.0);
// a fragment depth of "1" means the fragment wasn't drawn to,
// only update fragments that were drawn to
float fragmentDepth = texture(uSourceDepthTexture, TexCoord).r;
if (fragmentDepth != 1)
{
fragColor = texture(uSourceColorTexture, TexCoord);
}
else
{
// use the original MC texture if no LODs were drawn to this fragment
discard;
}
}
@@ -0,0 +1,15 @@
#version 150 core
in vec2 vPosition;
out vec2 TexCoord;
/**
* This is specifically used by application shaders.
* IE post process or pixel transfer shaders, anything that is rendered using a single rectangle.
*/
void main()
{
gl_Position = vec4(vPosition, 0.0, 1.0);
TexCoord = vPosition.xy * 0.5 + 0.5;
}
@@ -0,0 +1,13 @@
#version 150 core
in vec2 TexCoord;
out vec4 fragColor;
uniform sampler2D uCopyTexture;
// DH copy frag
void main()
{
fragColor = texture(uCopyTexture, TexCoord);
}
@@ -0,0 +1,12 @@
#version 150 core
in vec2 vPosition;
out vec2 TexCoord;
// DH copy
void main()
{
gl_Position = vec4(vPosition, 0.0, 1.0);
TexCoord = vPosition.xy * 0.5 + 0.5;
}
@@ -0,0 +1,14 @@
#version 150 core
layout (std140) uniform uniformBlock
{
mat4 uTransform;
vec4 uColor;
};
out vec4 fragColor;
void main()
{
fragColor = uColor;
}
@@ -0,0 +1,14 @@
#version 150 core
layout (std140) uniform uniformBlock
{
mat4 uTransform;
vec4 uColor;
};
in vec3 vPosition;
void main()
{
gl_Position = uTransform * vec4(vPosition, 1.0);
}
@@ -0,0 +1,67 @@
#version 150 core
in vec2 TexCoord;
out vec4 fragColor;
layout (std140) uniform fragUniformBlock
{
float uStartFadeBlockDistance;
float uEndFadeBlockDistance;
// inverted model view matrix and projection matrix
mat4 uDhInvMvmProj;
};
uniform sampler2D uMcColorTexture;
uniform sampler2D uDhDepthTexture;
uniform sampler2D uDhColorTexture;
vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj)
{
// normalized device coordinates
vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0);
ndc.xyz = ndc.xyz * 2.0 - 1.0;
vec4 eyeCoord = invMvmProj * ndc;
return eyeCoord.xyz / eyeCoord.w;
}
/**
* Used to fade out vanilla chunks so the transition
* between DH and vanilla is smoother.
*/
void main()
{
// includes both the vanilla chunks as well as DH
vec4 combinedMcDhColor = texture(uMcColorTexture, TexCoord);
// just the DH render pass
vec4 dhColor = texture(uDhColorTexture, TexCoord);
// the DH texture will have white if nothing was written to that pixel.
if (dhColor == vec4(1))
{
// if not done vanilla clouds will render incorrectly at night
dhColor = combinedMcDhColor;
}
float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r;
vec3 dhVertexWorldPos = calcViewPosition(dhFragmentDepth, uDhInvMvmProj);
float dhFragmentDistance = length(dhVertexWorldPos.xzy);
float startFade = uEndFadeBlockDistance;
float endFade = uStartFadeBlockDistance;
// Smoothly transition between combinedMcDhColor and uDhColorTexture
// as the depth increases from the camera
float fadeStep = smoothstep(startFade, endFade, dhFragmentDistance);
fragColor = mix(combinedMcDhColor, dhColor, fadeStep);
fragColor.a = 1.0;
}
@@ -0,0 +1,95 @@
#version 150 core
in vec2 TexCoord;
out vec4 fragColor;
uniform sampler2D uMcDepthTexture;
uniform sampler2D uCombinedMcDhColorTexture;
uniform sampler2D uDhDepthTexture;
uniform sampler2D uDhColorTexture;
layout (std140) uniform fragUniformBlock
{
bool uOnlyRenderLods;
float uStartFadeBlockDistance;
float uEndFadeBlockDistance;
float uMaxLevelHeight;
// inverted model view matrix and projection matrix
mat4 uDhInvMvmProj;
mat4 uMcInvMvmProj;
};
vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj)
{
// normalized device coordinates
vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0);
ndc.xyz = ndc.xyz * 2.0 - 1.0;
vec4 eyeCoord = invMvmProj * ndc;
return eyeCoord.xyz / eyeCoord.w;
}
/**
* Used to fade out vanilla chunks so the transition
* between DH and vanilla is smoother.
*/
void main()
{
// includes both the vanilla chunks as well as DH
vec4 combinedMcDhColor = texture(uCombinedMcDhColorTexture, TexCoord);
// just the DH render pass
vec4 dhColor = texture(uDhColorTexture, TexCoord);
// completely remove the MC render pass to only show LODs
// useful for debugging/troubleshooting, but doesn't improve performance since MC is still rendering
if (uOnlyRenderLods)
{
fragColor = dhColor;
return;
}
// ignore anything that DH hasn't drawn to
// We don't use DH's depth here because it would prevent the fade from running before DH has loaded
if (dhColor == vec4(1))
{
// if not done vanilla clouds will render incorrectly at night
dhColor = combinedMcDhColor;
}
float mcFragmentDepth = texture(uMcDepthTexture, TexCoord).r;
float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r;
vec3 dhVertexWorldPos = calcViewPosition(dhFragmentDepth, uDhInvMvmProj);
// this is a work around to prevent MC clouds rendering behind DH clouds
if (dhVertexWorldPos.y > uMaxLevelHeight)
{
fragColor = vec4(combinedMcDhColor.rgb, 0.0);
}
// a fragment depth of "1" means the fragment wasn't drawn to,
// we only want to fade vanilla rendered objects, not to the sky or LODs
else if (mcFragmentDepth < 1.0)
{
// fade based on distance from the camera
vec3 mcVertexWorldPos = calcViewPosition(mcFragmentDepth, uMcInvMvmProj);
float mcFragmentDistance = length(mcVertexWorldPos.xzy);
// Smoothly transition between combinedMcDhColor and uDhColorTexture
// as the depth increases from the camera
float fadeStep = smoothstep(uStartFadeBlockDistance, uEndFadeBlockDistance, mcFragmentDistance);
fragColor = mix(combinedMcDhColor, dhColor, fadeStep);
fragColor.a = 1.0;
}
else
{
fragColor = vec4(combinedMcDhColor.rgb, 0.0);
}
}
@@ -0,0 +1,15 @@
#version 150 core
in vec2 vPosition;
in vec4 vColor;
out vec4 fColor;
out vec2 TexCoord;
// DH vert fade test
void main()
{
gl_Position = vec4(vPosition, 0.0, 1.0);
fColor = vec4(vPosition, 0.0, 1.0);
TexCoord = vPosition.xy * 0.5 + 0.5;
}
@@ -0,0 +1,299 @@
#version 150 core
in vec2 TexCoord;
out vec4 fragColor;
layout (std140) uniform fragUniformBlock
{
// fog uniforms
vec4 uFogColor;
float uFogScale;
float uFogVerticalScale;
int uFogDebugMode;
int uFogFalloffType;
// fog config
float uFarFogStart;
float uFarFogLength;
float uFarFogMin;
float uFarFogRange;
float uFarFogDensity;
// height fog config
float uHeightFogStart;
float uHeightFogLength;
float uHeightFogMin;
float uHeightFogRange;
float uHeightFogDensity;
// ???
bool uHeightFogEnabled;
int uHeightFogFalloffType;
bool uHeightBasedOnCamera;
float uHeightFogBaseHeight;
bool uHeightFogAppliesUp;
bool uHeightFogAppliesDown;
bool uUseSphericalFog;
int uHeightFogMixingMode;
float uCameraBlockYPos;
// inverted model view matrix and projection matrix
mat4 uInvMvmProj;
};
uniform sampler2D uDhDepthTexture;
//====================//
// method definitions //
//====================//
vec3 calcViewPosition(float fragmentDepth);
float getFarFogThickness(float dist);
float getHeightFogThickness(float dist);
float calculateHeightFogDepth(float worldYPos);
float mixFogThickness(float far, float height);
float linearFog(float worldDist, float fogStart, float fogLength, float fogMin, float fogRange);
float exponentialFog(float x, float fogStart, float fogLength, float fogMin, float fogRange, float fogDensity);
float exponentialSquaredFog(float x, float fogStart, float fogLength, float fogMin, float fogRange, float fogDensity);
//======//
// main //
//======//
/**
* Fragment shader for fog.
* This should be run last so it applies above other affects like Ambient Occlusioning
*/
void main()
{
float fragmentDepth = texture(uDhDepthTexture, 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)
{
int fogDebugMode = uFogDebugMode;
if (fogDebugMode == 0)
{
// render fog based on distance from the camera
vec3 vertexWorldPos = calcViewPosition(fragmentDepth);
float horizontalWorldDistance = length(vertexWorldPos.xz) * uFogScale;
float worldDistance = length(vertexWorldPos.xyz) * uFogScale;
float activeDistance = uUseSphericalFog ? worldDistance : horizontalWorldDistance;
// 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);
}
else if (fogDebugMode == 1)
{
// test code
// render everything with the fog color
fragColor.a = 1.0;
}
else
{
// test code.
// this can be fired by manually changing the fullFogMode to a (normally)
// invalid value (like 7).
// By having a separate if statement defined by
// a uniform we don't have to worry about GLSL optimizing away different
// options when testing, causing a bunch of headaches if we just want to render the screen red.
float depthValue = textureLod(uDhDepthTexture, TexCoord, 0).r;
fragColor.rgb = vec3(depthValue); // Convert depth value to grayscale color
fragColor.a = 1.0;
}
}
}
//================//
// helper methods //
//================//
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;
}
//=========//
// far fog //
//=========//
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);
}
}
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)
{
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)
{
x = max((x-fogStart)/fogLength, 0.0) * fogDensity;
return fogMin + fogRange - fogRange/exp(x*x);
}
//============//
// height fog //
//============//
/** 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)
{
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.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;
}
@@ -0,0 +1,101 @@
#version 330 core
//layout (location = 1) in vec4 aColor; // RGBA_FLOAT_COLOR
//layout (location = 2) in vec3 aScale; // VEC3_SCALE
//layout (location = 3) in ivec3 aTranslateChunk; // IVEC3_SCALE
//layout (location = 4) in vec3 aTranslateSubChunk; // VEC3_SCALE
//layout (location = 5) in int aMaterial; // IRIS_MATERIAL
//uniform sampler2D /*vec4*/ uColorMap;
//uniform sampler2D /*vec3*/ uScaleMap;
//uniform sampler2D /*int*/ uTranslateChunkXMap;
//uniform sampler2D /*int*/ uTranslateChunkYMap;
//uniform sampler2D /*int*/ uTranslateChunkZMap;
//uniform sampler2D /*vec3*/ uTranslateSubChunkMap;
//uniform sampler2D /*int*/ uMaterialMap;
//
//in vec3 vPosition;
in vec3 vPosition;
in vec4 aColor; // RGBA_FLOAT_COLOR
in int aMaterial; // IRIS_MATERIAL
layout (std140) uniform vertUniformBlock
{
ivec3 uOffsetChunk;
vec3 uOffsetSubChunk;
ivec3 uCameraPosChunk;
vec3 uCameraPosSubChunk;
mat4 uProjectionMvm;
int uSkyLight;
int uBlockLight;
float uNorthShading;
float uSouthShading;
float uEastShading;
float uWestShading;
float uTopShading;
float uBottomShading;
};
uniform sampler2D uLightMap;
out vec4 fColor;
void main()
{
vec3 aScale = vec3(1);
if (aMaterial == 999)
{
aScale = vec3(2);
}
// vec4 aColor = texelFetch(uColorMap, ivec2(gl_InstanceID,0), 0);
// vec3 aScale = texelFetch(uScaleMap, ivec2(gl_InstanceID,0), 0).xyz;
//
// float chunkX = int(texelFetch(uTranslateChunkXMap, ivec2(gl_InstanceID,0), 0).x);
// float chunkY = int(texelFetch(uTranslateChunkYMap, ivec2(gl_InstanceID,0), 0).x);
// float chunkZ = int(texelFetch(uTranslateChunkZMap, ivec2(gl_InstanceID,0), 0).x);
// ivec3 aTranslateChunk = ivec3(chunkX, chunkY, chunkZ);
//
// vec3 aTranslateSubChunk = texelFetch(uTranslateSubChunkMap, ivec2(gl_InstanceID,0), 0).xyz;
// int aMaterial = int(texelFetch(uMaterialMap, ivec2(gl_InstanceID,0), 0).x);
// aTranslate - moves the vertex to the boxGroup's relative position
// uOffset - moves the vertex to the boxGroup's world position
// uCameraPos - moves the vertex into camera space
vec3 trans = (uOffsetChunk - uCameraPosChunk) * 16.0f;
// separate float and int values are to fix percission loss at extreme distances from the origin (IE 10,000,000+)
// luckily large translate values minus large cameraPos generally equal values that cleanly fit in a float
trans += (uOffsetSubChunk - uCameraPosSubChunk);
// combination translation and scaling matrix
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
);
gl_Position = uProjectionMvm * transform * vec4(vPosition, 1.0);
float blockLight = (float(uBlockLight)+0.5) / 16.0;
float skyLight = (float(uSkyLight)+0.5) / 16.0;
vec4 lightColor = vec4(texture(uLightMap, vec2(blockLight, skyLight)).xyz, 1.0);
fColor = lightColor * aColor;
int vertexIndex = gl_VertexID % 24;
// apply directional shading
if (vertexIndex >= 0 && vertexIndex < 4) { fColor.rgb *= uNorthShading; }
else if (vertexIndex >= 4 && vertexIndex < 8) { fColor.rgb *= uSouthShading; }
else if (vertexIndex >= 8 && vertexIndex < 12) { fColor.rgb *= uWestShading; }
else if (vertexIndex >= 12 && vertexIndex < 16) { fColor.rgb *= uEastShading; }
else if (vertexIndex >= 16 && vertexIndex < 20) { fColor.rgb *= uBottomShading; }
else if (vertexIndex >= 20 && vertexIndex < 24) { fColor.rgb *= uTopShading; }
}
@@ -0,0 +1,10 @@
#version 150 core
in vec4 fColor;
out vec4 fragColor;
void main()
{
fragColor = fColor;
}
@@ -0,0 +1,125 @@
#version 150
in vec4 vertexColor;
in vec3 vertexWorldPos;
in vec3 vPos;
in vec4 gl_FragCoord;
out vec4 fragColor;
layout (std140) uniform fragUniformBlock
{
// Fade/Clip Uniforms
float uClipDistance;
// Noise Uniforms
float uNoiseIntensity;
int uNoiseSteps;
int uNoiseDropoff;
bool uDitherDhRendering;
bool uNoiseEnabled;
};
// The random functions for diffrent dimentions
float rand(float co) { return fract(sin(co*(91.3458)) * 47453.5453); }
float rand(vec2 co) { return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); }
float rand(vec3 co) { return rand(co.xy + rand(co.z)); }
// Puts steps in a float
// EG. setting stepSize to 4 then this would be the result of this function
// In: 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, ..., 1.1, 1.2, 1.3
// Out: 0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, ..., 1.0, 1.0, 1.25
vec3 quantize(vec3 val, int stepSize)
{
return floor(val * stepSize) / stepSize;
}
void applyNoise(inout vec4 fragColor, const in float viewDist)
{
vec3 vertexNormal = normalize(cross(dFdy(vPos.xyz), dFdx(vPos.xyz)));
// This bit of code is required to fix the vertex position problem cus of floats in the verted world position varuable
vec3 fixedVPos = vPos.xyz + vertexNormal * 0.001;
float noiseAmplification = uNoiseIntensity;
float lum = (fragColor.r + fragColor.g + fragColor.b) / 3.0;
noiseAmplification = (1.0 - pow(lum * 2.0 - 1.0, 2.0)) * noiseAmplification; // Lessen the effect on depending on how dark the object is, equasion for this is -(2x-1)^{2}+1
noiseAmplification *= fragColor.a; // The effect would lessen on transparent objects
// Random value for each position
float randomValue = rand(quantize(fixedVPos, uNoiseSteps))
* 2.0 * noiseAmplification - noiseAmplification;
// Modifies the color
// A value of 0 on the randomValue will result in the original color, while a value of 1 will result in a fully bright color
vec3 newCol = fragColor.rgb + (1.0 - fragColor.rgb) * randomValue;
newCol = clamp(newCol, 0.0, 1.0);
if (uNoiseDropoff != 0) {
float distF = min(viewDist / uNoiseDropoff, 1.0);
newCol = mix(newCol, fragColor.rgb, distF); // The further away it gets, the less noise gets applied
}
fragColor.rgb = newCol;
}
/** returns a normalized value between 0.0 and 1.0 */
float bayerMatrix4x4(vec2 st)
{
int x = int(mod(st.x, 4.0));
int y = int(mod(st.y, 4.0));
// Flattened 4x4 Bayer matrix
float bayer4x4[16] = float[16](
0.0, 8.0, 2.0, 10.0,
12.0, 4.0, 14.0, 6.0,
3.0, 11.0, 1.0, 9.0,
15.0, 7.0, 13.0, 5.0
);
// Calculate the 1D index from the 2D coordinates
int index = y * 4 + x;
// Return the Bayer value normalized between 0.0 and 1.0
return bayer4x4[index] / 16.0;
}
void main()
{
fragColor = vertexColor;
float viewDist = length(vertexWorldPos);
if (uDitherDhRendering)
{
// Dither out the fragment based on distance and noise.
// Dithering is used since it works for both opaque and transparent rendering
// noise increases as the distance increases
// the fragCoord is used since it is stable and small so the dithering is cleaner
float worldNoise = bayerMatrix4x4(gl_FragCoord.xy);
// minor fudge factor to make sure all pixels fade out
// if not included 1 in 16 pixels would never fade away
worldNoise += 0.001;
float fadeStep = smoothstep(uClipDistance, uClipDistance * 1.5, viewDist);
if (fadeStep <= worldNoise)
{
discard;
}
}
else
{
if (viewDist < uClipDistance && uClipDistance > 0.0)
{
discard;
}
}
if (uNoiseEnabled)
{
applyNoise(fragColor, viewDist);
}
}
@@ -0,0 +1,81 @@
#version 150
in uvec3 vPosition;
in uint meta; // contains light and micro-offset data
in vec4 vColor;
in int irisMaterial;
in int irisNormal;
out vec3 vPos;
out vec4 vertexColor;
out vec3 vertexWorldPos;
out float vertexYPos;
layout (std140) uniform vertUniqueUniformBlock
{
vec3 uModelOffset;
};
layout (std140) uniform vertSharedUniformBlock
{
bool uIsWhiteWorld;
float uWorldYOffset;
float uMircoOffset;
float uEarthRadius;
vec3 uCameraPos;
mat4 uCombinedMatrix;
};
uniform sampler2D uLightMap;
/**
* LOD terrain Vertex Shader
*/
void main()
{
vPos = vPosition; // This is so it can be passed to the fragment shader
vertexWorldPos = vPosition.xyz + (uModelOffset - uCameraPos);
vertexYPos = vPosition.y + uWorldYOffset;
uint mirco = (meta & 0xFF00u) >> 8u; // mirco offset which is a xyz 2bit value
// 0b00 = no offset
// 0b01 = positive offset
// 0b11 = negative offset
// format is: 0b00zzyyxx
float mx = (mirco & 1u)!=0u ? uMircoOffset : 0.0;
mx = (mirco & 2u)!=0u ? -mx : mx;
//float my = (mirco & 4u)!=0u ? uMircoOffset : 0.0;
//my = (mirco & 8u)!=0u ? -my : my;
float mz = (mirco & 16u)!=0u ? uMircoOffset : 0.0;
mz = (mirco & 32u)!=0u ? -mz : mz;
vertexWorldPos.x += mx;
//vertexWorldPos.y += my;
vertexWorldPos.z += mz;
// apply the earth curvature if needed
if (uEarthRadius < -1.0f || uEarthRadius > 1.0f)
{
// vertex transformation logic - stduhpf
float localRadius = uEarthRadius + vertexYPos;
float phi = length(vertexWorldPos.xz) / localRadius;
vertexWorldPos.y += (cos(phi) - 1.0) * localRadius;
vertexWorldPos.xz = vertexWorldPos.xz * sin(phi) / phi;
}
uint lights = meta & 0xFFu;
float skyLight = (float(lights/16u)+0.5) / 16.0;
float blockLight = (mod(float(lights), 16.0)+0.5) / 16.0;
vertexColor = vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0);
if (!uIsWhiteWorld)
{
vertexColor *= vColor;
}
gl_Position = uCombinedMatrix * vec4(vertexWorldPos, 1.0);
}
@@ -0,0 +1,15 @@
#version 150 core
in vec2 vPosition;
out vec2 TexCoord;
/**
* This is specifically used by application shaders.
* IE post process or pixel transfer shaders, anything that is rendered using a single rectangle.
*/
void main()
{
gl_Position = vec4(vPosition, 1.0, 1.0);
TexCoord = vPosition.xy * 0.5 + 0.5;
}
@@ -1,9 +1,9 @@
#version 150 core
in uvec4 vPosition;
out vec4 vPos;
in vec4 color;
out vec4 vPos;
out vec4 vertexColor;
out vec3 vertexWorldPos;
out float vertexYPos;
@@ -0,0 +1,86 @@
#version 150 core
in vec2 TexCoord;
out vec4 fragColor;
uniform sampler2D uSourceColorTexture;
uniform sampler2D uSourceDepthTexture;
layout (std140) uniform applyFragUniformBlock
{
vec2 uViewSize;
int uBlurRadius;
float uNearClipPlane; // in blocks
float uFarClipPlane; // in blocks
};
float linearizeDepth(const in float depth) { return (uNearClipPlane * uFarClipPlane) / (depth * (uNearClipPlane - uFarClipPlane) + uFarClipPlane); }
float Gaussian(const in float sigma, const in float x) { return exp(-(x*x) / (2.0 * (sigma*sigma))); }
float BilateralGaussianBlur(const in vec2 texcoord, const in float linearDepth, const in float g_sigmaV)
{
float g_sigmaX = 1.6;
float g_sigmaY = 1.6;
int radius = clamp(uBlurRadius, 1, 3);
vec2 pixelSize = 1.0 / uViewSize;
float accum = 0.0;
float total = 0.0;
for (int iy = -radius; iy <= radius; iy++)
{
float fy = Gaussian(g_sigmaY, iy);
for (int ix = -radius; ix <= radius; ix++)
{
float fx = Gaussian(g_sigmaX, ix);
vec2 sampleTexCoord = texcoord + ivec2(ix, iy) * pixelSize;
float sampleValue = textureLod(uSourceColorTexture, sampleTexCoord, 0).r;
float sampleDepth = textureLod(uSourceDepthTexture, sampleTexCoord, 0).r;
float sampleLinearDepth = linearizeDepth(sampleDepth);
float depthDiff = abs(sampleLinearDepth - linearDepth);
float fv = Gaussian(g_sigmaV, depthDiff);
float weight = fx*fy*fv;
accum += weight * sampleValue;
total += weight;
}
}
if (total <= 1.e-4)
{
return 1.0;
}
return accum / total;
}
void main()
{
fragColor = vec4(1.0);
float fragmentDepth = textureLod(uSourceDepthTexture, TexCoord, 0).r;
// a fragment depth of "1" means the fragment wasn't drawn to,
// we only want to apply SSAO to LODs, not to the sky outside the LODs
if (fragmentDepth < 1)
{
if (uBlurRadius > 0)
{
float fragmentDepthLinear = linearizeDepth(fragmentDepth);
fragColor.a = BilateralGaussianBlur(TexCoord, fragmentDepthLinear, 1.6);
}
else
{
fragColor.a = texelFetch(uSourceColorTexture, ivec2(gl_FragCoord.xy), 0).r;
}
}
}
@@ -0,0 +1,137 @@
#version 150 core
#extension GL_ARB_derivative_control : enable
#define SAMPLE_MAX 64
#define saturate(x) (clamp((x), 0.0, 1.0))
in vec2 TexCoord;
out vec4 fragColor;
layout (std140) uniform fragUniformBlock
{
int uSampleCount;
float uRadius;
float uStrength;
float uMinLight;
float uBias;
float uFadeDistanceInBlocks;
mat4 uInvProj;
mat4 uProj;
};
uniform sampler2D uDhDepthTexture;
const float EPSILON = 1.e-6;
const float GOLDEN_ANGLE = 2.39996323;
const vec3 MAGIC = vec3(0.06711056, 0.00583715, 52.9829189);
const float PI = 3.1415926538;
const float TAU = PI * 2.0;
vec3 unproject(vec4 pos)
{
return pos.xyz / pos.w;
}
float InterleavedGradientNoise(const in vec2 pixel)
{
float x = dot(pixel, MAGIC.xy);
return fract(MAGIC.z * fract(x));
}
vec3 calcViewPosition(const in vec3 clipPos)
{
vec4 viewPos = uInvProj * vec4(clipPos * 2.0 - 1.0, 1.0);
return viewPos.xyz / viewPos.w;
}
float GetSpiralOcclusion(const in vec2 uv, const in vec3 viewPos, const in vec3 viewNormal)
{
float dither = InterleavedGradientNoise(gl_FragCoord.xy);
float rotatePhase = dither * TAU;
float rStep = uRadius / uSampleCount;
vec2 offset;
float ao = 0.0;
int sampleCount = 0;
float radius = rStep;
for (int i = 0; i < clamp(uSampleCount, 1, SAMPLE_MAX); i++) {
vec2 offset = vec2(
sin(rotatePhase),
cos(rotatePhase)
) * radius;
radius += rStep;
rotatePhase += GOLDEN_ANGLE;
vec3 sampleViewPos = viewPos + vec3(offset, -0.1);
vec3 sampleClipPos = unproject(uProj * vec4(sampleViewPos, 1.0)) * 0.5 + 0.5;
sampleClipPos = saturate(sampleClipPos);
float sampleClipDepth = textureLod(uDhDepthTexture, sampleClipPos.xy, 0.0).r;
if (sampleClipDepth >= 1.0 - EPSILON) continue;
sampleClipPos.z = sampleClipDepth;
sampleViewPos = unproject(uInvProj * vec4(sampleClipPos * 2.0 - 1.0, 1.0));
vec3 diff = sampleViewPos - viewPos;
float sampleDist = length(diff);
vec3 sampleNormal = diff / sampleDist;
float sampleNoLm = max(dot(viewNormal, sampleNormal) - uBias, 0.0);
float aoF = 1.0 - saturate(sampleDist / uRadius);
ao += sampleNoLm * aoF;
sampleCount++;
}
ao /= max(sampleCount, 1);
ao = smoothstep(0.0, uStrength, ao);
return ao * (1.0 - uMinLight);
}
void main()
{
float fragmentDepth = textureLod(uDhDepthTexture, TexCoord, 0).r;
float occlusion = 0.0;
// Do not apply to sky
if (fragmentDepth < 1.0)
{
vec3 viewPos = calcViewPosition(vec3(TexCoord, fragmentDepth));
// fading is done to prevent banding/noise
// at super far distance
float distanceFromCamera = length(viewPos);
float fadeDistance = uFadeDistanceInBlocks;
if (distanceFromCamera < fadeDistance)
{
#ifdef GL_ARB_derivative_control
// Get higher precision derivatives when available
vec3 viewNormal = cross(dFdxFine(viewPos.xyz), dFdyFine(viewPos.xyz));
#else
vec3 viewNormal = cross(dFdx(viewPos.xyz), dFdy(viewPos.xyz));
#endif
viewNormal = normalize(viewNormal);
occlusion = GetSpiralOcclusion(TexCoord, viewPos, viewNormal);
// linearly fade with distance
occlusion *= (fadeDistance - distanceFromCamera) / fadeDistance;
}
else
{
// we're out of range, no need to do any SSAO calculations
occlusion = 0.0;
}
}
fragColor = vec4(vec3(1.0 - occlusion), 1.0);
}
@@ -0,0 +1,15 @@
#version 150 core
in vec2 vPosition;
out vec2 TexCoord;
/**
* This is specifically used by application shaders.
* IE post process or pixel transfer shaders, anything that is rendered using a single rectangle.
*/
void main()
{
gl_Position = vec4(vPosition, 1.0, 1.0);
TexCoord = vPosition.xy * 0.5 + 0.5;
}
@@ -0,0 +1,10 @@
#version 150 core
in vec4 fColor;
out vec4 fragColor;
// DH frag test
void main()
{
fragColor = fColor;
}
@@ -0,0 +1,13 @@
#version 150 core
in vec2 vPosition;
in vec4 vColor;
out vec4 fColor;
// DH vert test
void main()
{
gl_Position = vec4(vPosition, 0.0, 1.0);
fColor = vColor;
}
@@ -3,9 +3,7 @@
"package": "com.seibel.distanthorizons.cleanroom.mixins",
"compatibilityLevel": "JAVA_8",
"target": "@env(DEFAULT)",
"mixins": [
"common.MixinChunkProviderServer"
],
"mixins": [],
"minVersion": "0.8.7",
"server": [
"server.MixinEntityPlayerMP"
+12
View File
@@ -0,0 +1,12 @@
[{
"modid": "${mod_id}",
"name": "${mod_name}",
"version": "${mod_version}",
"mcversion": "1.12.2",
"description": "${mod_description}",
"authorList": ["${mod_authors}"],
"credits": "${mod_credits}",
"url": "${mod_url}",
"updateJSON": "${mod_update_json}",
"logoFile": "${mod_logo_path}"
}]
+6
View File
@@ -0,0 +1,6 @@
{
"pack": {
"description": "${mod_name} Resources",
"pack_format": 3
}
}
@@ -1,74 +0,0 @@
#version 150 core
in vec4 vertexColor;
in vec4 vPos;
in vec3 vertexWorldPos;
out vec4 fragColor;
uniform float distanceScale;
uniform int uNoiseSteps;
uniform float uNoiseIntensity;
uniform float uNoiseDropoff;
// The random functions for diffrent dimentions
float rand(float co) { return fract(sin(co*(91.3458)) * 47453.5453); }
float rand(vec2 co){ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); }
float rand(vec3 co){ return rand(co.xy+rand(co.z)); }
// Puts steps in a float
// EG. setting stepSize to 4 then this would be the result of this function
// In: 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, ..., 1.1, 1.2, 1.3
// Out: 0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, ..., 1.0, 1.0, 1.25
float quantize(float val, int stepSize) {
return floor(val*stepSize)/stepSize;
}
vec3 quantize(vec3 val, int stepSize) {
return floor(val*stepSize)/stepSize;
}
/**
* Fragment shader for adding noise to lods.
* This should be passed close to first as it affects the base color of the lod
*
* version: 2023-6-21
*/
void main() {
// This bit of code is required to fix the vertex position problem cus of floats in the verted world position varuable
vec3 vertexNormal = normalize(cross(dFdx(vPos.xyz), dFdy(vPos.xyz)));
vec3 fixedVPos = vPos.xyz - vertexNormal * 0.001;
float noiseAmplification = uNoiseIntensity;
noiseAmplification = (-1 * pow(2*((vertexColor.x + vertexColor.y + vertexColor.z) / 3) - 1, 2) + 1) * noiseAmplification; // Lessen the effect on depending on how dark the object is, equasion for this is -(2x-1)^{2}+1
noiseAmplification *= vertexColor.w; // The effect would lessen on transparent objects
// Random value for each position
float randomValue = rand(quantize(fixedVPos.xyz, uNoiseSteps))
* 2.0 * noiseAmplification - noiseAmplification;
// Modifies the color
// A value of 0 on the randomValue will result in the original color, while a value of 1 will result in a fully bright color
vec3 newCol = (1.0 - vertexColor.rgb) * randomValue;
// Clamps it and turns it back into a vec4
float distA = length(vertexWorldPos) * distanceScale * uNoiseDropoff;
fragColor = clamp(vec4(newCol.rgb, distA), 0.0, 1.0); // The further away it gets, the less noise gets applied
// The further away it gets, the less noise gets applied
fragColor = vec4(0.0, 0.0, 0.0, randomValue);
// For testing
// if (vertexColor.r != 69420.) {
// fragColor = vec4(
// mod(fixedVPos.x, 1),
// mod(fixedVPos.y, 1),
// mod(fixedVPos.z, 1),
// 1f);
// }
}
@@ -1,9 +0,0 @@
#version 150 core
out vec4 fragColor;
// A test shader that makes everything darker
void main()
{
fragColor = vec4(0., 0., 1., 0.5);
}