mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-24 11:57:54 +01:00
In the right direction
- Use vanilla light directions for diffuse lighting - Copy mc's glsl code for it, but assume directions are normalized - Add command/config to toggle use of light directions vs chunk accurate diffuse - Always use shade in getItemMaterial - Do not reload resource packs when updating light smoothness config, we don't need to anymore with lazy compilation
This commit is contained in:
parent
22b5676e47
commit
40577420d5
13 changed files with 146 additions and 12 deletions
|
@ -11,4 +11,6 @@ public interface BackendConfig {
|
|||
* @return The current light smoothness setting.
|
||||
*/
|
||||
LightSmoothness lightSmoothness();
|
||||
|
||||
boolean useLightDirections();
|
||||
}
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
package dev.engine_room.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import dev.engine_room.flywheel.api.RenderContext;
|
||||
import dev.engine_room.flywheel.backend.BackendConfig;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public final class LevelUniforms extends UniformWriter {
|
||||
private static final int SIZE = 16 * 2 + 4 * 13;
|
||||
private static final int SIZE = 16 * 4 + 4 * 13;
|
||||
static final UniformBuffer BUFFER = new UniformBuffer(Uniforms.LEVEL_INDEX, SIZE);
|
||||
|
||||
public static final Vector3f LIGHT0_DIRECTION = new Vector3f();
|
||||
public static final Vector3f LIGHT1_DIRECTION = new Vector3f();
|
||||
|
||||
private LevelUniforms() {
|
||||
}
|
||||
|
||||
|
@ -24,6 +30,9 @@ public final class LevelUniforms extends UniformWriter {
|
|||
ptr = writeVec4(ptr, (float) skyColor.x, (float) skyColor.y, (float) skyColor.z, 1f);
|
||||
ptr = writeVec4(ptr, (float) cloudColor.x, (float) cloudColor.y, (float) cloudColor.z, 1f);
|
||||
|
||||
ptr = writeVec3(ptr, LIGHT0_DIRECTION);
|
||||
ptr = writeVec3(ptr, LIGHT1_DIRECTION);
|
||||
|
||||
long dayTime = level.getDayTime();
|
||||
long levelDay = dayTime / 24000L;
|
||||
float timeOfDay = (float) (dayTime - levelDay * 24000L) / 24000f;
|
||||
|
@ -46,6 +55,8 @@ public final class LevelUniforms extends UniformWriter {
|
|||
|
||||
ptr = writeInt(ptr, level.effects().constantAmbientLight() ? 1 : 0);
|
||||
|
||||
ptr = writeInt(ptr, BackendConfig.INSTANCE.useLightDirections() ? 1 : 0);
|
||||
|
||||
// TODO: use defines for custom dimension ids
|
||||
int dimensionId;
|
||||
ResourceKey<Level> dimension = level.dimension();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package dev.engine_room.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3fc;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import dev.engine_room.flywheel.lib.util.ExtraMemoryOps;
|
||||
|
@ -37,6 +38,10 @@ class UniformWriter {
|
|||
return ptr + 16;
|
||||
}
|
||||
|
||||
static long writeVec3(long ptr, Vector3fc vec) {
|
||||
return writeVec3(ptr, vec.x(), vec.y(), vec.z());
|
||||
}
|
||||
|
||||
static long writeVec4(long ptr, float x, float y, float z, float w) {
|
||||
MemoryUtil.memPutFloat(ptr, x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, y);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package dev.engine_room.flywheel.backend.mixin;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
@ -7,6 +9,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
import dev.engine_room.flywheel.backend.engine.uniform.LevelUniforms;
|
||||
import dev.engine_room.flywheel.backend.gl.GlStateTracker;
|
||||
import dev.engine_room.flywheel.backend.gl.buffer.GlBufferType;
|
||||
|
||||
|
@ -26,4 +29,12 @@ abstract class GlStateManagerMixin {
|
|||
private static void flywheel$onUseProgram(int program, CallbackInfo ci) {
|
||||
GlStateTracker._setProgram(program);
|
||||
}
|
||||
|
||||
@Inject(method = "setupLevelDiffuseLighting", at = @At("HEAD"))
|
||||
private static void flywheel$onSetupLevelDiffuseLighting(Vector3f vector3f, Vector3f vector3f2, Matrix4f matrix4f, CallbackInfo ci) {
|
||||
// Capture the light directions before they're transformed into screen space
|
||||
// Basically all usages of assigning light direction go through here so I think this is safe
|
||||
LevelUniforms.LIGHT0_DIRECTION.set(vector3f);
|
||||
LevelUniforms.LIGHT1_DIRECTION.set(vector3f2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,14 @@ out vec4 _flw_outputColor;
|
|||
|
||||
float _flw_diffuseFactor() {
|
||||
if (flw_material.diffuse) {
|
||||
if (flw_constantAmbientLight == 1u) {
|
||||
return diffuseNether(flw_vertexNormal);
|
||||
if (flw_useLightDirections == 1u) {
|
||||
return diffuseFromLightDirections(flw_vertexNormal);
|
||||
} else {
|
||||
return diffuse(flw_vertexNormal);
|
||||
if (flw_constantAmbientLight == 1u) {
|
||||
return diffuseNether(flw_vertexNormal);
|
||||
} else {
|
||||
return diffuse(flw_vertexNormal);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 1.;
|
||||
|
|
|
@ -7,3 +7,11 @@ float diffuseNether(vec3 normal) {
|
|||
vec3 n2 = normal * normal * vec3(.6, .9, .8);
|
||||
return min(n2.x + n2.y + n2.z, 1.);
|
||||
}
|
||||
|
||||
float diffuseFromLightDirections(vec3 normal) {
|
||||
// We assume the directions are normalized before upload.
|
||||
float light0 = max(0.0, dot(flw_light0Direction, normal));
|
||||
float light1 = max(0.0, dot(flw_light1Direction, normal));
|
||||
return min(1.0, (light0 + light1) * 0.6 + 0.4);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@ layout(std140) uniform _FlwLevelUniforms {
|
|||
vec4 flw_skyColor;
|
||||
vec4 flw_cloudColor;
|
||||
|
||||
vec4 _flw_light0Direction;
|
||||
vec4 _flw_light1Direction;
|
||||
|
||||
/** The current day number of the level. */
|
||||
uint flw_levelDay;
|
||||
/** The current fraction of the current day that has elapsed. */
|
||||
|
@ -23,11 +26,15 @@ layout(std140) uniform _FlwLevelUniforms {
|
|||
float flw_skyDarken;
|
||||
|
||||
uint flw_constantAmbientLight;
|
||||
uint flw_useLightDirections;
|
||||
|
||||
/** Use FLW_DIMENSION_* ids to determine the dimension. May eventually be implemented for custom dimensions. */
|
||||
uint flw_dimension;
|
||||
};
|
||||
|
||||
#define flw_light0Direction (_flw_light0Direction.xyz)
|
||||
#define flw_light1Direction (_flw_light1Direction.xyz)
|
||||
|
||||
#define FLW_DIMENSION_OVERWORLD 0
|
||||
#define FLW_DIMENSION_NETHER 1
|
||||
#define FLW_DIMENSION_END 2
|
||||
|
|
|
@ -50,15 +50,15 @@ public final class ModelUtil {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
public static Material getItemMaterial(RenderType renderType, boolean shaded) {
|
||||
var chunkMaterial = getMaterial(renderType, shaded);
|
||||
public static Material getItemMaterial(RenderType renderType) {
|
||||
var chunkMaterial = getMaterial(renderType, true);
|
||||
|
||||
if (chunkMaterial != null) {
|
||||
return chunkMaterial;
|
||||
}
|
||||
|
||||
if (renderType == Sheets.translucentCullBlockSheet() || renderType == Sheets.translucentItemSheet()) {
|
||||
return shaded ? Materials.CUTOUT_BLOCK : Materials.CUTOUT_UNSHADED_BLOCK;
|
||||
return Materials.CUTOUT_BLOCK;
|
||||
}
|
||||
if (renderType == RenderType.glint() || renderType == RenderType.glintDirect()) {
|
||||
return Materials.GLINT;
|
||||
|
|
|
@ -6,5 +6,9 @@
|
|||
"command.flywheel.limit_updates.get.off": "Update limiting is currently disabled",
|
||||
"command.flywheel.limit_updates.get.on": "Update limiting is currently enabled",
|
||||
"command.flywheel.limit_updates.set.off": "Update limiting is now disabled",
|
||||
"command.flywheel.limit_updates.set.on": "Update limiting is now enabled"
|
||||
"command.flywheel.limit_updates.set.on" : "Update limiting is now enabled",
|
||||
"command.flywheel.use_light_directions.get.off" : "Not using light directions",
|
||||
"command.flywheel.use_light_directions.get.on" : "Using light directions",
|
||||
"command.flywheel.use_light_directions.set.off" : "Set light directions to off",
|
||||
"command.flywheel.use_light_directions.set.on" : "Set light directions to on"
|
||||
}
|
||||
|
|
|
@ -185,16 +185,24 @@ public class FabricFlwConfig implements FlwConfig {
|
|||
|
||||
public static class FabricBackendConfig implements BackendConfig {
|
||||
public static final LightSmoothness LIGHT_SMOOTHNESS_DEFAULT = LightSmoothness.SMOOTH;
|
||||
public static final boolean USE_LIGHT_DIRECTIONS_DEFAULT = true;
|
||||
|
||||
public LightSmoothness lightSmoothness = LIGHT_SMOOTHNESS_DEFAULT;
|
||||
public boolean useLightDirections = USE_LIGHT_DIRECTIONS_DEFAULT;
|
||||
|
||||
@Override
|
||||
public LightSmoothness lightSmoothness() {
|
||||
return lightSmoothness;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useLightDirections() {
|
||||
return useLightDirections;
|
||||
}
|
||||
|
||||
public void fromJson(JsonObject object) {
|
||||
readLightSmoothness(object);
|
||||
readUseLightDirections(object);
|
||||
}
|
||||
|
||||
private void readLightSmoothness(JsonObject object) {
|
||||
|
@ -224,9 +232,23 @@ public class FabricFlwConfig implements FlwConfig {
|
|||
lightSmoothness = LIGHT_SMOOTHNESS_DEFAULT;
|
||||
}
|
||||
|
||||
private void readUseLightDirections(JsonObject object) {
|
||||
var useLightDirectionsJson = object.get("useLightDirections");
|
||||
|
||||
if (useLightDirectionsJson instanceof JsonPrimitive primitive && primitive.isBoolean()) {
|
||||
useLightDirections = primitive.getAsBoolean();
|
||||
return;
|
||||
} else if (useLightDirectionsJson != null) {
|
||||
FlwBackend.LOGGER.warn("'useLightDirections' value must be a boolean");
|
||||
}
|
||||
|
||||
useLightDirections = USE_LIGHT_DIRECTIONS_DEFAULT;
|
||||
}
|
||||
|
||||
public JsonObject toJson() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("lightSmoothness", lightSmoothness.getSerializedName());
|
||||
object.addProperty("useLightDirections", useLightDirections);
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.mojang.brigadier.context.CommandContext;
|
|||
import dev.engine_room.flywheel.api.backend.Backend;
|
||||
import dev.engine_room.flywheel.api.backend.BackendManager;
|
||||
import dev.engine_room.flywheel.backend.compile.LightSmoothness;
|
||||
import dev.engine_room.flywheel.backend.compile.PipelineCompiler;
|
||||
import dev.engine_room.flywheel.backend.engine.uniform.DebugMode;
|
||||
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
||||
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
|
||||
|
@ -133,12 +134,39 @@ public final class FlwCommands {
|
|||
if (oldValue != newValue) {
|
||||
FabricFlwConfig.INSTANCE.backendConfig.lightSmoothness = newValue;
|
||||
FabricFlwConfig.INSTANCE.save();
|
||||
Minecraft.getInstance()
|
||||
.reloadResourcePacks();
|
||||
PipelineCompiler.deleteAll();
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
command.then(ClientCommandManager.literal("useLightDirections")
|
||||
.executes(context -> {
|
||||
if (FabricFlwConfig.INSTANCE.backendConfig.useLightDirections) {
|
||||
context.getSource()
|
||||
.sendFeedback(Component.translatable("command.flywheel.use_light_directions.get.on"));
|
||||
} else {
|
||||
context.getSource()
|
||||
.sendFeedback(Component.translatable("command.flywheel.use_light_directions.get.off"));
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
.then(ClientCommandManager.literal("on")
|
||||
.executes(context -> {
|
||||
FabricFlwConfig.INSTANCE.backendConfig.useLightDirections = true;
|
||||
FabricFlwConfig.INSTANCE.save();
|
||||
context.getSource()
|
||||
.sendFeedback(Component.translatable("command.flywheel.use_light_directions.set.on"));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}))
|
||||
.then(ClientCommandManager.literal("off")
|
||||
.executes(context -> {
|
||||
FabricFlwConfig.INSTANCE.backendConfig.useLightDirections = false;
|
||||
FabricFlwConfig.INSTANCE.save();
|
||||
context.getSource()
|
||||
.sendFeedback(Component.translatable("command.flywheel.use_light_directions.set.off"));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
dispatcher.register(command);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|||
import dev.engine_room.flywheel.api.backend.Backend;
|
||||
import dev.engine_room.flywheel.api.backend.BackendManager;
|
||||
import dev.engine_room.flywheel.backend.compile.LightSmoothness;
|
||||
import dev.engine_room.flywheel.backend.compile.PipelineCompiler;
|
||||
import dev.engine_room.flywheel.backend.engine.uniform.DebugMode;
|
||||
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -131,12 +132,34 @@ public final class FlwCommands {
|
|||
|
||||
if (oldValue != newValue) {
|
||||
lightSmoothnessValue.set(newValue);
|
||||
Minecraft.getInstance()
|
||||
.reloadResourcePacks();
|
||||
PipelineCompiler.deleteAll();
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
var useLightDirectionsValue = ForgeFlwConfig.INSTANCE.client.backendConfig.useLightDirections;
|
||||
command.then(Commands.literal("useLightDirections")
|
||||
.executes(context -> {
|
||||
if (useLightDirectionsValue.get()) {
|
||||
sendMessage(context.getSource(), Component.translatable("command.flywheel.use_light_directions.get.on"));
|
||||
} else {
|
||||
sendMessage(context.getSource(), Component.translatable("command.flywheel.use_light_directions.get.off"));
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
.then(Commands.literal("on")
|
||||
.executes(context -> {
|
||||
useLightDirectionsValue.set(true);
|
||||
sendMessage(context.getSource(), Component.translatable("command.flywheel.use_light_directions.set.on"));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}))
|
||||
.then(Commands.literal("off")
|
||||
.executes(context -> {
|
||||
useLightDirectionsValue.set(false);
|
||||
sendMessage(context.getSource(), Component.translatable("command.flywheel.use_light_directions.set.off"));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
event.getDispatcher().register(command);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,15 +101,24 @@ public class ForgeFlwConfig implements FlwConfig {
|
|||
|
||||
public static class ForgeBackendConfig implements BackendConfig {
|
||||
public final ForgeConfigSpec.EnumValue<LightSmoothness> lightSmoothness;
|
||||
public final ForgeConfigSpec.BooleanValue useLightDirections;
|
||||
|
||||
public ForgeBackendConfig(ForgeConfigSpec.Builder builder) {
|
||||
lightSmoothness = builder.comment("How smooth flywheel's shader-based lighting should be. May have a large performance impact.")
|
||||
.defineEnum("lightSmoothness", LightSmoothness.SMOOTH);
|
||||
|
||||
useLightDirections = builder.comment("If true, diffuse lighting is accurate to vanilla entities and block entities. If false, diffuse lighting is accurate to vanilla chunks. Zero performance impact, just a matter of visual preference.")
|
||||
.define("useLightDirections", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightSmoothness lightSmoothness() {
|
||||
return lightSmoothness.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useLightDirections() {
|
||||
return useLightDirections.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue