Add shader loading functionality
[no changelog]
This commit is contained in:
@@ -17,6 +17,11 @@ path = ["src/main/resources/**/*.png", "src/main/resources/**/*.mcmeta"]
|
|||||||
SPDX-License-Identifier = "CC-BY-4.0"
|
SPDX-License-Identifier = "CC-BY-4.0"
|
||||||
SPDX-FileCopyrightText = ["Linnea Gräf <nea@nea.moe>", "Firmament Contributors"]
|
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]]
|
[[annotations]]
|
||||||
path = "src/main/resources/assets/**/lang/*.json"
|
path = "src/main/resources/assets/**/lang/*.json"
|
||||||
SPDX-License-Identifier = "CC0-1.0"
|
SPDX-License-Identifier = "CC0-1.0"
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/main/kotlin/events/RegisterCustomShadersEvent.kt
Normal file
24
src/main/kotlin/events/RegisterCustomShadersEvent.kt
Normal file
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/main/kotlin/util/render/FirmamentShaders.kt
Normal file
23
src/main/kotlin/util/render/FirmamentShaders.kt
Normal file
@@ -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 },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,7 +56,7 @@ class RenderInWorldContext private constructor(
|
|||||||
false, false, // do we need translucent? i dont think so
|
false, false, // do we need translucent? i dont think so
|
||||||
RenderLayer.MultiPhaseParameters.builder()
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||||
.program(RenderPhase.LINES_PROGRAM)
|
.program(FirmamentShaders.LINES)
|
||||||
.build(false)
|
.build(false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ class RenderInWorldContext private constructor(
|
|||||||
points.zipWithNext().forEach { (a, b) ->
|
points.zipWithNext().forEach { (a, b) ->
|
||||||
val normal = Vector3f(b.x.toFloat(), b.y.toFloat(), b.z.toFloat())
|
val normal = Vector3f(b.x.toFloat(), b.y.toFloat(), b.z.toFloat())
|
||||||
.sub(a.x.toFloat(), a.y.toFloat(), a.z.toFloat())
|
.sub(a.x.toFloat(), a.y.toFloat(), a.z.toFloat())
|
||||||
.normalize()
|
// .normalize()
|
||||||
val lastNormal0 = lastNormal ?: normal
|
val lastNormal0 = lastNormal ?: normal
|
||||||
lastNormal = normal
|
lastNormal = normal
|
||||||
buffer.vertex(matrix.positionMatrix, a.x.toFloat(), a.y.toFloat(), a.z.toFloat())
|
buffer.vertex(matrix.positionMatrix, a.x.toFloat(), a.y.toFloat(), a.z.toFloat())
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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 ] }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user