diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java
index 14310c962..86e43e77b 100644
--- a/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java
@@ -30,7 +30,7 @@ public interface DynamicInstance extends Instance {
*
You might want to opt out of this if you want your animations to remain smooth
* even when far away from the camera. It is recommended to keep this as is, however.
*
- * @return true
if your instance should be slow ticked.
+ * @return {@code true} if your instance should be slow ticked.
*/
default boolean decreaseFramerateWithDistance() {
return true;
diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java
index efb2fedb1..488ba8697 100644
--- a/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java
@@ -38,7 +38,7 @@ public interface TickableInstance extends Instance {
*
You might want to opt out of this if you want your animations to remain smooth
* even when far away from the camera. It is recommended to keep this as is, however.
*
- * @return true
if your instance should be slow ticked.
+ * @return {@code true} if your instance should be slow ticked.
*/
default boolean decreaseTickRateWithDistance() {
return true;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java
index bffbddc46..2285f5684 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java
@@ -1,10 +1,6 @@
package com.jozufozu.flywheel.backend;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import javax.annotation.Nullable;
@@ -55,7 +51,7 @@ public class Backend {
* (Meshlet, MDI, GL31 Draw Instanced are planned), this will name which one is in use.
*/
public String getBackendDescriptor() {
- return engine.getProperName();
+ return engine == null ? "" : engine.getProperName();
}
public FlwEngine getEngine() {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java
index f003208fe..51e60eebe 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java
@@ -4,7 +4,11 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.util.Optional;
+import java.util.function.BooleanSupplier;
+
+import com.jozufozu.flywheel.util.Lazy;
import net.minecraft.client.Minecraft;
@@ -15,6 +19,23 @@ public class OptifineHandler {
private static Package optifine;
private static OptifineHandler handler;
+ private static final Lazy isShadowPass = Lazy.of(() -> {
+ try {
+ Class> ofShaders = Class.forName("net.optifine.shaders.Shaders");
+ Field field = ofShaders.getDeclaredField("isShadowPass");
+ field.setAccessible(true);
+ return () -> {
+ try {
+ return field.getBoolean(null);
+ } catch (IllegalAccessException ignored) {
+ return false;
+ }
+ };
+ } catch (Exception ignored) {
+ return () -> false;
+ }
+ });
+
public final boolean usingShaders;
public OptifineHandler(boolean usingShaders) {
@@ -40,6 +61,10 @@ public class OptifineHandler {
.orElse(false);
}
+ public static boolean isShadowPass() {
+ return isShadowPass.get().getAsBoolean();
+ }
+
public static void init() {
optifine = Package.getPackage(OPTIFINE_ROOT_PACKAGE);
diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java
index 1ec315fa9..4f194e5d9 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java
@@ -12,10 +12,17 @@ public class GlVertexArray extends GlObject {
setHandle(GlStateManager._glGenVertexArrays());
}
+ public static void bind(int vao) {
+ GlStateManager._glBindVertexArray(vao);
+ BufferUploaderAccessor.flywheel$setLastVAO(vao);
+ }
+
public void bind() {
- int handle = handle();
- GlStateManager._glBindVertexArray(handle);
- BufferUploaderAccessor.flywheel$setLastVAO(handle);
+ bind(handle());
+ }
+
+ public static int getBoundVertexArray() {
+ return BufferUploaderAccessor.flywheel$getLastVAO();
}
public static void unbind() {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java
index 53a0ab9ac..16f0c450a 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/GlBufferType.java
@@ -50,4 +50,12 @@ public enum GlBufferType {
case GL15C.GL_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$setLastVBO(0);
}
}
+
+ public int getBoundBuffer() {
+ return switch (this.glEnum) {
+ case GL15C.GL_ELEMENT_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$getLastEBO();
+ case GL15C.GL_ARRAY_BUFFER -> BufferUploaderAccessor.flywheel$getLastVBO();
+ default -> -1;
+ };
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlVersioned.java b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlVersioned.java
index d019832b7..8615e9086 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlVersioned.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/gl/versioned/GlVersioned.java
@@ -4,7 +4,7 @@ import org.lwjgl.opengl.GLCapabilities;
/**
* This interface should be implemented by enums such that the
- * last defined variant always returns true
.
+ * last defined variant always returns {@code true}
*/
public interface GlVersioned {
/**
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java
index 1a2ebb781..6a3e67ba8 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java
@@ -65,13 +65,13 @@ public abstract class AbstractInstance implements Instance, LightListener {
* When an instance is reset, the instance is deleted and re-created.
*
*
- * Just before {@link #update()} would be called, shouldReset()
is checked.
- * If this function returns true
, then this instance will be {@link #remove removed},
+ * Just before {@link #update()} would be called, {@code shouldReset()} is checked.
+ * If this function returns {@code true}, then this instance will be {@link #remove removed},
* and another instance will be constructed to replace it. This allows for more sane resource
* acquisition compared to trying to update everything within the lifetime of an instance.
*
*
- * @return true
if this instance should be discarded and refreshed.
+ * @return {@code true} if this instance should be discarded and refreshed.
*/
public boolean shouldReset() {
return false;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java
index 1f4c7200c..8274a2e06 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java
@@ -90,12 +90,12 @@ public class InstanceWorld {
*
*/
public void beginFrame(BeginFrameEvent event) {
- engine.beginFrame(event.getInfo());
+ engine.beginFrame(event.getCamera());
taskEngine.syncPoint();
- blockEntityInstanceManager.beginFrame(taskEngine, event.getInfo());
- entityInstanceManager.beginFrame(taskEngine, event.getInfo());
+ blockEntityInstanceManager.beginFrame(taskEngine, event.getCamera());
+ entityInstanceManager.beginFrame(taskEngine, event.getCamera());
}
/**
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java
index 11925664f..ed4313063 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java
@@ -48,12 +48,12 @@ public abstract class BlockEntityInstance extends Abstrac
}
/**
- * Just before {@link #update()} would be called, shouldReset()
is checked.
- * If this function returns true
, then this instance will be {@link #remove removed},
+ * Just before {@link #update()} would be called, {@code shouldReset()} is checked.
+ * If this function returns {@code true}, then this instance will be {@link #remove removed},
* and another instance will be constructed to replace it. This allows for more sane resource
* acquisition compared to trying to update everything within the lifetime of an instance.
*
- * @return true
if this instance should be discarded and refreshed.
+ * @return {@code true} if this instance should be discarded and refreshed.
*/
public boolean shouldReset() {
return blockEntity.getBlockState() != blockState;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
index a617e0e0e..513840e0a 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
@@ -80,6 +80,10 @@ public class InstancingEngine implements Engine {
*/
@Override
public void render(TaskEngine taskEngine, RenderLayerEvent event) {
+ int ebo = GlBufferType.ELEMENT_ARRAY_BUFFER.getBoundBuffer();
+ int vbo = GlBufferType.ARRAY_BUFFER.getBoundBuffer();
+ int vao = GlVertexArray.getBoundVertexArray();
+
double camX;
double camY;
double camZ;
@@ -100,9 +104,9 @@ public class InstancingEngine
implements Engine {
getGroupsToRender(event.getLayer()).forEach(group -> group.render(viewProjection, camX, camY, camZ));
- GlBufferType.ELEMENT_ARRAY_BUFFER.unbind();
- GlBufferType.ARRAY_BUFFER.unbind();
- GlVertexArray.unbind();
+ GlBufferType.ELEMENT_ARRAY_BUFFER.bind(ebo);
+ GlBufferType.ARRAY_BUFFER.bind(vbo);
+ GlVertexArray.bind(vao);
}
private Stream> getGroupsToRender(@Nullable RenderLayer layer) {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/source/SourceFile.java b/src/main/java/com/jozufozu/flywheel/backend/source/SourceFile.java
index ab055553d..24a8d1836 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/source/SourceFile.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/source/SourceFile.java
@@ -217,7 +217,7 @@ public class SourceFile {
}
/**
- * Scan the source for #use "..."
directives.
+ * Scan the source for {@code #use "..."} directives.
* Records the contents of the directive into an {@link Import} object, and marks the directive for elision.
* @param elisions
*/
diff --git a/src/main/java/com/jozufozu/flywheel/core/LastActiveCamera.java b/src/main/java/com/jozufozu/flywheel/core/LastActiveCamera.java
new file mode 100644
index 000000000..0d47d3c66
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/core/LastActiveCamera.java
@@ -0,0 +1,16 @@
+package com.jozufozu.flywheel.core;
+
+import net.minecraft.client.Camera;
+
+public class LastActiveCamera {
+
+ private static Camera camera;
+
+ public static void _setActiveCamera(Camera camera) {
+ LastActiveCamera.camera = camera;
+ }
+
+ public static Camera getActiveCamera() {
+ return camera;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java b/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java
index 038a7250a..3829a1a84 100644
--- a/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java
+++ b/src/main/java/com/jozufozu/flywheel/core/materials/FlatLit.java
@@ -14,14 +14,14 @@ public interface FlatLit> {
/**
* @param blockLight An integer in the range [0, 15] representing the
* amount of block light this instance should receive.
- * @return this
+ * @return {@code this}
*/
D setBlockLight(int blockLight);
/**
* @param skyLight An integer in the range [0, 15] representing the
* amount of sky light this instance should receive.
- * @return this
+ * @return {@code this}
*/
D setSkyLight(int skyLight);
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java
index b3e96aa7d..c350361c9 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java
@@ -16,7 +16,7 @@ public class WorldModel implements Model {
private final String name;
/**
- * It is expected that renderWorld.getShade(...)
returns a constant.
+ * It is expected that {@code renderWorld.getShade(...)} returns a constant.
*/
public WorldModel(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks, String name) {
reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks));
diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/spec/ProgramSpec.java b/src/main/java/com/jozufozu/flywheel/core/shader/spec/ProgramSpec.java
index 3716caef2..e293a2732 100644
--- a/src/main/java/com/jozufozu/flywheel/core/shader/spec/ProgramSpec.java
+++ b/src/main/java/com/jozufozu/flywheel/core/shader/spec/ProgramSpec.java
@@ -15,11 +15,11 @@ import net.minecraft.resources.ResourceLocation;
* An object describing a shader program that can be loaded by flywheel.
*
*
- * These are defined through json. All ProgramSpecs in assets/modid/flywheel/programs
are parsed and
+ * These are defined through json. All ProgramSpecs in {@code assets/modid/flywheel/programs} are parsed and
* processed. One ProgramSpec typically specifies one "material" that can be used in game to render things.
*
*
- * All shader source files in assets/modid/flywheel/shaders
are completely loaded and parsed into
+ * All shader source files in {@code assets/modid/flywheel/shaders} are completely loaded and parsed into
* {@link SourceFile SourceFiles}, but not compiled until one of them is
* referenced by a ProgramSpec.
*
diff --git a/src/main/java/com/jozufozu/flywheel/event/BeginFrameEvent.java b/src/main/java/com/jozufozu/flywheel/event/BeginFrameEvent.java
index e6ca8c36b..a6479e3e2 100644
--- a/src/main/java/com/jozufozu/flywheel/event/BeginFrameEvent.java
+++ b/src/main/java/com/jozufozu/flywheel/event/BeginFrameEvent.java
@@ -9,28 +9,28 @@ import net.minecraft.world.phys.Vec3;
public class BeginFrameEvent extends EventContext {
private final ClientLevel world;
- private final Camera info;
- private final Frustum clippingHelper;
+ private final Camera camera;
+ private final Frustum frustum;
- public BeginFrameEvent(ClientLevel world, Camera info, Frustum clippingHelper) {
+ public BeginFrameEvent(ClientLevel world, Camera camera, Frustum frustum) {
this.world = world;
- this.info = info;
- this.clippingHelper = clippingHelper;
+ this.camera = camera;
+ this.frustum = frustum;
}
public ClientLevel getWorld() {
return world;
}
- public Camera getInfo() {
- return info;
+ public Camera getCamera() {
+ return camera;
}
- public Frustum getClippingHelper() {
- return clippingHelper;
+ public Frustum getFrustum() {
+ return frustum;
}
public Vec3 getCameraPos() {
- return info.getPosition();
+ return camera.getPosition();
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderAccessor.java b/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderAccessor.java
index 64b81bd2b..f7d609805 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderAccessor.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/BufferUploaderAccessor.java
@@ -21,4 +21,19 @@ public interface BufferUploaderAccessor {
static void flywheel$setLastEBO(int id) {
throw new AssertionError();
}
+
+ @Accessor("lastIndexBufferObject")
+ static int flywheel$getLastEBO() {
+ throw new AssertionError();
+ }
+
+ @Accessor("lastVertexBufferObject")
+ static int flywheel$getLastVBO() {
+ throw new AssertionError();
+ }
+
+ @Accessor("lastVertexArrayObject")
+ static int flywheel$getLastVAO() {
+ throw new AssertionError();
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/CameraMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/CameraMixin.java
new file mode 100644
index 000000000..52e6043ef
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/CameraMixin.java
@@ -0,0 +1,21 @@
+package com.jozufozu.flywheel.mixin;
+
+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.jozufozu.flywheel.core.LastActiveCamera;
+
+import net.minecraft.client.Camera;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.level.BlockGetter;
+
+@Mixin(Camera.class)
+public class CameraMixin {
+
+ @Inject(method = "setup", at = @At("TAIL"))
+ private void setup(BlockGetter level, Entity entity, boolean is3rdPerson, boolean isMirrored, float pt, CallbackInfo ci) {
+ LastActiveCamera._setActiveCamera((Camera)(Object) this);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java
new file mode 100644
index 000000000..7f7ceded0
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java
@@ -0,0 +1,25 @@
+package com.jozufozu.flywheel.mixin;
+
+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.jozufozu.flywheel.backend.OptifineHandler;
+import com.jozufozu.flywheel.core.LastActiveCamera;
+import com.jozufozu.flywheel.event.BeginFrameEvent;
+import com.jozufozu.flywheel.fabric.event.FlywheelEvents;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.culling.Frustum;
+
+@Mixin(Frustum.class)
+public class FrustumMixin {
+
+ @Inject(method = "prepare", at = @At("TAIL"))
+ private void onPrepare(double x, double y, double z, CallbackInfo ci) {
+ if (OptifineHandler.isShadowPass()) {
+ FlywheelEvents.BEGIN_FRAME.invoker().handleEvent(new BeginFrameEvent(Minecraft.getInstance().level, LastActiveCamera.getActiveCamera(), (Frustum) (Object) this));
+ }
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/RenderHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java
similarity index 95%
rename from src/main/java/com/jozufozu/flywheel/mixin/RenderHooksMixin.java
rename to src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java
index b20a6eac2..981f8757e 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/RenderHooksMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java
@@ -30,7 +30,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
@Mixin(LevelRenderer.class)
-public class RenderHooksMixin {
+public class LevelRendererMixin {
@Shadow
private ClientLevel level;
@@ -49,7 +49,7 @@ public class RenderHooksMixin {
* layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects.
* This should probably be a forge event.
*/
- @Inject(at = @At("TAIL"), method = "renderChunkLayer")
+ @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ShaderInstance;clear()V"), method = "renderChunkLayer")
private void renderLayer(RenderType type, PoseStack stack, double camX, double camY, double camZ, Matrix4f p_172999_, CallbackInfo ci) {
RenderBuffers renderBuffers = this.renderBuffers;
diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json
index 64b2e922c..1af7bff1d 100644
--- a/src/main/resources/flywheel.mixins.json
+++ b/src/main/resources/flywheel.mixins.json
@@ -1,33 +1,35 @@
{
- "required": true,
- "minVersion": "0.8",
- "package": "com.jozufozu.flywheel.mixin",
- "compatibilityLevel": "JAVA_17",
- "client": [
- "BlockEntityTypeMixin",
- "BufferBuilderMixin",
- "BufferUploaderAccessor",
- "CancelEntityRenderMixin",
- "ChunkRebuildHooksMixin",
- "EntityTypeMixin",
- "FixFabulousDepthMixin",
- "InstanceAddMixin",
- "InstanceRemoveMixin",
- "LevelRendererAccessor",
- "PausedPartialTickAccessor",
- "RenderHooksMixin",
- "RenderTexturesMixin",
- "ShaderCloseMixin",
- "ShaderInstanceAccessor",
- "atlas.AtlasDataMixin",
- "atlas.SheetDataAccessor",
- "light.LightUpdateMixin",
- "light.NetworkLightUpdateMixin",
- "matrix.Matrix3fMixin",
- "matrix.Matrix4fMixin",
- "matrix.PoseStackMixin"
- ],
- "injectors": {
- "defaultRequire": 1
- }
+ "required": true,
+ "minVersion": "0.8",
+ "package": "com.jozufozu.flywheel.mixin",
+ "compatibilityLevel": "JAVA_17",
+ "client": [
+ "BlockEntityTypeMixin",
+ "BufferBuilderMixin",
+ "BufferUploaderAccessor",
+ "CameraMixin",
+ "CancelEntityRenderMixin",
+ "ChunkRebuildHooksMixin",
+ "EntityTypeMixin",
+ "FixFabulousDepthMixin",
+ "FrustumMixin",
+ "InstanceAddMixin",
+ "InstanceRemoveMixin",
+ "LevelRendererAccessor",
+ "LevelRendererMixin",
+ "PausedPartialTickAccessor",
+ "RenderTexturesMixin",
+ "ShaderCloseMixin",
+ "ShaderInstanceAccessor",
+ "atlas.AtlasDataMixin",
+ "atlas.SheetDataAccessor",
+ "light.LightUpdateMixin",
+ "light.NetworkLightUpdateMixin",
+ "matrix.Matrix3fMixin",
+ "matrix.Matrix4fMixin",
+ "matrix.PoseStackMixin"
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
}