aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--REUSE.toml5
-rw-r--r--src/main/java/moe/nea/firmament/mixins/InjectCustomShaderPrograms.java31
-rw-r--r--src/main/kotlin/events/RegisterCustomShadersEvent.kt24
-rw-r--r--src/main/kotlin/util/render/FirmamentShaders.kt23
-rw-r--r--src/main/kotlin/util/render/RenderInWorldContext.kt4
-rw-r--r--src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.fsh18
-rw-r--r--src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.json17
-rw-r--r--src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.vsh62
8 files changed, 182 insertions, 2 deletions
diff --git a/REUSE.toml b/REUSE.toml
index 1cafccf..b5bd945 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -18,6 +18,11 @@ SPDX-License-Identifier = "CC-BY-4.0"
SPDX-FileCopyrightText = ["Linnea Gräf <nea@nea.moe>", "Firmament Contributors"]
[[annotations]]
+path = ["src/main/resources/assets/minecraft/shaders/core/**/*"]
+SPDX-License-Identifier = "GPL-3.0-or-later"
+SPDX-FileCopyrightText = ["Linnea Gräf <nea@nea.moe>", "Firmament Contributors"]
+
+[[annotations]]
path = "src/main/resources/assets/**/lang/*.json"
SPDX-License-Identifier = "CC0-1.0"
SPDX-FileCopyrightText = ["Linnea Gräf <nea@nea.moe>", "Firmament Contributors"]
diff --git a/src/main/java/moe/nea/firmament/mixins/InjectCustomShaderPrograms.java b/src/main/java/moe/nea/firmament/mixins/InjectCustomShaderPrograms.java
new file mode 100644
index 0000000..5306e42
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/InjectCustomShaderPrograms.java
@@ -0,0 +1,31 @@
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
+import com.mojang.datafixers.util.Pair;
+import moe.nea.firmament.events.RegisterCustomShadersEvent;
+import net.minecraft.client.gl.ShaderProgram;
+import net.minecraft.client.render.GameRenderer;
+import net.minecraft.resource.ResourceFactory;
+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 java.util.List;
+import java.util.function.Consumer;
+
+@Mixin(GameRenderer.class)
+public class InjectCustomShaderPrograms {
+
+ @Inject(method = "loadPrograms",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;loadBlurPostProcessor(Lnet/minecraft/resource/ResourceFactory;)V",
+ shift = At.Shift.AFTER))
+ void addFirmamentShaders(
+ ResourceFactory resourceFactory, CallbackInfo ci,
+ @Local(index = 3) List<Pair<ShaderProgram, Consumer<ShaderProgram>>> list
+ ) {
+ var event = new RegisterCustomShadersEvent(list, resourceFactory);
+ RegisterCustomShadersEvent.Companion.publish(event);
+ }
+}
diff --git a/src/main/kotlin/events/RegisterCustomShadersEvent.kt b/src/main/kotlin/events/RegisterCustomShadersEvent.kt
new file mode 100644
index 0000000..2f6d1f8
--- /dev/null
+++ b/src/main/kotlin/events/RegisterCustomShadersEvent.kt
@@ -0,0 +1,24 @@
+package moe.nea.firmament.events
+
+import com.mojang.datafixers.util.Pair
+import java.util.function.Consumer
+import net.minecraft.client.gl.ShaderProgram
+import net.minecraft.client.render.VertexFormat
+import net.minecraft.resource.ResourceFactory
+import moe.nea.firmament.Firmament
+
+data class RegisterCustomShadersEvent(
+ val list: MutableList<Pair<ShaderProgram, Consumer<ShaderProgram>>>,
+ val resourceFactory: ResourceFactory,
+) : FirmamentEvent() {
+ companion object : FirmamentEventBus<RegisterCustomShadersEvent>()
+
+ fun register(name: String, vertexFormat: VertexFormat, saver: Consumer<ShaderProgram>) {
+ require(name.startsWith("firmament_"))
+ try {
+ list.add(Pair.of(ShaderProgram(resourceFactory, name, vertexFormat), saver))
+ } catch (ex: Exception) {
+ Firmament.logger.fatal("Could not load firmament shader $name", ex)
+ }
+ }
+}
diff --git a/src/main/kotlin/util/render/FirmamentShaders.kt b/src/main/kotlin/util/render/FirmamentShaders.kt
new file mode 100644
index 0000000..1094bc2
--- /dev/null
+++ b/src/main/kotlin/util/render/FirmamentShaders.kt
@@ -0,0 +1,23 @@
+package moe.nea.firmament.util.render
+
+import net.minecraft.client.gl.ShaderProgram
+import net.minecraft.client.render.RenderPhase
+import net.minecraft.client.render.VertexFormats
+import moe.nea.firmament.annotations.Subscribe
+import moe.nea.firmament.events.RegisterCustomShadersEvent
+
+object FirmamentShaders {
+
+
+ private lateinit var _LINES: ShaderProgram
+ val LINES = RenderPhase.ShaderProgram({ _LINES })
+
+ @Subscribe
+ fun registerCustomShaders(event: RegisterCustomShadersEvent) {
+ event.register(
+ "firmament_rendertype_lines",
+ VertexFormats.LINES,
+ { _LINES = it },
+ )
+ }
+}
diff --git a/src/main/kotlin/util/render/RenderInWorldContext.kt b/src/main/kotlin/util/render/RenderInWorldContext.kt
index 775e8f3..75f2fad 100644
--- a/src/main/kotlin/util/render/RenderInWorldContext.kt
+++ b/src/main/kotlin/util/render/RenderInWorldContext.kt
@@ -56,7 +56,7 @@ class RenderInWorldContext private constructor(
false, false, // do we need translucent? i dont think so
RenderLayer.MultiPhaseParameters.builder()
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
- .program(RenderPhase.LINES_PROGRAM)
+ .program(FirmamentShaders.LINES)
.build(false)
)
}
@@ -172,7 +172,7 @@ class RenderInWorldContext private constructor(
points.zipWithNext().forEach { (a, b) ->
val normal = Vector3f(b.x.toFloat(), b.y.toFloat(), b.z.toFloat())
.sub(a.x.toFloat(), a.y.toFloat(), a.z.toFloat())
- .normalize()
+// .normalize()
val lastNormal0 = lastNormal ?: normal
lastNormal = normal
buffer.vertex(matrix.positionMatrix, a.x.toFloat(), a.y.toFloat(), a.z.toFloat())
diff --git a/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.fsh b/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.fsh
new file mode 100644
index 0000000..057f31f
--- /dev/null
+++ b/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.fsh
@@ -0,0 +1,18 @@
+#version 150
+
+#moj_import <fog.glsl>
+
+uniform vec4 ColorModulator;
+uniform float FogStart;
+uniform float FogEnd;
+uniform vec4 FogColor;
+
+in float vertexDistance;
+in vec4 vertexColor;
+
+out vec4 fragColor;
+
+void main() {
+ vec4 color = vertexColor * ColorModulator;
+ fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
+}
diff --git a/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.json b/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.json
new file mode 100644
index 0000000..0828480
--- /dev/null
+++ b/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.json
@@ -0,0 +1,17 @@
+{
+ "vertex": "firmament_rendertype_lines",
+ "fragment": "firmament_rendertype_lines",
+ "samplers": [
+ ],
+ "uniforms": [
+ { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
+ { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
+ { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
+ { "name": "LineWidth", "type": "float", "count": 1, "values": [ 1.0 ] },
+ { "name": "ScreenSize", "type": "float", "count": 2, "values": [ 1.0, 1.0 ] },
+ { "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] },
+ { "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] },
+ { "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] },
+ { "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] }
+ ]
+}
diff --git a/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.vsh b/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.vsh
new file mode 100644
index 0000000..35892be
--- /dev/null
+++ b/src/main/resources/assets/minecraft/shaders/core/firmament_rendertype_lines.vsh
@@ -0,0 +1,62 @@
+#version 150
+
+#moj_import <fog.glsl>
+
+in vec3 Position;
+in vec4 Color;
+in vec3 Normal;
+
+uniform mat4 ModelViewMat;
+uniform mat4 ProjMat;
+uniform float LineWidth;
+uniform vec2 ScreenSize;
+uniform int FogShape;
+
+out float vertexDistance;
+out vec4 vertexColor;
+
+const float VIEW_SHRINK = 1.0 - (1.0 / 256.0);
+const mat4 VIEW_SCALE = mat4(
+ VIEW_SHRINK, 0.0, 0.0, 0.0,
+ 0.0, VIEW_SHRINK, 0.0, 0.0,
+ 0.0, 0.0, VIEW_SHRINK, 0.0,
+ 0.0, 0.0, 0.0, 1.0
+);
+
+void main() {
+ vec4 linePosStart = ProjMat * VIEW_SCALE * ModelViewMat * vec4(Position, 1.0);
+ vec4 linePosEnd = ProjMat * VIEW_SCALE * ModelViewMat * vec4(Position + Normal, 1.0);
+
+ vec3 ndc1 = linePosStart.xyz / linePosStart.w;
+ vec3 ndc2 = linePosEnd.xyz / linePosEnd.w;
+
+ bool linePosStartBehind = ndc1.z <= -1;
+ bool linePosEndBehind = ndc2.z <= -1;
+
+ if ((linePosStartBehind && linePosEndBehind)) {
+ gl_Position = vec4(-2.0, -2.0, -2.0, 1.0);
+ return; // I don't care for these people
+ }
+ if (linePosStartBehind || linePosEndBehind) {
+ ndc1.z = 0.0;
+ ndc2.z = 0.0;
+ linePosStart.w = 1.0;
+ // TODO: use mx + b to find move the two coordinates around to extend lines
+ }
+
+ vec2 lineScreenDirection = normalize((ndc2.xy - ndc1.xy) * ScreenSize);
+ vec2 lineOffset = vec2(-lineScreenDirection.y, lineScreenDirection.x) * LineWidth / ScreenSize;
+
+ if (lineOffset.x < 0.0) {
+ lineOffset *= -1.0;
+ }
+
+ if (gl_VertexID % 2 == 0) {
+ gl_Position = vec4((ndc1 + vec3(lineOffset, 0.0)) * linePosStart.w, linePosStart.w);
+ } else {
+ gl_Position = vec4((ndc1 - vec3(lineOffset, 0.0)) * linePosStart.w, linePosStart.w);
+ }
+
+ vertexDistance = fog_distance(Position, FogShape);
+ vertexColor = Color;
+}