mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 22:43:56 +01:00
Add More Uniforms (#231)
Squashed commit history: * Add basic view.h matrices * Add last values * Add clean matrices * Finish adding most view.h things to frame.glsl * Document cameraIn- uniforms * Add options uniform * Begin on player uniforms * Add more player uniforms * Add level uniforms * Fix uniform bindings * Update options * Fix offset alignments * Add new uniforms to cull shader * Fix simple things * Make alpha 1 if team exists but does not have a color * Fix mixin method names * Provide all uniforms to cull shaders * Move constant ambient light uniform to level group * Level uniforms gets context from context * Remove `clean` matrices for now
This commit is contained in:
parent
3a0ec10a30
commit
a2dadb9fcb
@ -11,6 +11,7 @@ import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||
import com.jozufozu.flywheel.backend.compile.component.StructInstanceComponent;
|
||||
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,13 @@ public class IndirectPrograms extends AtomicReferenceCounted {
|
||||
.withComponent(StructInstanceComponent::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("_FlwFogUniforms", Uniforms.FOG_INDEX);
|
||||
program.setUniformBlockBinding("_FlwOptionsUniforms", Uniforms.OPTIONS_INDEX);
|
||||
program.setUniformBlockBinding("_FlwPlayerUniforms", Uniforms.PLAYER_INDEX);
|
||||
program.setUniformBlockBinding("_FlwLevelUniforms", Uniforms.LEVEL_INDEX);
|
||||
})
|
||||
.harness("culling", sources);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -57,8 +58,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();
|
||||
|
||||
|
@ -2,26 +2,47 @@ package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||
import com.jozufozu.flywheel.backend.mixin.GameRendererAccessor;
|
||||
import com.jozufozu.flywheel.lib.math.MatrixMath;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class FrameUniforms implements UniformProvider {
|
||||
public static final int SIZE = 304;
|
||||
public static final int SIZE = 1188;
|
||||
public int debugMode;
|
||||
|
||||
@Nullable
|
||||
private RenderContext context;
|
||||
|
||||
private final Matrix4f view = new Matrix4f();
|
||||
private final Matrix4f viewInverse = new Matrix4f();
|
||||
private final Matrix4f viewPrev = new Matrix4f();
|
||||
private final Matrix4f projection = new Matrix4f();
|
||||
private final Matrix4f projectionInverse = new Matrix4f();
|
||||
private final Matrix4f projectionPrev = new Matrix4f();
|
||||
private final Matrix4f viewProjection = new Matrix4f();
|
||||
private final Matrix4f viewProjectionInverse = new Matrix4f();
|
||||
private final Matrix4f viewProjectionPrev = new Matrix4f();
|
||||
|
||||
private final Vector3f cameraPositionPrev = new Vector3f();
|
||||
private final Vector3f cameraLookPrev = new Vector3f();
|
||||
private final Vector2f cameraRotPrev = new Vector2f();
|
||||
|
||||
private boolean lastInit = false;
|
||||
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
@ -46,6 +67,9 @@ public class FrameUniforms implements UniformProvider {
|
||||
var camY = (float) (cameraPos.y - renderOrigin.getY());
|
||||
var camZ = (float) (cameraPos.z - renderOrigin.getZ());
|
||||
|
||||
view.set(context.stack().last().pose());
|
||||
view.translate(-camX, -camY, -camZ);
|
||||
projection.set(context.projection());
|
||||
viewProjection.set(context.viewProjection());
|
||||
viewProjection.translate(-camX, -camY, -camZ);
|
||||
|
||||
@ -56,39 +80,76 @@ public class FrameUniforms implements UniformProvider {
|
||||
|
||||
ptr += 96;
|
||||
|
||||
// manage last values of matrices
|
||||
if (!lastInit) {
|
||||
viewPrev.set(view);
|
||||
projectionPrev.set(projection);
|
||||
viewProjectionPrev.set(viewProjectionPrev);
|
||||
}
|
||||
ptr = writeMatrices(ptr);
|
||||
viewPrev.set(view);
|
||||
projectionPrev.set(projection);
|
||||
viewProjectionPrev.set(viewProjection);
|
||||
|
||||
ptr = writeCamera(ptr, camX, camY, camZ, camera);
|
||||
// last values for camera
|
||||
if (!lastInit) {
|
||||
cameraPositionPrev.set(camX, camY, camZ);
|
||||
cameraLookPrev.set(camera.getLookVector());
|
||||
cameraRotPrev.set(camera.getXRot(), camera.getYRot());
|
||||
}
|
||||
ptr = writeCamera(ptr, camX, camY, camZ);
|
||||
cameraPositionPrev.set(camX, camY, camZ);
|
||||
cameraLookPrev.set(camera.getLookVector());
|
||||
cameraRotPrev.set(camera.getXRot(), camera.getYRot());
|
||||
|
||||
var window = Minecraft.getInstance()
|
||||
.getWindow();
|
||||
ptr = writeVec2(ptr, window.getWidth(), window.getHeight());
|
||||
ptr = Uniforms.writeVec2(ptr, window.getWidth(), window.getHeight());
|
||||
|
||||
// default line width: net.minecraft.client.renderer.RenderStateShard.LineStateShard
|
||||
MemoryUtil.memPutFloat(ptr, Math.max(2.5F, (float) window.getWidth() / 1920.0F * 2.5F));
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, getConstantAmbientLightFlag(context));
|
||||
MemoryUtil.memPutFloat(ptr, (float) window.getWidth() / (float) window.getHeight());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, Minecraft.getInstance().gameRenderer.getDepthFar());
|
||||
ptr += 4;
|
||||
|
||||
ptr = writeTime(ptr);
|
||||
|
||||
ptr = writeCameraIn(ptr);
|
||||
|
||||
MemoryUtil.memPutInt(ptr, debugMode);
|
||||
|
||||
lastInit = true;
|
||||
}
|
||||
|
||||
private long writeMatrices(long ptr) {
|
||||
MatrixMath.writeUnsafe(viewProjection, ptr);
|
||||
MatrixMath.writeUnsafe(viewProjection.invert(viewProjectionInverse), ptr + 64);
|
||||
return ptr + 128;
|
||||
MatrixMath.writeUnsafe(view, ptr);
|
||||
MatrixMath.writeUnsafe(view.invert(viewInverse), ptr + 64);
|
||||
MatrixMath.writeUnsafe(viewPrev, ptr + 64 * 2);
|
||||
MatrixMath.writeUnsafe(projection, ptr + 64 * 3);
|
||||
MatrixMath.writeUnsafe(projection.invert(projectionInverse), ptr + 64 * 4);
|
||||
MatrixMath.writeUnsafe(projectionPrev, ptr + 64 * 5);
|
||||
MatrixMath.writeUnsafe(viewProjection, ptr + 64 * 6);
|
||||
MatrixMath.writeUnsafe(viewProjection.invert(viewProjectionInverse), ptr + 64 * 7);
|
||||
MatrixMath.writeUnsafe(viewProjectionPrev, ptr + 64 * 8);
|
||||
return ptr + 64 * 15;
|
||||
}
|
||||
|
||||
private static long writeCamera(long ptr, float camX, float camY, float camZ, Camera camera) {
|
||||
ptr = writeVec3(ptr, camX, camY, camZ);
|
||||
private long writeCamera(long ptr, float camX, float camY, float camZ) {
|
||||
Camera camera = context.camera();
|
||||
Vector3f lookVector = camera.getLookVector();
|
||||
|
||||
var lookVector = camera.getLookVector();
|
||||
ptr = writeVec3(ptr, lookVector.x, lookVector.y, lookVector.z);
|
||||
ptr = Uniforms.writeVec3(ptr, camX, camY, camZ);
|
||||
ptr = Uniforms.writeVec3(ptr, cameraPositionPrev.x, cameraPositionPrev.y, cameraPositionPrev.z);
|
||||
|
||||
ptr = writeVec2(ptr, camera.getXRot(), camera.getYRot());
|
||||
ptr = Uniforms.writeVec3(ptr, lookVector.x, lookVector.y, lookVector.z);
|
||||
ptr = Uniforms.writeVec3(ptr, cameraLookPrev.x, cameraLookPrev.y, cameraLookPrev.z);
|
||||
|
||||
ptr = Uniforms.writeVec2(ptr, camera.getXRot(), camera.getYRot());
|
||||
ptr = Uniforms.writeVec2(ptr, cameraRotPrev.x, cameraRotPrev.y);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -106,24 +167,16 @@ public class FrameUniforms implements UniformProvider {
|
||||
return ptr + 16;
|
||||
}
|
||||
|
||||
private static long writeVec3(long ptr, float camX, float camY, float camZ) {
|
||||
MemoryUtil.memPutFloat(ptr, camX);
|
||||
MemoryUtil.memPutFloat(ptr + 4, camY);
|
||||
MemoryUtil.memPutFloat(ptr + 8, camZ);
|
||||
MemoryUtil.memPutFloat(ptr + 12, 0f); // empty component of vec4 because we don't trust std140
|
||||
return ptr + 16;
|
||||
}
|
||||
|
||||
private static long writeVec2(long ptr, float camX, float camY) {
|
||||
MemoryUtil.memPutFloat(ptr, camX);
|
||||
MemoryUtil.memPutFloat(ptr + 4, camY);
|
||||
private long writeCameraIn(long ptr) {
|
||||
Camera camera = context.camera();
|
||||
if (!camera.isInitialized()) {
|
||||
MemoryUtil.memPutInt(ptr, 0);
|
||||
MemoryUtil.memPutInt(ptr + 4, 0);
|
||||
return ptr + 8;
|
||||
}
|
||||
|
||||
private static int getConstantAmbientLightFlag(RenderContext context) {
|
||||
var constantAmbientLight = context.level()
|
||||
.effects()
|
||||
.constantAmbientLight();
|
||||
return constantAmbientLight ? 1 : 0;
|
||||
Level level = camera.getEntity().level();
|
||||
BlockPos blockPos = camera.getBlockPosition();
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
return Uniforms.writeInFluidAndBlock(ptr, level, blockPos, cameraPos);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,102 @@
|
||||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
public class LevelUniforms implements UniformProvider {
|
||||
public static final int SIZE = 12 * 4 + 2 * 16;
|
||||
|
||||
@Nullable
|
||||
private RenderContext context;
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
public void setContext(RenderContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(long ptr) {
|
||||
if (context == null) {
|
||||
MemoryUtil.memSet(ptr, 0, SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
ClientLevel level = context.level();
|
||||
float ptick = context.partialTick();
|
||||
|
||||
Vec3 skyColor = level.getSkyColor(context.camera().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;
|
||||
MemoryUtil.memPutInt(ptr, (int) (levelDay % 0x7FFFFFFFL));
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutFloat(ptr, (float) timeOfDay / 24000f);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, level.dimensionType().hasSkyLight() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
float sunAngle = level.getSunAngle(ptick);
|
||||
MemoryUtil.memPutFloat(ptr, sunAngle);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, level.getMoonBrightness());
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutInt(ptr, level.getMoonPhase());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, level.isRaining() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutFloat(ptr, level.getRainLevel(ptick));
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, level.isThundering() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutFloat(ptr, level.getThunderLevel(ptick));
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, level.getSkyDarken(ptick));
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, getConstantAmbientLightFlag(context));
|
||||
ptr += 4;
|
||||
|
||||
// TODO: use defines for custom dimension ids
|
||||
int dimensionId;
|
||||
ResourceKey<Level> dimension = level.dimension();
|
||||
if (Level.OVERWORLD.equals(dimension)) {
|
||||
dimensionId = 0;
|
||||
} else if (Level.NETHER.equals(dimension)) {
|
||||
dimensionId = 1;
|
||||
} else if (Level.END.equals(dimension)) {
|
||||
dimensionId = 2;
|
||||
} else {
|
||||
dimensionId = -1;
|
||||
}
|
||||
MemoryUtil.memPutInt(ptr, dimensionId);
|
||||
}
|
||||
|
||||
private static int getConstantAmbientLightFlag(RenderContext context) {
|
||||
var constantAmbientLight = context.level()
|
||||
.effects()
|
||||
.constantAmbientLight();
|
||||
return constantAmbientLight ? 1 : 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Options;
|
||||
|
||||
public class OptionsUniforms implements UniformProvider {
|
||||
public static final int SIZE = 4 * 14;
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(long ptr) {
|
||||
Options options = Minecraft.getInstance().options;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.gamma().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.fov().get());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.screenEffectScale().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.glintSpeed().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.glintStrength().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.biomeBlendRadius().get());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.ambientOcclusion().get() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.bobView().get() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.highContrast().get() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.textBackgroundOpacity().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.backgroundForChatOnly().get() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.darknessEffectScale().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.damageTiltStrength().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.hideLightningFlash().get() ? 1 : 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.backend.mixin.AbstractClientPlayerAccessor;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.multiplayer.PlayerInfo;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
|
||||
public class PlayerUniforms implements UniformProvider {
|
||||
public static final int SIZE = 9 * 4 + 8 + 2 * 16;
|
||||
|
||||
@Nullable
|
||||
private RenderContext context;
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
public void setContext(RenderContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(long ptr) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
LocalPlayer player = mc.player;
|
||||
if (context == null || player == null) {
|
||||
MemoryUtil.memSet(ptr, 0, SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
ptr = writeTeamColor(ptr, info);
|
||||
|
||||
ptr = writeEyeBrightness(ptr, player);
|
||||
|
||||
ptr = writeHeldLight(ptr, player);
|
||||
|
||||
ptr = writeEyeIn(ptr, player);
|
||||
|
||||
MemoryUtil.memPutInt(ptr, player.isCrouching() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutInt(ptr, player.isSleeping() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutInt(ptr, player.isSwimming() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutInt(ptr, player.isFallFlying() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, player.isShiftKeyDown() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, info.getGameMode().getId());
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return Uniforms.writeVec4(ptr, (float) red / 255f, (float) blue / 255f, (float) green / 255f,
|
||||
(float) alpha / 255f);
|
||||
}
|
||||
|
||||
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);
|
||||
return Uniforms.writeInFluidAndBlock(ptr, level, blockPos, eyePos);
|
||||
}
|
||||
}
|
@ -5,29 +5,73 @@ import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||
import com.jozufozu.flywheel.config.DebugMode;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
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 UniformBuffer<FrameUniforms> frame;
|
||||
private static UniformBuffer<FogUniforms> fog;
|
||||
private static @Nullable UniformBuffer<FrameUniforms> frame;
|
||||
private static @Nullable UniformBuffer<FogUniforms> fog;
|
||||
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<>(OPTIONS_INDEX, new OptionsUniforms());
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
public static UniformBuffer<PlayerUniforms> player() {
|
||||
if (player == null) {
|
||||
player = new UniformBuffer<>(PLAYER_INDEX, new PlayerUniforms());
|
||||
}
|
||||
return player;
|
||||
}
|
||||
|
||||
public static UniformBuffer<LevelUniforms> level() {
|
||||
if (level == null) {
|
||||
level = new UniformBuffer<>(LEVEL_INDEX, new LevelUniforms());
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
public static void bindForDraw() {
|
||||
bindFrame();
|
||||
bindFog();
|
||||
bindOptions();
|
||||
bindPlayer();
|
||||
bindLevel();
|
||||
}
|
||||
|
||||
public static void bindFrame() {
|
||||
@ -42,16 +86,52 @@ public class Uniforms {
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindOptions() {
|
||||
if (options != null) {
|
||||
options.bind();
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindPlayer() {
|
||||
if (player != null) {
|
||||
player.bind();
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindLevel() {
|
||||
if (level != null) {
|
||||
level.bind();
|
||||
}
|
||||
}
|
||||
|
||||
public static void onFogUpdate() {
|
||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||
fog().update();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (optionsRequiresUpdate) {
|
||||
options().update();
|
||||
optionsRequiresUpdate = false;
|
||||
}
|
||||
|
||||
var player = player();
|
||||
player.provider.setContext(ctx);
|
||||
player.update();
|
||||
|
||||
var level = level();
|
||||
level.provider.setContext(ctx);
|
||||
level.update();
|
||||
}
|
||||
|
||||
public static void setDebugMode(DebugMode mode) {
|
||||
@ -68,5 +148,74 @@ public class Uniforms {
|
||||
fog.delete();
|
||||
fog = null;
|
||||
}
|
||||
|
||||
if (options != null) {
|
||||
options.delete();
|
||||
options = null;
|
||||
}
|
||||
|
||||
if (player != null) {
|
||||
player.delete();
|
||||
player = null;
|
||||
}
|
||||
|
||||
if (level != null) {
|
||||
level.delete();
|
||||
level = null;
|
||||
}
|
||||
}
|
||||
|
||||
static long writeVec4(long ptr, float x, float y, float z, float w) {
|
||||
MemoryUtil.memPutFloat(ptr, x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, y);
|
||||
MemoryUtil.memPutFloat(ptr + 8, z);
|
||||
MemoryUtil.memPutFloat(ptr + 12, w);
|
||||
return ptr + 16;
|
||||
}
|
||||
|
||||
static long writeVec3(long ptr, float camX, float camY, float camZ) {
|
||||
MemoryUtil.memPutFloat(ptr, camX);
|
||||
MemoryUtil.memPutFloat(ptr + 4, camY);
|
||||
MemoryUtil.memPutFloat(ptr + 8, camZ);
|
||||
MemoryUtil.memPutFloat(ptr + 12, 0f); // empty component of vec4 because we don't trust std140
|
||||
return ptr + 16;
|
||||
}
|
||||
|
||||
static long writeVec2(long ptr, float camX, float camY) {
|
||||
MemoryUtil.memPutFloat(ptr, camX);
|
||||
MemoryUtil.memPutFloat(ptr + 4, camY);
|
||||
return ptr + 8;
|
||||
}
|
||||
|
||||
static long writeInFluidAndBlock(long ptr, Level level, BlockPos blockPos, Vec3 pos) {
|
||||
FluidState fState = level.getFluidState(blockPos);
|
||||
BlockState bState = level.getBlockState(blockPos);
|
||||
float height = fState.getHeight(level, blockPos);
|
||||
|
||||
if (fState.isEmpty()) {
|
||||
MemoryUtil.memPutInt(ptr, 0);
|
||||
} else if (pos.y < blockPos.getY() + height) {
|
||||
// TODO: handle custom fluids via defines
|
||||
if (fState.is(FluidTags.WATER)) {
|
||||
MemoryUtil.memPutInt(ptr, 1);
|
||||
} else if (fState.is(FluidTags.LAVA)) {
|
||||
MemoryUtil.memPutInt(ptr, 2);
|
||||
} else {
|
||||
MemoryUtil.memPutInt(ptr, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (bState.isAir()) {
|
||||
MemoryUtil.memPutInt(ptr + 4, 0);
|
||||
} else {
|
||||
// TODO: handle custom blocks via defines
|
||||
if (bState.is(Blocks.POWDER_SNOW)) {
|
||||
MemoryUtil.memPutInt(ptr + 4, 0);
|
||||
} else {
|
||||
MemoryUtil.memPutInt(ptr + 4, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return ptr + 8;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.jozufozu.flywheel.backend.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.client.multiplayer.PlayerInfo;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
|
||||
@Mixin(AbstractClientPlayer.class)
|
||||
public interface AbstractClientPlayerAccessor {
|
||||
@Invoker("getPlayerInfo")
|
||||
PlayerInfo flywheel$getPlayerInfo();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.jozufozu.flywheel.backend.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
|
||||
@Mixin(GameRenderer.class)
|
||||
public interface GameRendererAccessor {
|
||||
@Invoker("getFov")
|
||||
double flywheel$getFov(Camera pActiveRenderInfo, float pPartialTicks, boolean pUseFOVSetting);
|
||||
|
||||
@Accessor("zoom")
|
||||
float flywheel$getZoom();
|
||||
|
||||
@Accessor("zoomX")
|
||||
float flywheel$getZoomX();
|
||||
|
||||
@Accessor("zoomY")
|
||||
float flywheel$getZoomY();
|
||||
}
|
@ -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 flywheel$onLoad(CallbackInfo ci) {
|
||||
Uniforms.onOptionsUpdate();
|
||||
}
|
||||
|
||||
@Inject(method = "save", at = @At("HEAD"))
|
||||
private void flywheel$onSave(CallbackInfo ci) {
|
||||
Uniforms.onOptionsUpdate();
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
#include "flywheel:internal/material.glsl"
|
||||
#include "flywheel:internal/uniforms/frame.glsl"
|
||||
#include "flywheel:internal/uniforms/fog.glsl"
|
||||
#include "flywheel:internal/uniforms/uniforms.glsl"
|
||||
|
||||
in vec4 flw_vertexPos;
|
||||
in vec4 flw_vertexColor;
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "flywheel:internal/material.glsl"
|
||||
#include "flywheel:internal/uniforms/frame.glsl"
|
||||
#include "flywheel:internal/uniforms/fog.glsl"
|
||||
#include "flywheel:internal/uniforms/uniforms.glsl"
|
||||
|
||||
// TODO: can we combine some of these internally to use fewer in/out slots?
|
||||
out vec4 flw_vertexPos;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "flywheel:internal/indirect/buffers.glsl"
|
||||
#include "flywheel:internal/indirect/model_descriptor.glsl"
|
||||
#include "flywheel:internal/indirect/object.glsl"
|
||||
#include "flywheel:internal/uniforms/frame.glsl"
|
||||
#include "flywheel:internal/uniforms/uniforms.glsl"
|
||||
#include "flywheel:util/matrix.glsl"
|
||||
|
||||
layout(local_size_x = _FLW_SUBGROUP_SIZE) in;
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include "flywheel:internal/uniforms/frame.glsl"
|
||||
|
||||
// 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"
|
||||
// Cull shaders may not need all uniforms, but it is
|
||||
// more consistent if we just provide all uniforms anyways.
|
||||
#include "flywheel:internal/uniforms/uniforms.glsl"
|
||||
|
@ -12,15 +12,27 @@ struct FrustumPlanes {
|
||||
layout(std140) uniform _FlwFrameUniforms {
|
||||
FrustumPlanes flw_frustumPlanes;
|
||||
|
||||
mat4 flw_view;
|
||||
mat4 flw_viewInverse;
|
||||
mat4 flw_viewPrev;
|
||||
mat4 flw_projection;
|
||||
mat4 flw_projectionInverse;
|
||||
mat4 flw_projectionPrev;
|
||||
mat4 flw_viewProjection;
|
||||
mat4 flw_viewProjectionInverse;
|
||||
mat4 flw_viewProjectionPrev;
|
||||
|
||||
vec4 _flw_cameraPos;
|
||||
vec4 _flw_cameraPosPrev;
|
||||
vec4 _flw_cameraLook;
|
||||
vec4 _flw_cameraLookPrev;
|
||||
vec2 flw_cameraRot;
|
||||
vec2 flw_cameraRotPrev;
|
||||
|
||||
vec2 flw_viewportSize;
|
||||
float flw_defaultLineWidth;
|
||||
float flw_aspectRatio;
|
||||
float flw_viewDistance;
|
||||
|
||||
uint flw_constantAmbientLight;
|
||||
|
||||
@ -30,8 +42,22 @@ layout(std140) uniform _FlwFrameUniforms {
|
||||
float flw_renderTicks;
|
||||
float flw_renderSeconds;
|
||||
|
||||
/** 0 means no fluid. Use FLW_CAMERA_IN_FLUID_* defines to detect fluid type. */
|
||||
uint flw_cameraInFluid;
|
||||
/** 0 means no block. Use FLW_CAMERA_IN_BLOCK_* defines to detect block type. */
|
||||
uint flw_cameraInBlock;
|
||||
|
||||
uint _flw_debugMode;
|
||||
};
|
||||
|
||||
#define flw_cameraPos _flw_cameraPos.xyz
|
||||
#define flw_cameraLook _flw_cameraLook.xyz
|
||||
#define flw_cameraPosPrev _flw_cameraPosPrev.xyz
|
||||
#define flw_cameraLookPrev _flw_cameraLookPrev.xyz
|
||||
|
||||
#define FLW_CAMERA_IN_FLUID_WATER 1
|
||||
#define FLW_CAMERA_IN_FLUID_LAVA 2
|
||||
#define FLW_CAMERA_IN_FLUID_UNKNOWN 0xFFFFFFFFu
|
||||
|
||||
#define FLW_CAMERA_IN_BLOCK_POWDER_SNOW 1
|
||||
#define FLW_CAMERA_IN_BLOCK_UNKNOWN 0xFFFFFFFFu
|
||||
|
@ -0,0 +1,32 @@
|
||||
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. */
|
||||
float flw_timeOfDay;
|
||||
|
||||
uint flw_levelHasSkyLight;
|
||||
|
||||
float flw_sunAngle;
|
||||
|
||||
float flw_moonBrightness;
|
||||
/** There are normally only 8 moon phases. */
|
||||
uint flw_moonPhase;
|
||||
|
||||
uint flw_isRaining;
|
||||
float flw_rainLevel;
|
||||
uint flw_isThundering;
|
||||
float flw_thunderLevel;
|
||||
|
||||
float flw_skyDarken;
|
||||
|
||||
/** Use FLW_DIMENSION_* ids to determine the dimension. May eventually be implemented for custom dimensions. */
|
||||
uint flw_dimension;
|
||||
};
|
||||
|
||||
#define FLW_DIMENSION_OVERWORLD 0
|
||||
#define FLW_DIMENSION_NETHER 1
|
||||
#define FLW_DIMENSION_END 2
|
||||
#define FLW_DIMENSION_UNKNOWN 0xFFFFFFFFu
|
@ -0,0 +1,19 @@
|
||||
// options.glsl - Houses uniforms for many of the game's settings, focusing on video and accessibility settings.
|
||||
|
||||
layout(std140) uniform _FlwOptionsUniforms {
|
||||
float flw_brightnessOption;
|
||||
uint flw_fovOption;
|
||||
float flw_distortionOption;
|
||||
float flw_glintSpeedOption;
|
||||
float flw_glintStrengthOption;
|
||||
uint flw_biomeBlendOption;
|
||||
uint flw_smoothLightingOption;
|
||||
uint flw_viewBobbingOption;
|
||||
|
||||
uint flw_highContrastOption;
|
||||
float flw_textBackgroundOpacityOption;
|
||||
uint flw_textBackgroundForChatOnlyOption;
|
||||
float flw_darknessPulsingOption;
|
||||
float flw_damageTiltOption;
|
||||
uint hideLightningFlashesOption;
|
||||
};
|
@ -0,0 +1,37 @@
|
||||
// player.glsl - Holds uniforms for player state.
|
||||
|
||||
layout (std140) uniform _FlwPlayerUniforms {
|
||||
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. */
|
||||
uint flw_playerEyeInBlock;
|
||||
|
||||
uint flw_playerCrouching;
|
||||
uint flw_playerSleeping;
|
||||
uint flw_playerSwimming;
|
||||
uint flw_playerFallFlying;
|
||||
|
||||
uint flw_shiftKeyDown;
|
||||
|
||||
/** 0 = survival, 1 = creative, 2 = adventure, 3 = spectator. */
|
||||
uint flw_gameMode;
|
||||
};
|
||||
|
||||
#define flw_eyePos _flw_eyePos.xyz
|
||||
|
||||
#define FLW_PLAYER_EYE_IN_FLUID_WATER 1
|
||||
#define FLW_PLAYER_EYE_IN_FLUID_LAVA 2
|
||||
#define FLW_PLAYER_EYE_IN_FLUID_UNKNOWN 0xFFFFFFFFu
|
||||
|
||||
#define FLW_PLAYER_EYE_IN_BLOCK_POWDER_SNOW 1
|
||||
#define FLW_PLAYER_EYE_IN_BLOCK_UNKNOWN 0xFFFFFFFFu
|
@ -0,0 +1,7 @@
|
||||
// uniforms.glsl - Includes common uniforms.
|
||||
|
||||
#include "flywheel:internal/uniforms/frame.glsl"
|
||||
#include "flywheel:internal/uniforms/fog.glsl"
|
||||
#include "flywheel:internal/uniforms/options.glsl"
|
||||
#include "flywheel:internal/uniforms/player.glsl"
|
||||
#include "flywheel:internal/uniforms/level.glsl"
|
@ -5,8 +5,11 @@
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"refmap": "flywheel.refmap.json",
|
||||
"client": [
|
||||
"AbstractClientPlayerAccessor",
|
||||
"GameRendererAccessor",
|
||||
"GlStateManagerMixin",
|
||||
"LightTextureAccessor",
|
||||
"OptionsMixin",
|
||||
"OverlayTextureAccessor",
|
||||
"RenderSystemMixin"
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user