Skip to content

Commit

Permalink
Revert to 20-byte vertex format
Browse files Browse the repository at this point in the history
  • Loading branch information
jellysquid3 committed Jan 18, 2024
1 parent 4da6b37 commit 53a673d
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,14 @@ private GlTessellation prepareTessellation(CommandList commandList, RenderRegion
private GlTessellation createRegionTessellation(CommandList commandList, RenderRegion.DeviceResources resources) {
return commandList.createTessellation(GlPrimitiveType.TRIANGLES, new TessellationBinding[] {
TessellationBinding.forVertexBuffer(resources.getVertexBuffer(), new GlVertexAttributeBinding[] {
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_PACKED_DATA,
this.vertexFormat.getAttribute(ChunkMeshAttribute.VERTEX_DATA))
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_POSITION_ID,
this.vertexFormat.getAttribute(ChunkMeshAttribute.POSITION_MATERIAL_MESH)),
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_COLOR,
this.vertexFormat.getAttribute(ChunkMeshAttribute.COLOR_SHADE)),
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_BLOCK_TEXTURE,
this.vertexFormat.getAttribute(ChunkMeshAttribute.BLOCK_TEXTURE)),
new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_TEXTURE,
this.vertexFormat.getAttribute(ChunkMeshAttribute.LIGHT_TEXTURE))
}),
TessellationBinding.forElementBuffer(this.sharedIndexBuffer.getBufferObject())
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ private GlProgram<ChunkShaderInterface> createShader(String path, ChunkShaderOpt
return GlProgram.builder(new Identifier("sodium", "chunk_shader"))
.attachShader(vertShader)
.attachShader(fragShader)
.bindAttribute("in_VertexData", ChunkShaderBindingPoints.ATTRIBUTE_PACKED_DATA)
.bindFragmentData("out_FragColor", ChunkShaderBindingPoints.FRAG_COLOR)
.bindAttribute("a_PosId", ChunkShaderBindingPoints.ATTRIBUTE_POSITION_ID)
.bindAttribute("a_Color", ChunkShaderBindingPoints.ATTRIBUTE_COLOR)
.bindAttribute("a_TexCoord", ChunkShaderBindingPoints.ATTRIBUTE_BLOCK_TEXTURE)
.bindAttribute("a_LightCoord", ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_TEXTURE)
.bindFragmentData("fragColor", ChunkShaderBindingPoints.FRAG_COLOR)
.link((shader) -> new ChunkShaderInterface(shader, options));
} finally {
vertShader.delete();
Expand All @@ -64,7 +67,7 @@ private GlProgram<ChunkShaderInterface> createShader(String path, ChunkShaderOpt
protected void begin(TerrainRenderPass pass) {
pass.startDrawing();

ChunkShaderOptions options = new ChunkShaderOptions(ChunkFogMode.SMOOTH, pass);
ChunkShaderOptions options = new ChunkShaderOptions(ChunkFogMode.SMOOTH, pass, this.vertexType);

this.activeProgram = this.compileProgram(options);
this.activeProgram.bind();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package me.jellysquid.mods.sodium.client.render.chunk.shader;

public class ChunkShaderBindingPoints {
public static final int ATTRIBUTE_PACKED_DATA = 1;
public static final int ATTRIBUTE_POSITION_ID = 1;
public static final int ATTRIBUTE_COLOR = 2;
public static final int ATTRIBUTE_BLOCK_TEXTURE = 3;
public static final int ATTRIBUTE_LIGHT_TEXTURE = 4;

public static final int FRAG_COLOR = 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import me.jellysquid.mods.sodium.client.gl.shader.ShaderConstants;
import me.jellysquid.mods.sodium.client.render.chunk.terrain.TerrainRenderPass;
import me.jellysquid.mods.sodium.client.render.chunk.vertex.format.ChunkVertexType;

public record ChunkShaderOptions(ChunkFogMode fog, TerrainRenderPass pass) {
public record ChunkShaderOptions(ChunkFogMode fog, TerrainRenderPass pass, ChunkVertexType vertexType) {
public ShaderConstants constants() {
ShaderConstants.Builder constants = ShaderConstants.builder();
constants.addAll(this.fog.getDefines());
Expand All @@ -12,6 +13,11 @@ public ShaderConstants constants() {
constants.add("USE_FRAGMENT_DISCARD");
}

constants.add("USE_VERTEX_COMPRESSION"); // TODO: allow compact vertex format to be disabled
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()));

return constants.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package me.jellysquid.mods.sodium.client.render.chunk.vertex.format;

public enum ChunkMeshAttribute {
VERTEX_DATA
POSITION_MATERIAL_MESH,
COLOR_SHADE,
BLOCK_TEXTURE,
LIGHT_TEXTURE
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexFormat;

public interface ChunkVertexType {
/**
* @return The scale to be applied to vertex coordinates
*/
float getPositionScale();

/**
* @return The translation to be applied to vertex coordinates
*/
float getPositionOffset();

/**
* @return The scale to be applied to texture coordinates
*/
float getTextureScale();

GlVertexFormat<ChunkMeshAttribute> getVertexFormat();

ChunkVertexEncoder getEncoder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,45 @@

import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexAttributeFormat;
import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexFormat;
import me.jellysquid.mods.sodium.client.render.chunk.terrain.material.Material;
import me.jellysquid.mods.sodium.client.render.chunk.vertex.format.ChunkMeshAttribute;
import me.jellysquid.mods.sodium.client.render.chunk.vertex.format.ChunkVertexEncoder;
import me.jellysquid.mods.sodium.client.render.chunk.vertex.format.ChunkVertexType;
import net.caffeinemc.mods.sodium.api.util.ColorABGR;
import net.caffeinemc.mods.sodium.api.util.ColorU8;
import org.lwjgl.system.MemoryUtil;

public class CompactChunkVertex implements ChunkVertexType {
public static final GlVertexFormat<ChunkMeshAttribute> VERTEX_FORMAT = GlVertexFormat.builder(ChunkMeshAttribute.class, 16)
.addElement(ChunkMeshAttribute.VERTEX_DATA, 0, GlVertexAttributeFormat.UNSIGNED_INT, 4, false, true)
public static final GlVertexFormat<ChunkMeshAttribute> VERTEX_FORMAT = GlVertexFormat.builder(ChunkMeshAttribute.class, 20)
.addElement(ChunkMeshAttribute.POSITION_MATERIAL_MESH, 0, GlVertexAttributeFormat.UNSIGNED_SHORT, 4, false, true)
.addElement(ChunkMeshAttribute.COLOR_SHADE, 8, GlVertexAttributeFormat.UNSIGNED_BYTE, 4, true, false)
.addElement(ChunkMeshAttribute.BLOCK_TEXTURE, 12, GlVertexAttributeFormat.UNSIGNED_SHORT, 2, false, false)
.addElement(ChunkMeshAttribute.LIGHT_TEXTURE, 16, GlVertexAttributeFormat.UNSIGNED_SHORT, 2, false, true)
.build();

public static final int STRIDE = 16;
public static final int STRIDE = 20;

private static final int POSITION_MAX_VALUE = 65536;
private static final int TEXTURE_MAX_VALUE = 32768;

private static final float MODEL_ORIGIN = 8.0f;
private static final float MODEL_SCALE = 32.0f;
private static final float MODEL_RANGE = 32.0f;
private static final float MODEL_SCALE = MODEL_RANGE / POSITION_MAX_VALUE;
private static final float MODEL_SCALE_INV = POSITION_MAX_VALUE / MODEL_RANGE;

private static final float TEXTURE_SCALE = (1.0f / TEXTURE_MAX_VALUE);

@Override
public float getTextureScale() {
return TEXTURE_SCALE;
}

@Override
public float getPositionScale() {
return MODEL_SCALE;
}

@Override
public float getPositionOffset() {
return -MODEL_ORIGIN;
}

@Override
public GlVertexFormat<ChunkMeshAttribute> getVertexFormat() {
Expand All @@ -31,42 +50,29 @@ public GlVertexFormat<ChunkMeshAttribute> getVertexFormat() {
@Override
public ChunkVertexEncoder getEncoder() {
return (ptr, material, vertex, sectionIndex) -> {
MemoryUtil.memPutInt(ptr + 0, (encodePosition(vertex.x) << 0) | (encodePosition(vertex.y) << 16));
MemoryUtil.memPutInt(ptr + 4, (encodePosition(vertex.z) << 0) | (encodeDrawParameters(material, sectionIndex) << 16));
MemoryUtil.memPutInt(ptr + 8, (encodeColor(vertex.color) << 0) | (encodeLight(vertex.light) << 24));
MemoryUtil.memPutInt(ptr + 12, encodeTexture(vertex.u, vertex.v));
MemoryUtil.memPutShort(ptr + 0, encodePosition(vertex.x));
MemoryUtil.memPutShort(ptr + 2, encodePosition(vertex.y));
MemoryUtil.memPutShort(ptr + 4, encodePosition(vertex.z));

return ptr + STRIDE;
};
}
MemoryUtil.memPutByte(ptr + 6, (byte) (material.bits() & 0xFF));
MemoryUtil.memPutByte(ptr + 7, (byte) (sectionIndex & 0xFF));

private static int encodePosition(float value) {
return (int) ((MODEL_ORIGIN + value) * (POSITION_MAX_VALUE / MODEL_SCALE));
}
MemoryUtil.memPutInt(ptr + 8, vertex.color);

private static int encodeDrawParameters(Material material, int sectionIndex) {
return (((sectionIndex & 0xFF) << 8) | ((material.bits() & 0xFF) << 0));
}
MemoryUtil.memPutShort(ptr + 12, encodeTexture(vertex.u));
MemoryUtil.memPutShort(ptr + 14, encodeTexture(vertex.v));

private static int encodeColor(int color) {
var brightness = ColorU8.byteToNormalizedFloat(ColorABGR.unpackAlpha(color));
MemoryUtil.memPutInt(ptr + 16, vertex.light);

int r = ColorU8.normalizedFloatToByte(ColorU8.byteToNormalizedFloat(ColorABGR.unpackRed(color)) * brightness);
int g = ColorU8.normalizedFloatToByte(ColorU8.byteToNormalizedFloat(ColorABGR.unpackGreen(color)) * brightness);
int b = ColorU8.normalizedFloatToByte(ColorU8.byteToNormalizedFloat(ColorABGR.unpackBlue(color)) * brightness);

return ColorABGR.pack(r, g, b, 0x00);
return ptr + STRIDE;
};
}

private static int encodeLight(int light) {
int block = (light >> 4) & 0xF;
int sky = (light >> 20) & 0xF;

return ((block << 0) | (sky << 4));
private static short encodePosition(float v) {
return (short) ((MODEL_ORIGIN + v) * MODEL_SCALE_INV);
}

private static int encodeTexture(float u, float v) {
return ((Math.round(u * TEXTURE_MAX_VALUE) & 0xFFFF) << 0) |
((Math.round(v * TEXTURE_MAX_VALUE) & 0xFFFF) << 16);
private static short encodeTexture(float value) {
return (short) (Math.round(value * TEXTURE_MAX_VALUE) & 0xFFFF);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@

#import <sodium:include/fog.glsl>

in vec3 v_ColorModulator; // The interpolated vertex color
in vec4 v_Color; // The interpolated vertex color
in vec2 v_TexCoord; // The interpolated block texture coordinates

in float v_FragDistance; // The fragment's distance from the camera

in float v_MaterialMipBias;
in float v_MaterialAlphaCutoff;

uniform sampler2D u_BlockTex; // The block atlas texture
uniform sampler2D u_BlockTex; // The block texture

uniform vec4 u_FogColor; // The color of the shader fog
uniform float u_FogStart; // The starting position of the shader fog
uniform float u_FogEnd; // The ending position of the shader fog

out vec4 out_FragColor; // The output fragment for the color framebuffer
out vec4 fragColor; // The output fragment for the color framebuffer

void main() {
vec4 diffuseColor = texture(u_BlockTex, v_TexCoord, v_MaterialMipBias);
Expand All @@ -27,8 +26,11 @@ void main() {
}
#endif

// Modulate the color (used by ambient occlusion and per-vertex colouring)
diffuseColor.rgb *= v_ColorModulator;
// Apply per-vertex color
diffuseColor.rgb *= v_Color.rgb;

// Apply ambient occlusion "shade"
diffuseColor.rgb *= v_Color.a;

out_FragColor = _linearFog(diffuseColor, v_FragDistance, u_FogColor, u_FogStart, u_FogEnd);
fragColor = _linearFog(diffuseColor, v_FragDistance, u_FogColor, u_FogStart, u_FogEnd);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#import <sodium:include/chunk_matrices.glsl>
#import <sodium:include/chunk_material.glsl>

out vec3 v_ColorModulator;
out vec4 v_Color;
out vec2 v_TexCoord;

out float v_MaterialMipBias;
Expand All @@ -18,26 +18,26 @@ out float v_FragDistance;
uniform int u_FogShape;
uniform vec3 u_RegionOffset;

uniform sampler2D u_LightTex; // The light map texture
uniform sampler2D u_LightTex; // The light map texture sampler

vec3 _sample_lightmap(uvec2 coord) {
return texelFetch(u_LightTex, ivec2(coord), 0).rgb;
vec4 _sample_lightmap(sampler2D lightMap, ivec2 uv) {
return texture(lightMap, clamp(uv / 256.0, vec2(0.5 / 16.0), vec2(15.5 / 16.0)));
}

uvec3 _get_relative_chunk_coord(uint pos) {
// Packing scheme is defined by LocalSectionIndex
return (uvec3(pos) >> uvec3(5u, 0u, 2u)) & uvec3(7u, 3u, 7u);
return uvec3(pos) >> uvec3(5u, 0u, 2u) & uvec3(7u, 3u, 7u);
}

vec3 _get_draw_translation(uint pos) {
return vec3(_get_relative_chunk_coord(pos)) * vec3(16.0);
return _get_relative_chunk_coord(pos) * vec3(16.0);
}

void main() {
_vert_init();

// Transform the chunk-local vertex position into world model space
vec3 translation = u_RegionOffset + _get_draw_translation(_vert_mesh_id);
vec3 translation = u_RegionOffset + _get_draw_translation(_draw_id);
vec3 position = _vert_position + translation;

#ifdef USE_FOG
Expand All @@ -47,9 +47,10 @@ void main() {
// Transform the vertex position into model-view-projection space
gl_Position = u_ProjectionMatrix * u_ModelViewMatrix * vec4(position, 1.0);

v_ColorModulator = _vert_color * _sample_lightmap(_vert_light);
v_TexCoord = _vert_tex_coord;
// Add the light color to the vertex color, and pass the texture coordinates to the fragment shader
v_Color = _vert_color * _sample_lightmap(u_LightTex, _vert_tex_light_coord);
v_TexCoord = _vert_tex_diffuse_coord;

v_MaterialMipBias = _material_mip_bias(_vert_material);
v_MaterialAlphaCutoff = _material_alpha_cutoff(_vert_material);
v_MaterialMipBias = _material_mip_bias(_material_params);
v_MaterialAlphaCutoff = _material_alpha_cutoff(_material_params);
}
Loading

0 comments on commit 53a673d

Please sign in to comment.