Compare commits

..

6 Commits

Author SHA1 Message Date
Kneelawk
5399b0fc50
Make alpha 1 if team exists but does not have a color 2024-03-04 18:31:50 -08:00
Kneelawk
b477ef0f65
Fix simple things 2024-03-04 18:29:33 -08:00
Kneelawk
8f4958ee2a
Add new uniforms to cull shader 2024-03-04 18:21:36 -08:00
Kneelawk
3e55ae6aea
Fix offset alignments 2024-03-04 15:21:55 -08:00
Kneelawk
ce1d7dc44b
Update options 2024-03-04 14:58:58 -08:00
Kneelawk
aae98c06f4
Fix uniform bindings 2024-03-04 14:28:02 -08:00
13 changed files with 129 additions and 55 deletions

View File

@ -11,6 +11,7 @@ import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
import com.jozufozu.flywheel.backend.compile.core.Compile;
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
import com.jozufozu.flywheel.backend.gl.GlCompat;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
@ -81,7 +82,12 @@ public class IndirectPrograms extends AtomicReferenceCounted {
.withComponent(IndirectComponent::create)
.withResource(InstanceType::cullShader)
.withResource(CULL_SHADER_MAIN))
.postLink((key, program) -> program.setUniformBlockBinding("_FlwFrameUniforms", 0))
.postLink((key, program) -> {
program.setUniformBlockBinding("_FlwFrameUniforms", Uniforms.FRAME_INDEX);
program.setUniformBlockBinding("_FlwOptionsUniforms", Uniforms.OPTIONS_INDEX);
program.setUniformBlockBinding("_FlwPlayerUniforms", Uniforms.PLAYER_INDEX);
program.setUniformBlockBinding("_FlwLevelUniforms", Uniforms.LEVEL_INDEX);
})
.harness("culling", sources);
}

View File

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.backend.InternalVertex;
import com.jozufozu.flywheel.backend.Samplers;
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
import com.jozufozu.flywheel.backend.compile.core.Compile;
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
@ -60,8 +61,11 @@ public class PipelineCompiler {
program.bindAttribLocation("_flw_a_normal", 5);
})
.postLink((key, program) -> {
program.setUniformBlockBinding("_FlwFrameUniforms", 0);
program.setUniformBlockBinding("_FlwFogUniforms", 1);
program.setUniformBlockBinding("_FlwFrameUniforms", Uniforms.FRAME_INDEX);
program.setUniformBlockBinding("_FlwFogUniforms", Uniforms.FOG_INDEX);
program.setUniformBlockBinding("_FlwOptionsUniforms", Uniforms.OPTIONS_INDEX);
program.setUniformBlockBinding("_FlwPlayerUniforms", Uniforms.PLAYER_INDEX);
program.setUniformBlockBinding("_FlwLevelUniforms", Uniforms.LEVEL_INDEX);
program.bind();

View File

@ -103,16 +103,13 @@ public class FrameUniforms implements UniformProvider {
cleanProjectionPrev.set(cleanProjection);
cleanViewProjectionPrev.set(cleanViewProjection);
ptr = writeCamera(ptr, camX, camY, camZ, camera.getLookVector(), camera.getXRot(), camera.getYRot());
// last values for camera
if (!lastInit) {
cameraPositionPrev.set(camX, camY, camZ);
cameraLookPrev.set(camera.getLookVector());
cameraRotPrev.set(camera.getXRot(), camera.getYRot());
}
ptr = writeCamera(ptr, cameraPositionPrev.x, cameraPositionPrev.y, cameraPositionPrev.z, cameraLookPrev,
cameraRotPrev.x, cameraRotPrev.y);
ptr = writeCamera(ptr, camX, camY, camZ);
cameraPositionPrev.set(camX, camY, camZ);
cameraLookPrev.set(camera.getLookVector());
cameraRotPrev.set(camera.getXRot(), camera.getYRot());
@ -182,13 +179,18 @@ public class FrameUniforms implements UniformProvider {
cleanViewProjection.set(cleanProjection).mul(stack.last().pose());
}
private static long writeCamera(long ptr, float camX, float camY, float camZ, Vector3f lookVector, float xRot,
float yRot) {
private long writeCamera(long ptr, float camX, float camY, float camZ) {
Camera camera = context.camera();
Vector3f lookVector = camera.getLookVector();
ptr = Uniforms.writeVec3(ptr, camX, camY, camZ);
ptr = Uniforms.writeVec3(ptr, cameraPositionPrev.x, cameraPositionPrev.y, cameraPositionPrev.z);
ptr = Uniforms.writeVec3(ptr, lookVector.x, lookVector.y, lookVector.z);
ptr = Uniforms.writeVec3(ptr, cameraLookPrev.x, cameraLookPrev.y, cameraLookPrev.z);
ptr = Uniforms.writeVec2(ptr, xRot, yRot);
ptr = Uniforms.writeVec2(ptr, camera.getXRot(), camera.getYRot());
ptr = Uniforms.writeVec2(ptr, cameraRotPrev.x, cameraRotPrev.y);
return ptr;
}

View File

@ -37,6 +37,12 @@ public class LevelUniforms implements UniformProvider {
float ptick = context.partialTick();
Vec3 skyColor = level.getSkyColor(mc.gameRenderer.getMainCamera().getPosition(), ptick);
ptr = Uniforms.writeVec4(ptr, (float) skyColor.x, (float) skyColor.y, (float) skyColor.z, 1f);
Vec3 cloudColor = level.getCloudColor(ptick);
ptr = Uniforms.writeVec4(ptr, (float) cloudColor.x, (float) cloudColor.y, (float) cloudColor.z, 1f);
long dayTime = level.getDayTime();
long levelDay = dayTime / 24000L;
long timeOfDay = dayTime - levelDay * 24000L;
@ -70,12 +76,6 @@ public class LevelUniforms implements UniformProvider {
MemoryUtil.memPutFloat(ptr, level.getSkyDarken(ptick));
ptr += 4;
Vec3 skyColor = level.getSkyColor(mc.gameRenderer.getMainCamera().getPosition(), ptick);
ptr = Uniforms.writeVec4(ptr, (float) skyColor.x, (float) skyColor.y, (float) skyColor.z, 1f);
Vec3 cloudColor = level.getCloudColor(ptick);
ptr = Uniforms.writeVec4(ptr, (float) cloudColor.x, (float) cloudColor.y, (float) cloudColor.z, 1f);
// TODO: use defines for custom dimension ids
int dimensionId;
ResourceKey<Level> dimension = level.dimension();

View File

@ -44,30 +44,16 @@ public class PlayerUniforms implements UniformProvider {
return;
}
int luminance = 0;
for (InteractionHand hand : InteractionHand.values()) {
Item handItem = player.getItemInHand(hand).getItem();
if (handItem instanceof BlockItem bitem) {
Block block = bitem.getBlock();
int blockLight = block.defaultBlockState().getLightEmission(player.clientLevel, BlockPos.ZERO);
if (luminance < blockLight) {
luminance = blockLight;
}
}
}
MemoryUtil.memPutFloat(ptr, (float) luminance / 15);
ptr += 4;
PlayerInfo info = ((AbstractClientPlayerAccessor) player).flywheel$getPlayerInfo();
Vec3 eyePos = player.getEyePosition(context.partialTick());
ptr = Uniforms.writeVec3(ptr, (float) eyePos.x, (float) eyePos.y, (float) eyePos.z);
int blockBrightness = player.clientLevel.getBrightness(LightLayer.BLOCK, player.blockPosition());
int skyBrightness = player.clientLevel.getBrightness(LightLayer.SKY, player.blockPosition());
int maxBrightness = player.clientLevel.getMaxLightLevel();
ptr = writeTeamColor(ptr, info);
ptr = Uniforms.writeVec2(ptr, (float) blockBrightness / (float) maxBrightness,
(float) skyBrightness / (float) maxBrightness);
ptr = writeEyeBrightness(ptr, player);
ptr = writeHeldLight(ptr, player);
ptr = writeEyeIn(ptr, player);
@ -83,28 +69,56 @@ public class PlayerUniforms implements UniformProvider {
MemoryUtil.memPutInt(ptr, player.isShiftKeyDown() ? 1 : 0);
ptr += 4;
PlayerInfo info = ((AbstractClientPlayerAccessor) player).flywheel$getPlayerInfo();
MemoryUtil.memPutInt(ptr, info.getGameMode().getId());
ptr += 4;
}
int red = 0, green = 0, blue = 0, alpha = 0;
private static long writeTeamColor(long ptr, PlayerInfo info) {
int red = 255, green = 255, blue = 255, alpha = 0;
PlayerTeam team = info.getTeam();
if (team != null) {
alpha = 255;
Integer color = team.getColor().getColor();
if (color != null) {
int icolor = color;
red = FastColor.ARGB32.red(icolor);
green = FastColor.ARGB32.green(icolor);
blue = FastColor.ARGB32.blue(icolor);
alpha = 255;
}
}
ptr = Uniforms.writeVec4(ptr, (float) red / 255f, (float) blue / 255f, (float) green / 255f,
return Uniforms.writeVec4(ptr, (float) red / 255f, (float) blue / 255f, (float) green / 255f,
(float) alpha / 255f);
}
private long writeEyeIn(long ptr, LocalPlayer player) {
private static long writeEyeBrightness(long ptr, LocalPlayer player) {
int blockBrightness = player.clientLevel.getBrightness(LightLayer.BLOCK, player.blockPosition());
int skyBrightness = player.clientLevel.getBrightness(LightLayer.SKY, player.blockPosition());
int maxBrightness = player.clientLevel.getMaxLightLevel();
ptr = Uniforms.writeVec2(ptr, (float) blockBrightness / (float) maxBrightness,
(float) skyBrightness / (float) maxBrightness);
return ptr;
}
private static long writeHeldLight(long ptr, LocalPlayer player) {
int luminance = 0;
for (InteractionHand hand : InteractionHand.values()) {
Item handItem = player.getItemInHand(hand).getItem();
if (handItem instanceof BlockItem bitem) {
Block block = bitem.getBlock();
int blockLight = block.defaultBlockState().getLightEmission(player.clientLevel, BlockPos.ZERO);
if (luminance < blockLight) {
luminance = blockLight;
}
}
}
MemoryUtil.memPutFloat(ptr, (float) luminance / 15);
return ptr + 4;
}
private static long writeEyeIn(long ptr, LocalPlayer player) {
ClientLevel level = player.clientLevel;
Vec3 eyePos = player.getEyePosition();
BlockPos blockPos = BlockPos.containing(eyePos);

View File

@ -17,6 +17,11 @@ import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.Vec3;
public class Uniforms {
public static final int FRAME_INDEX = 0;
public static final int FOG_INDEX = 1;
public static final int OPTIONS_INDEX = 2;
public static final int PLAYER_INDEX = 3;
public static final int LEVEL_INDEX = 4;
public static boolean frustumPaused = false;
public static boolean frustumCapture = false;
private static @Nullable UniformBuffer<FrameUniforms> frame;
@ -24,38 +29,39 @@ public class Uniforms {
private static @Nullable UniformBuffer<OptionsUniforms> options;
private static @Nullable UniformBuffer<PlayerUniforms> player;
private static @Nullable UniformBuffer<LevelUniforms> level;
private static boolean optionsRequiresUpdate = false;
public static UniformBuffer<FrameUniforms> frame() {
if (frame == null) {
frame = new UniformBuffer<>(0, new FrameUniforms());
frame = new UniformBuffer<>(FRAME_INDEX, new FrameUniforms());
}
return frame;
}
public static UniformBuffer<FogUniforms> fog() {
if (fog == null) {
fog = new UniformBuffer<>(1, new FogUniforms());
fog = new UniformBuffer<>(FOG_INDEX, new FogUniforms());
}
return fog;
}
public static UniformBuffer<OptionsUniforms> options() {
if (options == null) {
options = new UniformBuffer<>(2, new OptionsUniforms());
options = new UniformBuffer<>(OPTIONS_INDEX, new OptionsUniforms());
}
return options;
}
public static UniformBuffer<PlayerUniforms> player() {
if (player == null) {
player = new UniformBuffer<>(3, new PlayerUniforms());
player = new UniformBuffer<>(PLAYER_INDEX, new PlayerUniforms());
}
return player;
}
public static UniformBuffer<LevelUniforms> level() {
if (level == null) {
level = new UniformBuffer<>(4, new LevelUniforms());
level = new UniformBuffer<>(LEVEL_INDEX, new LevelUniforms());
}
return level;
}
@ -104,12 +110,20 @@ public class Uniforms {
}
}
public static void onOptionsUpdate() {
// this is sometimes called too early to do an actual update
optionsRequiresUpdate = true;
}
public static void updateContext(RenderContext ctx) {
var ubo = frame();
ubo.provider.setContext(ctx);
ubo.update();
options();
if (optionsRequiresUpdate) {
options().update();
optionsRequiresUpdate = false;
}
var player = player();
player.provider.setContext(ctx);

View File

@ -0,0 +1,23 @@
package com.jozufozu.flywheel.backend.mixin;
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
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 net.minecraft.client.Options;
@Mixin(Options.class)
public class OptionsMixin {
@Inject(method = "load()V", at = @At("RETURN"))
private void onLoad(CallbackInfo ci) {
Uniforms.onOptionsUpdate();
}
@Inject(method = "save", at = @At("HEAD"))
private void onSave(CallbackInfo ci) {
Uniforms.onOptionsUpdate();
}
}

View File

@ -2,6 +2,9 @@
#include "flywheel:internal/indirect/model_descriptor.glsl"
#include "flywheel:internal/indirect/object.glsl"
#include "flywheel:internal/uniforms/frame.glsl"
#include "flywheel:internal/uniforms/options.glsl"
#include "flywheel:internal/uniforms/player.glsl"
#include "flywheel:internal/uniforms/level.glsl"
#include "flywheel:util/matrix.glsl"
layout(local_size_x = _FLW_SUBGROUP_SIZE) in;

View File

@ -3,3 +3,7 @@
// Fog doesn't seem like a valid thing to query during the cull pass. Other uniforms added in the
// future may also be excluded, and we'll have to document each one.
// #include "flywheel:internal/uniforms/fog.glsl"
#include "flywheel:internal/uniforms/options.glsl"
#include "flywheel:internal/uniforms/player.glsl"
#include "flywheel:internal/uniforms/level.glsl"

View File

@ -30,10 +30,10 @@ layout(std140) uniform _FlwFrameUniforms {
mat4 flw_cleanViewProjectionPrev;
vec4 _flw_cameraPos;
vec4 _flw_cameraLook;
vec2 flw_cameraRot;
vec4 _flw_cameraPosPrev;
vec4 _flw_cameraLook;
vec4 _flw_cameraLookPrev;
vec2 flw_cameraRot;
vec2 flw_cameraRotPrev;
vec2 flw_viewportSize;

View File

@ -1,4 +1,7 @@
layout(std140) uniform _FlwLevelUniforms {
vec4 flw_skyColor;
vec4 flw_cloudColor;
/** The current day number of the level. */
uint flw_levelDay;
/** The current fraction of the current day that has elapsed. */
@ -18,8 +21,6 @@ layout(std140) uniform _FlwLevelUniforms {
float flw_thunderLevel;
float flw_skyDarken;
vec4 flw_skyColor;
vec4 flw_cloudColor;
/** Use FLW_DIMENSION_* ids to determine the dimension. May eventually be implemented for custom dimensions. */
uint flw_dimension;

View File

@ -1,11 +1,16 @@
// player.glsl - Holds uniforms for player state.
layout (std140) uniform _FlwPlayerUniforms {
/** Brightness of the brightest light that the player is holding, 0-1. */
float flw_heldLight;
vec4 _flw_eyePos;
/** Alpha is 1 if any team color is present, 0 otherwise. */
vec4 flw_teamColor;
/** The brightness at the player's eye position. */
vec2 flw_eyeBrightness;
/** Brightness of the brightest light that the player is holding, 0-1. */
float flw_heldLight;
/** 0 means no fluid. Use FLW_PLAYER_EYE_IN_FLUID_* defines to detect fluid type. */
uint flw_playerEyeInFluid;
/** 0 means no block. Use FLW_PLAYER_EYE_IN_BLOCK_* defines to detect block type. */
@ -20,9 +25,6 @@ layout (std140) uniform _FlwPlayerUniforms {
/** 0 = survival, 1 = creative, 2 = adventure, 3 = spectator. */
uint flw_gameMode;
/** Alpha is 1 if any team color is present, 0 otherwise. */
vec4 flw_teamColor;
};
#define flw_eyePos _flw_eyePos.xyz

View File

@ -9,6 +9,7 @@
"GameRendererAccessor",
"GlStateManagerMixin",
"LightTextureAccessor",
"OptionsMixin",
"OverlayTextureAccessor",
"RenderSystemMixin"
],