Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
feat: Add custom uniforms to Nvidium's scene data using the render pi…
Browse files Browse the repository at this point in the history
…peline
  • Loading branch information
Steveplays28 committed Jan 17, 2024
1 parent 628c46a commit bed48a8
Show file tree
Hide file tree
Showing 19 changed files with 193 additions and 43 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ dependencies {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

// Mixin Extras
include(implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:${project.mixin_extras_version}")))

// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"

Expand Down
6 changes: 3 additions & 3 deletions docs/nvidium/shaders/occlusion/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ layout(std140, binding=0) uniform SceneData {
float fogEnd;
bool isCylindricalFog;

// Blendium: the fragment distance
float v_FragDistance;

//align(2)
uint16_t regionCount;//Number of regions in regionIndicies
//align(1)
uint8_t frameId;

int u_Far; // Blendium: the view distance
float u_ViewDistanceFactor; // Blendium: the view distance blend factor
};
3 changes: 3 additions & 0 deletions docs/nvidium/shaders/terrain/frag.frag
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ layout(location = 1) in Interpolants {
f16vec4 uv_bias_cutoff;
f16vec3 tint;
f16vec3 addin;
// Blendium: the fragment distance
float16_t v_FragDistance;
};


layout(binding = 0) uniform sampler2D tex_diffuse;

uniform int u_Far; // Blendium: the view distance
uniform float u_ViewDistanceFactor; // Blendium: the view distance blend factor

Expand Down
9 changes: 4 additions & 5 deletions docs/nvidium/shaders/terrain/mesh.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ layout(location=1) out Interpolants {
f16vec4 uv_bias_cutoff;
f16vec3 tint;
f16vec3 addin;
// Blendium: the fragment distance
float16_t v_FragDistance;
} OUT[];

taskNV in Task {
Expand Down Expand Up @@ -73,11 +75,8 @@ void emitVertex(uint vertexBaseId, uint innerId) {
tint *= sampleLight(decodeLightUV(V));
tint *= tint.w;

if (isCylindricalFog) {
v_FragDistance = max(length(pos.xz), abs(pos.y));
} else {
v_FragDistance = length(pos);
}
// Blendium: calculate the fragment distance
OUT[outId].v_FragDistance = (float16_t) getFragDistance(isCylindricalFog, pos+subchunkOffset.xyz);

vec3 tintO;
vec3 addiO;
Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=true
org.gradle.caching=true

# Fabric Properties
# Fabric properties
# Check these on https://modmuss50.me/fabric.html
minecraft_version=1.20.1
yarn_mappings=1.20.1+build.10
Expand All @@ -17,6 +17,7 @@ archives_base_name=blendium
supported_minecraft_version=1.20.x

# Dependencies
mixin_extras_version=0.2.2
fabric_api_version=0.91.0+1.20.1
modmenu_version=7.2.1
sodium_version=mc1.20.1-0.5.3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public static void saveConfig() {
modifiedShaderSourceCode = insertCodeInMain(modifiedShaderSourceCode, """
// Blendium: blend the alpha of the blocks
float far = u_Far * 16.0;
out_FragColor.a *= 1.0 - smoothstep(u_ViewDistanceFactor * far, far, v_FragDistance);""");
out_FragColor.a *= 1.0 - smoothstep(u_ViewDistanceFactor * far, far, v_FragDistance);
""");

if (config.debug) {
BlendiumClient.LOGGER.info("Original Sodium shader source code:\n{}", shaderSourceCode);
Expand All @@ -88,19 +89,29 @@ public static void saveConfig() {
return modifiedShaderSourceCode;
}

public static @NotNull String injectNvidiumSceneDataShaderCode(String shaderSourceCode) {
var modifiedShaderSourceCode = insertCodeAfterCode(shaderSourceCode, "uint8_t frameId;", """
int u_Far; // Blendium: the view distance
float u_ViewDistanceFactor; // Blendium: the view distance blend factor
""");

// if (config.debug) {
BlendiumClient.LOGGER.info("Original Nvidium shader source code:\n{}", shaderSourceCode);
BlendiumClient.LOGGER.info("Modified Nvidium shader source code:\n{}", modifiedShaderSourceCode);
// }

return modifiedShaderSourceCode;
}

public static @NotNull String injectNvidiumMeshVertexShaderCode(String shaderSourceCode) {
// Insert a custom uniform into the scene data, which is merged into both the mesh vertex shader and the fragment shader
var modifiedShaderSourceCode = insertCodeAfterCode(shaderSourceCode, "bool isCylindricalFog;", """
var modifiedShaderSourceCode = insertCodeAfterCode(shaderSourceCode, "out Interpolants {", """
// Blendium: the fragment distance
float v_FragDistance;
float16_t v_FragDistance;
""");
modifiedShaderSourceCode = insertCodeAfterCode(modifiedShaderSourceCode, "tint *= tint.w;", """
// Blendium: calculate the fragment distance
if (isCylindricalFog) {
v_FragDistance = max(length(pos.xz), abs(pos.y));
} else {
v_FragDistance = length(pos);
}""");
OUT[outId].v_FragDistance = (float16_t) getFragDistance(isCylindricalFog, pos+subchunkOffset.xyz);
""");

// if (config.debug) {
BlendiumClient.LOGGER.info("Original Nvidium shader source code:\n{}", shaderSourceCode);
Expand All @@ -111,14 +122,16 @@ public static void saveConfig() {
}

public static @NotNull String injectNvidiumFragmentShaderCode(String shaderSourceCode) {
var modifiedShaderSourceCode = insertCodeAfterCode(shaderSourceCode, "layout(location = 0) out vec4 colour;", """
uniform int u_Far; // Blendium: the view distance
uniform float u_ViewDistanceFactor; // Blendium: the view distance blend factor
var modifiedShaderSourceCode = insertCodeAfterCode(shaderSourceCode, "in Interpolants {", """
// Blendium: the fragment distance
float16_t v_FragDistance;
""");
modifiedShaderSourceCode = insertCodeInMain(modifiedShaderSourceCode, """
// Blendium: blend the alpha of the blocks
float far = u_Far * 16.0;
colour.a *= 1.0 - smoothstep(u_ViewDistanceFactor * far, far, v_FragDistance);""");
colour.a *= smoothstep(u_ViewDistanceFactor * far, far, v_FragDistance);
colour.a = u_ViewDistanceFactor;
""");

// if (config.debug) {
BlendiumClient.LOGGER.info("Original Nvidium shader source code:\n{}", shaderSourceCode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,15 @@ public class BlendiumMixinPlugin implements IMixinConfigPlugin {
"io.github.steveplays28.blendium.mixin.sodium.ShaderLoaderMixin",
() -> FabricLoader.getInstance().isModLoaded(SODIUM_MOD_ID),
"io.github.steveplays28.blendium.mixin.iris.IrisMixin",
() -> FabricLoader.getInstance().isModLoaded(IRIS_SHADERS_MOD_ID)
() -> FabricLoader.getInstance().isModLoaded(IRIS_SHADERS_MOD_ID),
"io.github.steveplays28.blendium.mixin.nvidium.NvidiumPrimaryAndTemporalTerrainRasterizerMixin",
() -> FabricLoader.getInstance().isModLoaded(NVIDIUM_MOD_ID),
"io.github.steveplays28.blendium.mixin.nvidium.NvidiumRenderPipelineMixin",
() -> FabricLoader.getInstance().isModLoaded(NVIDIUM_MOD_ID),
"io.github.steveplays28.blendium.mixin.nvidium.NvidiumShaderLoaderMixin",
() -> FabricLoader.getInstance().isModLoaded(NVIDIUM_MOD_ID),
"io.github.steveplays28.blendium.mixin.sodium.SodiumShaderParserMixin",
() -> FabricLoader.getInstance().isModLoaded(SODIUM_MOD_ID) && FabricLoader.getInstance().isModLoaded(NVIDIUM_MOD_ID)
);

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.github.steveplays28.blendium.mixin;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.block.FernBlock;
import net.minecraft.block.LeavesBlock;
Expand All @@ -13,6 +15,7 @@

import static net.minecraft.client.render.RenderLayer.getTranslucent;

@Environment(EnvType.CLIENT)
@Mixin(RenderLayers.class)
public class RenderLayersMixin {
@Inject(method = "getBlockLayer", at = @At(value = "HEAD"), cancellable = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
import io.github.steveplays28.blendium.client.compat.iris.BlendiumDhShaderpackPresets;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import org.joml.Vector3f;
Expand All @@ -18,6 +20,7 @@
import static io.github.steveplays28.blendium.client.BlendiumClient.IRIS_SHADERS_MOD_ID;
import static io.github.steveplays28.blendium.client.BlendiumClient.config;

@Environment(EnvType.CLIENT)
@Mixin(LodRenderProgram.class)
public class LodRenderProgramMixin extends ShaderProgram {
@Unique
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.github.steveplays28.blendium.mixin.distanthorizons;

import com.seibel.distanthorizons.core.render.glObject.shader.Shader;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -9,6 +11,7 @@

import static io.github.steveplays28.blendium.client.BlendiumClient.*;

@Environment(EnvType.CLIENT)
@Mixin(Shader.class)
public class ShaderMixin {
@Inject(method = "loadFile", at = @At(value = "RETURN"), remap = false, cancellable = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package io.github.steveplays28.blendium.mixin.iris;

import net.coderbot.iris.Iris;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import static io.github.steveplays28.blendium.client.compat.iris.BlendiumDhShaderpackPresets.applyDhShaderpackPreset;

@Environment(EnvType.CLIENT)
@Mixin(Iris.class)
public class IrisMixin {
@Inject(method = "loadShaderpack", at = @At(value = "TAIL"), remap = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.github.steveplays28.blendium.mixin.nvidium;

import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import me.cortex.nvidium.renderers.PrimaryTerrainRasterizer;
import me.cortex.nvidium.renderers.TemporalTerrainRasterizer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Environment(EnvType.CLIENT)
@Mixin(value = {PrimaryTerrainRasterizer.class, TemporalTerrainRasterizer.class}, remap = false)
public class NvidiumPrimaryAndTemporalTerrainRasterizerMixin {
@Inject(method = "raster", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/NVMeshShader;glMultiDrawMeshTasksIndirectNV(JII)V"))
private void blendium$rasterBlendFuncInject(int regionCount, long commandAddr, CallbackInfo ci) {
RenderSystem.blendFuncSeparate(GlStateManager.SrcFactor.SRC_ALPHA.value, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA.value,
GlStateManager.SrcFactor.ONE.value, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA.value
);
RenderSystem.enableBlend();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.github.steveplays28.blendium.mixin.nvidium;

import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.ref.LocalLongRef;
import me.cortex.nvidium.RenderPipeline;
import me.cortex.nvidium.gl.RenderDevice;
import me.cortex.nvidium.managers.SectionManager;
import me.cortex.nvidium.util.DownloadTaskStream;
import me.cortex.nvidium.util.UploadingBufferStream;
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderMatrices;
import me.jellysquid.mods.sodium.client.render.viewport.Viewport;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import static io.github.steveplays28.blendium.client.BlendiumClient.config;

@Environment(EnvType.CLIENT)
@Mixin(value = RenderPipeline.class, remap = false)
public class NvidiumRenderPipelineMixin {
@Mutable
@Shadow
@Final
private static int SCENE_SIZE;

@Unique
private static final int INT_UNIFORM_SIZE_BYTES = 4;
@Unique
private static final int FLOAT_UNIFORM_SIZE_BYTES = 4;

@Inject(method = "<init>", at = @At("TAIL"))
private void blendium$constructorInject(RenderDevice device, UploadingBufferStream uploadStream, DownloadTaskStream downloadStream, SectionManager sectionManager, CallbackInfo ci) {
SCENE_SIZE += INT_UNIFORM_SIZE_BYTES * FLOAT_UNIFORM_SIZE_BYTES;
}

@Inject(method = "renderFrame", at = @At(value = "INVOKE", target = "Lorg/lwjgl/system/MemoryUtil;memPutByte(JB)V", ordinal = 0, shift = At.Shift.BEFORE))
private void blendium$renderFrameSetUniformsInject(Viewport frustum, ChunkRenderMatrices crm, double px, double py, double pz, CallbackInfo ci, @Local(ordinal = 1) LocalLongRef addr) {
// u_Far
MemoryUtil.memPutInt(addr.get(), MinecraftClient.getInstance().options.getClampedViewDistance());
addr.set(addr.get() + INT_UNIFORM_SIZE_BYTES);

// u_ViewDistanceFactor
MemoryUtil.memPutFloat(addr.get(), config.viewDistanceFactor);
addr.set(addr.get() + FLOAT_UNIFORM_SIZE_BYTES);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,26 @@
@Mixin(ShaderLoader.class)
public class NvidiumShaderLoaderMixin {
@Unique
private static final String FRAGMENT_SHADER_NAME = "frag.frag";
private static final String SCENE_DATA_SHADER_PATH = "occlusion/scene.glsl";
@Unique
private static final String MESH_VERTEX_SHADER_NAME = "mesh.glsl";
private static final String MESH_VERTEX_SHADER_PATH = "terrain/mesh.glsl";
@Unique
private static final String TRANSLUCENT_MESH_VERTEX_SHADER_PATH = "terrain/translucent/mesh.glsl";
@Unique
private static final String FRAGMENT_SHADER_PATH = "terrain/frag.frag";
@Unique
private static final String TRANSLUCENT_FRAGMENT_SHADER_PATH = "terrain/translucent/frag.frag";

@Inject(method = "parse", at = @At(value = "RETURN"), cancellable = true)
private static void parseInject(@NotNull Identifier path, @NotNull CallbackInfoReturnable<String> cir) {
String[] splitPath = path.toString().split("/");
String shaderFileName = splitPath[splitPath.length - 1];

switch (shaderFileName) {
case MESH_VERTEX_SHADER_NAME -> {
switch (path.getPath()) {
case MESH_VERTEX_SHADER_PATH, TRANSLUCENT_MESH_VERTEX_SHADER_PATH -> {
var originalShaderSourceCode = cir.getReturnValue();
var modifiedShaderSourceCode = injectNvidiumMeshVertexShaderCode(originalShaderSourceCode);

cir.setReturnValue(modifiedShaderSourceCode);
}
case FRAGMENT_SHADER_NAME -> {
case FRAGMENT_SHADER_PATH, TRANSLUCENT_FRAGMENT_SHADER_PATH -> {
var originalShaderSourceCode = cir.getReturnValue();
var modifiedShaderSourceCode = injectNvidiumFragmentShaderCode(originalShaderSourceCode);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@
import static io.github.steveplays28.blendium.client.BlendiumClient.*;

@Environment(EnvType.CLIENT)
@Mixin(ChunkShaderFogComponent.Smooth.class)
@Mixin(value = ChunkShaderFogComponent.Smooth.class, remap = false)
public class ChunkShaderFogComponentSmoothMixin {
@Unique
private GlUniformInt uFar;
@Unique
private GlUniformFloat uViewDistanceFactor;

@Inject(method = "<init>", at = @At(value = "TAIL"), remap = false)
@Inject(method = "<init>", at = @At(value = "TAIL"))
public void constructorInject(@NotNull ShaderBindingContext context, CallbackInfo ci) {
this.uFar = context.bindUniform(U_FAR_NAME, GlUniformInt::new);
this.uViewDistanceFactor = context.bindUniform(U_VIEW_DISTANCE_FACTOR_NAME, GlUniformFloat::new);
}

@Inject(method = "setup", at = @At(value = "TAIL"), remap = false)
@Inject(method = "setup", at = @At(value = "TAIL"))
public void setupInject(CallbackInfo ci) {
this.uFar.set(MinecraftClient.getInstance().options.getClampedViewDistance());
this.uViewDistanceFactor.set(config.viewDistanceFactor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Environment(EnvType.CLIENT)
@Mixin(DefaultChunkRenderer.class)
@Mixin(value = DefaultChunkRenderer.class, remap = false)
public class DefaultChunkRendererMixin {
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/gl/shader/GlProgram;getInterface()Ljava/lang/Object;"), remap = false)
public void createShaderInject(ChunkRenderMatrices matrices, CommandList commandList, ChunkRenderListIterable renderLists, TerrainRenderPass renderPass, CameraTransform camera, CallbackInfo ci) {
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/gl/shader/GlProgram;getInterface()Ljava/lang/Object;"))
public void blendium$renderCreateShaderInject(ChunkRenderMatrices matrices, CommandList commandList, ChunkRenderListIterable renderLists, TerrainRenderPass renderPass, CameraTransform camera, CallbackInfo ci) {
RenderSystem.blendFuncSeparate(GlStateManager.SrcFactor.SRC_ALPHA.value, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA.value,
GlStateManager.SrcFactor.ONE.value, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA.value
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import static io.github.steveplays28.blendium.client.BlendiumClient.injectSodiumFragmentShaderCode;

@Environment(EnvType.CLIENT)
@Mixin(ShaderLoader.class)
@Mixin(value = ShaderLoader.class, remap = false)
public class SodiumShaderLoaderMixin {
@Unique
private static final String FRAGMENT_SHADER_NAME = "block_layer_opaque.fsh";
Expand Down
Loading

0 comments on commit bed48a8

Please sign in to comment.