diff --git a/src/main/java/me/jellysquid/mods/sodium/client/SodiumClientMod.java b/src/main/java/me/jellysquid/mods/sodium/client/SodiumClientMod.java index 93fe51b19..7521f4531 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/SodiumClientMod.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/SodiumClientMod.java @@ -30,6 +30,7 @@ public class SodiumClientMod { public static boolean flywheelLoaded = false; public static boolean cclLoaded = false; + public static boolean oculusLoaded = false; public static boolean immersiveLoaded = FMLLoader.getLoadingModList().getModFileById("immersiveengineering") != null; public SodiumClientMod() { @@ -37,6 +38,8 @@ public SodiumClientMod() { MinecraftForge.EVENT_BUS.addListener(this::registerReloadListener); MOD_VERSION = ModList.get().getModContainerById(MODID).get().getModInfo().getVersion().toString(); + oculusLoaded = ModList.get().isLoaded("oculus"); + ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (a, b) -> true)); } @@ -106,4 +109,8 @@ public static String getVersion() { public static boolean isDirectMemoryAccessEnabled() { return options().advanced.allowDirectMemoryAccess; } + + public static boolean canUseVanillaVertices() { + return !SodiumClientMod.options().performance.useCompactVertexFormat && !oculusLoaded; + } } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gl/attribute/GlVertexAttributeFormat.java b/src/main/java/me/jellysquid/mods/sodium/client/gl/attribute/GlVertexAttributeFormat.java index 3e0ca9fe8..e1bb381fa 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gl/attribute/GlVertexAttributeFormat.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gl/attribute/GlVertexAttributeFormat.java @@ -9,4 +9,5 @@ public record GlVertexAttributeFormat(int typeId, int size) { public static final GlVertexAttributeFormat FLOAT = new GlVertexAttributeFormat(GL20C.GL_FLOAT, 4); public static final GlVertexAttributeFormat UNSIGNED_SHORT = new GlVertexAttributeFormat(GL20C.GL_UNSIGNED_SHORT, 2); public static final GlVertexAttributeFormat UNSIGNED_BYTE = new GlVertexAttributeFormat(GL20C.GL_UNSIGNED_BYTE, 1); + public static final GlVertexAttributeFormat UNSIGNED_INT = new GlVertexAttributeFormat(GL20C.GL_UNSIGNED_INT, 4); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gl/tessellation/TessellationBinding.java b/src/main/java/me/jellysquid/mods/sodium/client/gl/tessellation/TessellationBinding.java index 1c66e28d8..c0152c937 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gl/tessellation/TessellationBinding.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gl/tessellation/TessellationBinding.java @@ -4,10 +4,13 @@ import me.jellysquid.mods.sodium.client.gl.buffer.GlBuffer; import me.jellysquid.mods.sodium.client.gl.buffer.GlBufferTarget; +import java.util.Objects; + public record TessellationBinding(GlBufferTarget target, GlBuffer buffer, GlVertexAttributeBinding[] attributeBindings) { public static TessellationBinding forVertexBuffer(GlBuffer buffer, GlVertexAttributeBinding[] attributes) { + Objects.requireNonNull(attributes); return new TessellationBinding(GlBufferTarget.ARRAY_BUFFER, buffer, attributes); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java index 43e381d70..f2a3f4c87 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java @@ -275,6 +275,17 @@ public static OptionPage performance() { .setFlags(OptionFlag.REQUIRES_RENDERER_UPDATE) .build() ) + .add(OptionImpl.createBuilder(boolean.class, sodiumOpts) + .setName(new TranslatableText("sodium.options.use_compact_vertex_format.name")) + .setTooltip(new TranslatableText("sodium.options.use_compact_vertex_format.tooltip")) + .setControl(TickBoxControl::new) + .setImpact(OptionImpact.MEDIUM) + .setBinding((opts, value) -> { + opts.performance.useCompactVertexFormat = value; + }, opts -> opts.performance.useCompactVertexFormat) + .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD) + .build() + ) .add(OptionImpl.createBuilder(boolean.class, sodiumOpts) .setName(new TranslatableText("sodium.options.use_fog_occlusion.name")) .setTooltip(new TranslatableText("sodium.options.use_fog_occlusion.tooltip")) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java index f2bb020de..36c50e3be 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptions.java @@ -47,6 +47,7 @@ public static class PerformanceSettings { public boolean useParticleCulling = true; public boolean useFogOcclusion = true; public boolean useBlockFaceCulling = true; + public boolean useCompactVertexFormat = true; } public static class AdvancedSettings { diff --git a/src/main/java/me/jellysquid/mods/sodium/client/model/vertex/type/ChunkVertexType.java b/src/main/java/me/jellysquid/mods/sodium/client/model/vertex/type/ChunkVertexType.java index 08cbb8e68..c33e2c94d 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/model/vertex/type/ChunkVertexType.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/model/vertex/type/ChunkVertexType.java @@ -1,9 +1,8 @@ package me.jellysquid.mods.sodium.client.model.vertex.type; -import me.jellysquid.mods.sodium.client.render.chunk.format.ChunkMeshAttribute; import me.jellysquid.mods.sodium.client.render.chunk.format.ModelVertexSink; -public interface ChunkVertexType extends BlittableVertexType, CustomVertexType { +public interface ChunkVertexType> extends BlittableVertexType, CustomVertexType { /** * @return The scale to be applied to vertex coordinates */ diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderer.java index 4f0f5042f..c1ce5cbb2 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ChunkRenderer.java @@ -27,5 +27,5 @@ public interface ChunkRenderer { /** * Returns the vertex format used by this chunk render backend for rendering meshes. */ - ChunkVertexType getVertexType(); + ChunkVertexType getVertexType(); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/RegionChunkRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/RegionChunkRenderer.java index a6c0c6957..c2899dd6f 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/RegionChunkRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/RegionChunkRenderer.java @@ -3,6 +3,7 @@ import com.google.common.collect.Lists; import me.jellysquid.mods.sodium.client.SodiumClientMod; import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexAttributeBinding; +import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexFormat; import me.jellysquid.mods.sodium.client.gl.buffer.GlBufferUsage; import me.jellysquid.mods.sodium.client.gl.buffer.GlMutableBuffer; import me.jellysquid.mods.sodium.client.gl.device.CommandList; @@ -18,6 +19,8 @@ import me.jellysquid.mods.sodium.client.model.vertex.type.ChunkVertexType; import me.jellysquid.mods.sodium.client.render.chunk.data.ChunkRenderBounds; import me.jellysquid.mods.sodium.client.render.chunk.format.ChunkMeshAttribute; +import me.jellysquid.mods.sodium.client.render.chunk.format.ChunkModelVertexFormats; +import me.jellysquid.mods.sodium.client.render.chunk.format.VanillaLikeChunkMeshAttribute; import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass; import me.jellysquid.mods.sodium.client.render.chunk.region.RenderRegion; import me.jellysquid.mods.sodium.client.render.chunk.shader.ChunkShaderBindingPoints; @@ -37,19 +40,38 @@ public class RegionChunkRenderer extends ShaderChunkRenderer { private final GlMutableBuffer chunkInfoBuffer; private final boolean isBlockFaceCullingEnabled = SodiumClientMod.options().performance.useBlockFaceCulling; - public RegionChunkRenderer(RenderDevice device, ChunkVertexType vertexType) { + private GlVertexAttributeBinding[] getBindingsForType() { + if(this.vertexType != ChunkModelVertexFormats.VANILLA_LIKE) { + GlVertexFormat compactFormat = (GlVertexFormat)this.vertexFormat; + return new GlVertexAttributeBinding[] { + new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_POSITION_ID, + compactFormat.getAttribute(ChunkMeshAttribute.POSITION_ID)), + new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_COLOR, + compactFormat.getAttribute(ChunkMeshAttribute.COLOR)), + new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_BLOCK_TEXTURE, + compactFormat.getAttribute(ChunkMeshAttribute.BLOCK_TEXTURE)), + new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_TEXTURE, + compactFormat.getAttribute(ChunkMeshAttribute.LIGHT_TEXTURE)) + }; + } else { + GlVertexFormat vanillaFormat = (GlVertexFormat)this.vertexFormat; + return new GlVertexAttributeBinding[] { + new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_POSITION_ID, + vanillaFormat.getAttribute(VanillaLikeChunkMeshAttribute.POSITION)), + new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_COLOR, + vanillaFormat.getAttribute(VanillaLikeChunkMeshAttribute.COLOR)), + new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_BLOCK_TEXTURE, + vanillaFormat.getAttribute(VanillaLikeChunkMeshAttribute.BLOCK_TEX_ID)), + new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_TEXTURE, + vanillaFormat.getAttribute(VanillaLikeChunkMeshAttribute.LIGHT)), + }; + } + } + + public RegionChunkRenderer(RenderDevice device, ChunkVertexType vertexType) { super(device, vertexType); - this.vertexAttributeBindings = new GlVertexAttributeBinding[] { - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_POSITION_ID, - this.vertexFormat.getAttribute(ChunkMeshAttribute.POSITION_ID)), - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_COLOR, - this.vertexFormat.getAttribute(ChunkMeshAttribute.COLOR)), - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_BLOCK_TEXTURE, - this.vertexFormat.getAttribute(ChunkMeshAttribute.BLOCK_TEXTURE)), - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_TEXTURE, - this.vertexFormat.getAttribute(ChunkMeshAttribute.LIGHT_TEXTURE)) - }; + this.vertexAttributeBindings = getBindingsForType(); try (CommandList commandList = device.createCommandList()) { this.chunkInfoBuffer = commandList.createMutableBuffer(); diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/RenderSectionManager.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/RenderSectionManager.java index 350c110d1..110812e84 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/RenderSectionManager.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/RenderSectionManager.java @@ -11,6 +11,7 @@ import me.jellysquid.mods.sodium.client.compat.immersive.ImmersiveEmptyChunkChecker; import me.jellysquid.mods.sodium.client.gl.device.CommandList; import me.jellysquid.mods.sodium.client.gl.device.RenderDevice; +import me.jellysquid.mods.sodium.client.model.vertex.type.ChunkVertexType; import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer; import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildResult; import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuilder; @@ -103,12 +104,14 @@ public class RenderSectionManager { private final ChunkTracker tracker; public RenderSectionManager(SodiumWorldRenderer worldRenderer, BlockRenderPassManager renderPassManager, ClientWorld world, int renderDistance, CommandList commandList) { - this.chunkRenderer = new RegionChunkRenderer(RenderDevice.INSTANCE, ChunkModelVertexFormats.DEFAULT); + ChunkVertexType vertexType = SodiumClientMod.canUseVanillaVertices() ? ChunkModelVertexFormats.VANILLA_LIKE : ChunkModelVertexFormats.DEFAULT; + + this.chunkRenderer = new RegionChunkRenderer(RenderDevice.INSTANCE, vertexType); this.worldRenderer = worldRenderer; this.world = world; - this.builder = new ChunkBuilder(ChunkModelVertexFormats.DEFAULT); + this.builder = new ChunkBuilder(vertexType); this.builder.init(world, renderPassManager); this.needsUpdate = true; diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ShaderChunkRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ShaderChunkRenderer.java index d10532167..31af7a66d 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ShaderChunkRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/ShaderChunkRenderer.java @@ -18,14 +18,14 @@ public abstract class ShaderChunkRenderer implements ChunkRenderer { private final Map> programs = new Object2ObjectOpenHashMap<>(); - protected final ChunkVertexType vertexType; - protected final GlVertexFormat vertexFormat; + protected final ChunkVertexType vertexType; + protected final GlVertexFormat vertexFormat; protected final RenderDevice device; protected GlProgram activeProgram; - public ShaderChunkRenderer(RenderDevice device, ChunkVertexType vertexType) { + public ShaderChunkRenderer(RenderDevice device, ChunkVertexType vertexType) { this.device = device; this.vertexType = vertexType; this.vertexFormat = vertexType.getCustomVertexFormat(); @@ -88,7 +88,7 @@ public void delete() { } @Override - public ChunkVertexType getVertexType() { + public ChunkVertexType getVertexType() { return this.vertexType; } } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildBuffers.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildBuffers.java index 7b893d605..de322715e 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildBuffers.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildBuffers.java @@ -32,11 +32,11 @@ public class ChunkBuildBuffers { private final VertexBufferBuilder[] vertexBuffers; private final IndexBufferBuilder[][] indexBuffers; - private final ChunkVertexType vertexType; + private final ChunkVertexType vertexType; private final BlockRenderPassManager renderPassManager; - public ChunkBuildBuffers(ChunkVertexType vertexType, BlockRenderPassManager renderPassManager) { + public ChunkBuildBuffers(ChunkVertexType vertexType, BlockRenderPassManager renderPassManager) { this.vertexType = vertexType; this.renderPassManager = renderPassManager; diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/ChunkMeshAttribute.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/ChunkMeshAttribute.java index 420da9679..7bd8c34b0 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/ChunkMeshAttribute.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/ChunkMeshAttribute.java @@ -1,5 +1,8 @@ package me.jellysquid.mods.sodium.client.render.chunk.format; +/** + * The attributes used by the compact chunk vertex format. + */ public enum ChunkMeshAttribute { POSITION_ID, COLOR, diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/ChunkModelVertexFormats.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/ChunkModelVertexFormats.java index 855993b20..dcbe6f5fa 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/ChunkModelVertexFormats.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/ChunkModelVertexFormats.java @@ -1,7 +1,9 @@ package me.jellysquid.mods.sodium.client.render.chunk.format; +import me.jellysquid.mods.sodium.client.render.chunk.format.full.VanillaModelVertexType; import me.jellysquid.mods.sodium.client.render.chunk.format.sfp.ModelVertexType; public class ChunkModelVertexFormats { public static final ModelVertexType DEFAULT = new ModelVertexType(); + public static final VanillaModelVertexType VANILLA_LIKE = new VanillaModelVertexType(); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/VanillaLikeChunkMeshAttribute.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/VanillaLikeChunkMeshAttribute.java new file mode 100644 index 000000000..f71e1ad2d --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/VanillaLikeChunkMeshAttribute.java @@ -0,0 +1,8 @@ +package me.jellysquid.mods.sodium.client.render.chunk.format; + +public enum VanillaLikeChunkMeshAttribute { + POSITION, + COLOR, + BLOCK_TEX_ID, + LIGHT +} diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexBufferWriterNio.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexBufferWriterNio.java new file mode 100644 index 000000000..db90d7b31 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexBufferWriterNio.java @@ -0,0 +1,33 @@ +package me.jellysquid.mods.sodium.client.render.chunk.format.full; + +import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView; +import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterNio; +import me.jellysquid.mods.sodium.client.render.chunk.format.ChunkModelVertexFormats; +import me.jellysquid.mods.sodium.client.render.chunk.format.ModelVertexSink; + +import java.nio.ByteBuffer; + +public class VanillaModelVertexBufferWriterNio extends VertexBufferWriterNio implements ModelVertexSink { + public VanillaModelVertexBufferWriterNio(VertexBufferView backingBuffer) { + super(backingBuffer, ChunkModelVertexFormats.VANILLA_LIKE); + } + + @Override + public void writeVertex(float posX, float posY, float posZ, int color, float u, float v, int light, int chunkId) { + int i = this.writeOffset; + + ByteBuffer buffer = this.byteBuffer; + buffer.putFloat(i + 0, posX); + buffer.putFloat(i + 4, posY); + buffer.putFloat(i + 8, posZ); + buffer.putInt(i + 12, color); + + buffer.putShort(i + 16, VanillaModelVertexType.encodeBlockTexture(u)); + buffer.putShort(i + 18, VanillaModelVertexType.encodeBlockTexture(v)); + buffer.putShort(i + 20, (short) chunkId); + + buffer.putInt(i + 24, VanillaModelVertexType.encodeLightMapTexCoord(light)); + + this.advance(); + } +} diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexBufferWriterUnsafe.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexBufferWriterUnsafe.java new file mode 100644 index 000000000..7c0cfada7 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexBufferWriterUnsafe.java @@ -0,0 +1,31 @@ +package me.jellysquid.mods.sodium.client.render.chunk.format.full; + +import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView; +import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe; +import me.jellysquid.mods.sodium.client.render.chunk.format.ChunkModelVertexFormats; +import me.jellysquid.mods.sodium.client.render.chunk.format.ModelVertexSink; +import org.lwjgl.system.MemoryUtil; + +public class VanillaModelVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe implements ModelVertexSink { + public VanillaModelVertexBufferWriterUnsafe(VertexBufferView backingBuffer) { + super(backingBuffer, ChunkModelVertexFormats.VANILLA_LIKE); + } + + @Override + public void writeVertex(float posX, float posY, float posZ, int color, float u, float v, int light, int chunkId) { + long i = this.writePointer; + + MemoryUtil.memPutFloat(i + 0, posX); + MemoryUtil.memPutFloat(i + 4, posY); + MemoryUtil.memPutFloat(i + 8, posZ); + MemoryUtil.memPutInt(i + 12, color); + + MemoryUtil.memPutShort(i + 16, VanillaModelVertexType.encodeBlockTexture(u)); + MemoryUtil.memPutShort(i + 18, VanillaModelVertexType.encodeBlockTexture(v)); + MemoryUtil.memPutShort(i + 20, (short) chunkId); + + MemoryUtil.memPutInt(i + 24, VanillaModelVertexType.encodeLightMapTexCoord(light)); + + this.advance(); + } +} diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexType.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexType.java new file mode 100644 index 000000000..ad7a7fd91 --- /dev/null +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/full/VanillaModelVertexType.java @@ -0,0 +1,83 @@ +package me.jellysquid.mods.sodium.client.render.chunk.format.full; + +import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexAttributeFormat; +import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexFormat; +import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView; +import me.jellysquid.mods.sodium.client.model.vertex.type.BlittableVertexType; +import me.jellysquid.mods.sodium.client.model.vertex.type.ChunkVertexType; +import me.jellysquid.mods.sodium.client.render.chunk.format.ChunkMeshAttribute; +import me.jellysquid.mods.sodium.client.render.chunk.format.ModelVertexSink; +import me.jellysquid.mods.sodium.client.render.chunk.format.VanillaLikeChunkMeshAttribute; +import net.minecraft.client.render.VertexConsumer; + +/** + * Simple vertex format which uses single-precision floating point numbers to represent position and texture + * coordinates. + */ +public class VanillaModelVertexType implements ChunkVertexType { + public static final GlVertexFormat VERTEX_FORMAT = GlVertexFormat.builder(VanillaLikeChunkMeshAttribute.class, 28) + .addElement(VanillaLikeChunkMeshAttribute.POSITION, 0, GlVertexAttributeFormat.FLOAT, 3, false) + .addElement(VanillaLikeChunkMeshAttribute.COLOR, 12, GlVertexAttributeFormat.UNSIGNED_BYTE, 4, true) + .addElement(VanillaLikeChunkMeshAttribute.BLOCK_TEX_ID, 16, GlVertexAttributeFormat.UNSIGNED_SHORT, 4, false) + .addElement(VanillaLikeChunkMeshAttribute.LIGHT, 24, GlVertexAttributeFormat.UNSIGNED_SHORT, 2, true) + .build(); + + private static final int TEXTURE_MAX_VALUE = 65536; + + private static final float TEXTURE_SCALE = (1.0f / TEXTURE_MAX_VALUE); + + @Override + public ModelVertexSink createFallbackWriter(VertexConsumer consumer) { + throw new UnsupportedOperationException(); + } + + @Override + public ModelVertexSink createBufferWriter(VertexBufferView buffer, boolean direct) { + return direct ? new VanillaModelVertexBufferWriterUnsafe(buffer) : new VanillaModelVertexBufferWriterNio(buffer); + } + + @Override + public BlittableVertexType asBlittable() { + return this; + } + + @Override + public GlVertexFormat getCustomVertexFormat() { + return VERTEX_FORMAT; + } + + @Override + public float getTextureScale() { + return TEXTURE_SCALE; + } + + static short encodeBlockTexture(float value) { + return (short) (Math.min(0.99999997F, value) * TEXTURE_MAX_VALUE); + } + + @Override + public float getPositionOffset() { + return 0; + } + + @Override + public float getPositionScale() { + return 1; + } + + static int encodeLightMapTexCoord(int light) { + int r = light; + + // Mask off coordinate values outside 0..255 + r &= 0x00FF_00FF; + + // Light coordinates are normalized values, so upcasting requires a shift + // Scale the coordinates from the range of 0..255 (unsigned byte) into 0..65535 (unsigned short) + r <<= 8; + + // Add a half-texel offset to each coordinate so we sample from the center of each texel + r += 0x0800_0800; + + return r; + } +} diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/sfp/ModelVertexType.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/sfp/ModelVertexType.java index 7e11585df..746b16da9 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/sfp/ModelVertexType.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/format/sfp/ModelVertexType.java @@ -13,7 +13,7 @@ * Simple vertex format which uses single-precision floating point numbers to represent position and texture * coordinates. */ -public class ModelVertexType implements ChunkVertexType { +public class ModelVertexType implements ChunkVertexType { public static final GlVertexFormat VERTEX_FORMAT = GlVertexFormat.builder(ChunkMeshAttribute.class, 20) .addElement(ChunkMeshAttribute.POSITION_ID, 0, GlVertexAttributeFormat.UNSIGNED_SHORT, 4, false) .addElement(ChunkMeshAttribute.COLOR, 8, GlVertexAttributeFormat.UNSIGNED_BYTE, 4, true) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/region/RenderRegion.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/region/RenderRegion.java index fefbe7c70..3949ff644 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/region/RenderRegion.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/region/RenderRegion.java @@ -8,6 +8,7 @@ import me.jellysquid.mods.sodium.client.gl.arena.staging.StagingBuffer; import me.jellysquid.mods.sodium.client.gl.device.CommandList; import me.jellysquid.mods.sodium.client.gl.tessellation.GlTessellation; +import me.jellysquid.mods.sodium.client.model.vertex.type.ChunkVertexType; import me.jellysquid.mods.sodium.client.util.frustum.Frustum; import me.jellysquid.mods.sodium.client.render.chunk.RenderSection; import me.jellysquid.mods.sodium.client.render.chunk.format.ChunkModelVertexFormats; @@ -151,7 +152,9 @@ public RenderRegionArenas(CommandList commandList, StagingBuffer stagingBuffer) int expectedVertexCount = REGION_SIZE * 756; int expectedIndexCount = (expectedVertexCount / 4) * 6; - this.vertexBuffers = createArena(commandList, expectedVertexCount * ChunkModelVertexFormats.DEFAULT.getBufferVertexFormat().getStride(), stagingBuffer); + ChunkVertexType vType = SodiumClientMod.canUseVanillaVertices() ? ChunkModelVertexFormats.VANILLA_LIKE : ChunkModelVertexFormats.DEFAULT; + + this.vertexBuffers = createArena(commandList, expectedVertexCount * vType.getBufferVertexFormat().getStride(), stagingBuffer); this.indexBuffers = createArena(commandList, expectedIndexCount * 4, stagingBuffer); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/shader/ChunkShaderOptions.java b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/shader/ChunkShaderOptions.java index 969d1bf48..d65d72f0f 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/shader/ChunkShaderOptions.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/shader/ChunkShaderOptions.java @@ -2,6 +2,7 @@ import me.jellysquid.mods.sodium.client.gl.shader.ShaderConstants; import me.jellysquid.mods.sodium.client.model.vertex.type.ChunkVertexType; +import me.jellysquid.mods.sodium.client.render.chunk.format.ChunkModelVertexFormats; import me.jellysquid.mods.sodium.client.render.chunk.passes.BlockRenderPass; public record ChunkShaderOptions(ChunkFogMode fog, BlockRenderPass pass, ChunkVertexType vertexType) { @@ -13,7 +14,8 @@ public ShaderConstants constants() { constants.add("ALPHA_CUTOFF", String.valueOf(this.pass.getAlphaCutoff())); } - constants.add("USE_VERTEX_COMPRESSION"); // TODO: allow compact vertex format to be disabled + if(vertexType != ChunkModelVertexFormats.VANILLA_LIKE) + constants.add("USE_VERTEX_COMPRESSION"); constants.add("VERT_POS_SCALE", String.valueOf(this.vertexType.getPositionScale())); constants.add("VERT_POS_OFFSET", String.valueOf(this.vertexType.getPositionOffset())); constants.add("VERT_TEX_SCALE", String.valueOf(this.vertexType.getTextureScale())); diff --git a/src/main/resources/assets/sodium/lang/en_us.json b/src/main/resources/assets/sodium/lang/en_us.json index 89a14775d..e98e17543 100644 --- a/src/main/resources/assets/sodium/lang/en_us.json +++ b/src/main/resources/assets/sodium/lang/en_us.json @@ -34,6 +34,8 @@ "sodium.options.mipmap_levels.tooltip": "Controls the number of mipmaps which will be used for block model textures. Higher values provide better rendering of blocks in the distance, but may adversely affect performance with many animated textures.", "sodium.options.use_block_face_culling.name": "Use Block Face Culling", "sodium.options.use_block_face_culling.tooltip": "If enabled, only the sides of blocks which are facing the camera will be submitted for rendering. This can eliminate a large number of block faces very early in the rendering process, saving memory bandwidth and time on the GPU. Some resource packs may have issues with this option, so try disabling it if you're seeing holes in blocks.", + "sodium.options.use_compact_vertex_format.name": "Use Compact Vertex Format", + "sodium.options.use_compact_vertex_format.tooltip": "If enabled, a more compact vertex format will be used for rendering chunks. This can reduce graphics memory usage and bandwidth requirements significantly, especially for integrated graphics cards, but can cause z-fighting with some resource packs due to how it reduces the precision of position and texture coordinate attributes. Disabling this has no effect if Oculus is installed.", "sodium.options.use_fog_occlusion.name": "Use Fog Occlusion", "sodium.options.use_fog_occlusion.tooltip": "If enabled, chunks which are determined to be fully hidden by fog effects will not be rendered, helping to improve performance. The improvement can be more dramatic when fog effects are heavier (such as while underwater), but it may cause undesirable visual artifacts between the sky and fog in some scenarios.", "sodium.options.use_entity_culling.name": "Use Entity Culling", diff --git a/src/main/resources/assets/sodium/shaders/include/chunk_vertex.glsl b/src/main/resources/assets/sodium/shaders/include/chunk_vertex.glsl index e6296e919..676135889 100644 --- a/src/main/resources/assets/sodium/shaders/include/chunk_vertex.glsl +++ b/src/main/resources/assets/sodium/shaders/include/chunk_vertex.glsl @@ -37,7 +37,19 @@ void _vert_init() { } #else -#error "Vertex compression must be enabled" +in vec3 a_PosId; +in vec4 a_Color; +in vec4 a_TexCoord; +in vec2 a_LightCoord; + +void _vert_init() { + _vert_position = a_PosId; + _vert_tex_diffuse_coord = (a_TexCoord.xy * VERT_TEX_SCALE); + _vert_tex_light_coord = a_LightCoord; + _vert_color = a_Color; + + _draw_id = uint(a_TexCoord.z); +} #endif // The translation vector of the current draw command