Skip to content

Commit

Permalink
In the right direction
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
Jozufozu committed Sep 29, 2024
1 parent 22b5676 commit 4057742
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public interface BackendConfig {
* @return The current light smoothness setting.
*/
LightSmoothness lightSmoothness();

boolean useLightDirections();
}
Original file line number Diff line number Diff line change
@@ -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() {
}

Expand All @@ -24,6 +30,9 @@ public static void update(RenderContext context) {
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;
Expand All @@ -46,6 +55,8 @@ public static void update(RenderContext context) {

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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -37,6 +38,10 @@ static long writeVec3(long ptr, float x, float y, float z) {
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);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
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;
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;

Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ public static Material getMaterial(RenderType chunkRenderType, boolean shaded) {
}

@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;
Expand Down
6 changes: 5 additions & 1 deletion common/src/main/resources/assets/flywheel/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,24 @@ public JsonObject toJson() {

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) {
Expand Down Expand Up @@ -224,9 +232,23 @@ private void readLightSmoothness(JsonObject object) {
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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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;
Expand Down Expand Up @@ -133,12 +134,39 @@ public static void registerClientCommands(CommandDispatcher<FabricClientCommandS
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);
}

Expand Down
27 changes: 25 additions & 2 deletions forge/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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;
Expand Down Expand Up @@ -131,12 +132,34 @@ public static void registerClientCommands(RegisterClientCommandsEvent event) {

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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,24 @@ private ClientConfig(ForgeConfigSpec.Builder builder) {

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();
}
}
}

0 comments on commit 4057742

Please sign in to comment.