From ea94b65f063a7b3813e9448a27cd22c085964194 Mon Sep 17 00:00:00 2001 From: Szymon Nowakowski Date: Wed, 23 Sep 2026 15:42:31 +0200 Subject: [PATCH] Smaller matrices in uniforms, texcoord transform to rotate voxel faces --- assets/blocks/OakLogX.json | 18 +++++++---- assets/blocks/OakLogY.json | 18 +++++++---- assets/blocks/OakLogZ.json | 18 +++++++---- assets/shaders/includes/structs.slang | 15 +++++----- assets/shaders/main.slang | 16 +++++----- assets/shaders/skybox.slang | 2 +- src/Chunk.zig | 15 ++++++---- src/Game.zig | 6 +++- src/Player.zig | 6 ++-- src/shaders.zig | 15 ++++++++-- src/voxels.zig | 43 +++++++++++++++++++++++++++ 11 files changed, 127 insertions(+), 45 deletions(-) diff --git a/assets/blocks/OakLogX.json b/assets/blocks/OakLogX.json index 704d45d..9301004 100644 --- a/assets/blocks/OakLogX.json +++ b/assets/blocks/OakLogX.json @@ -1,22 +1,28 @@ { "walls": { "positive_x": { - "material": "OakLogTop.json" + "material": "OakLogTop.json", + "transform": "identity" }, "negative_x": { - "material": "OakLogTop.json" + "material": "OakLogTop.json", + "transform": "mirror" }, "positive_y": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "rotate_ccw" }, "negative_y": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "rotate_cw" }, "positive_z": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "rotate_cw" }, "negative_z": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "rotate_cw" } } } diff --git a/assets/blocks/OakLogY.json b/assets/blocks/OakLogY.json index 2fd93a6..e49660d 100644 --- a/assets/blocks/OakLogY.json +++ b/assets/blocks/OakLogY.json @@ -1,22 +1,28 @@ { "walls": { "positive_x": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "rotate_cw" }, "negative_x": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "rotate_ccw" }, "positive_y": { - "material": "OakLogTop.json" + "material": "OakLogTop.json", + "transform": "identity" }, "negative_y": { - "material": "OakLogTop.json" + "material": "OakLogTop.json", + "transform": "mirror" }, "positive_z": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "identity" }, "negative_z": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "rotate_180" } } } diff --git a/assets/blocks/OakLogZ.json b/assets/blocks/OakLogZ.json index d08e9d8..49a6ed1 100644 --- a/assets/blocks/OakLogZ.json +++ b/assets/blocks/OakLogZ.json @@ -1,22 +1,28 @@ { "walls": { "positive_x": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "identity" }, "negative_x": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "identity" }, "positive_y": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "identity" }, "negative_y": { - "material": "OakLog.json" + "material": "OakLog.json", + "transform": "identity" }, "positive_z": { - "material": "OakLogTop.json" + "material": "OakLogTop.json", + "transform": "identity" }, "negative_z": { - "material": "OakLogTop.json" + "material": "OakLogTop.json", + "transform": "mirror_rotate_180" } } } diff --git a/assets/shaders/includes/structs.slang b/assets/shaders/includes/structs.slang index 37c309c..f872849 100644 --- a/assets/shaders/includes/structs.slang +++ b/assets/shaders/includes/structs.slang @@ -1,5 +1,5 @@ struct GlobalUniforms { - float4x4 matrixWStoVS; + float3x4 matrixWStoVS; float4x4 matrixVStoCS; float2x3 matrixSSPXtoCS; @@ -12,10 +12,10 @@ struct PointLight { float3 positionWS; float3 color; - IncomingLight getIncoming(float4x4 matrixWStoVS, float3 positionVS) { + IncomingLight getIncoming(float3x4 matrixWStoVS, float3 positionVS) { IncomingLight light; - let lightPositionVS = mul(matrixWStoVS, float4(positionWS, 1.0)).xyz; + let lightPositionVS = mul(matrixWStoVS, float4(positionWS, 1.0)); let lightDirectionVS = normalize(lightPositionVS - positionVS); let lightDistance = distance(positionVS, lightPositionVS); let lightAttenuation = 1.0 / (lightDistance * lightDistance); @@ -31,11 +31,11 @@ struct DirectionalLight { float3 directionWS; float3 color; - IncomingLight getIncoming(float4x4 matrixWStoVS) { + IncomingLight getIncoming(float3x4 matrixWStoVS) { IncomingLight light; light.radiance = color; - light.directionVS = normalize(mul(matrixWStoVS, float4(-directionWS, 0.0)).xyz); + light.directionVS = normalize(mul(matrixWStoVS, float4(-directionWS, 0.0))); return light; } } @@ -56,8 +56,9 @@ struct Material { } struct ObjectUniforms { - float4x4 matrixOStoWS; - float4x4 matrixOStoWSNormal; + // Limited to a composition of translation and rotation + float3x4 matrixOStoWS; + float2x3 texCoordTransform; uint16_t material; } diff --git a/assets/shaders/main.slang b/assets/shaders/main.slang index a6ae891..1b37629 100644 --- a/assets/shaders/main.slang +++ b/assets/shaders/main.slang @@ -33,22 +33,24 @@ Varyings vertexMain(Vertex vert, uint instanceID : SV_VulkanInstanceID) { let object = _Objects[instanceID]; - let positionWS = mul(object.matrixOStoWS, float4(vert.positionOS, 1.0)).xyz; - let positionVS = mul(_Global.matrixWStoVS, float4(positionWS, 1.0)).xyz; + let positionWS = mul(object.matrixOStoWS, float4(vert.positionOS, 1.0)); + let positionVS = mul(_Global.matrixWStoVS, float4(positionWS, 1.0)); let positionCS = mul(_Global.matrixVStoCS, float4(positionVS, 1.0)); - let normalWS = normalize(mul(object.matrixOStoWSNormal, float4(vert.normalOS, 0.0)).xyz); - let normalVS = normalize(mul(_Global.matrixWStoVS, float4(normalWS, 0.0)).xyz); + let texCoord = mul(object.texCoordTransform, float3(vert.texCoord, 1.0)); - let tangentWS = normalize(mul(object.matrixOStoWSNormal, float4(vert.tangentOS.xyz, 0.0)).xyz); - let tangentVS = normalize(mul(_Global.matrixWStoVS, float4(tangentWS, 0.0)).xyz); + let normalWS = normalize(mul(object.matrixOStoWS, float4(vert.normalOS, 0.0))); + let normalVS = normalize(mul(_Global.matrixWStoVS, float4(normalWS, 0.0))); + + let tangentWS = normalize(mul(object.matrixOStoWS, float4(vert.tangentOS.xyz, 0.0))); + let tangentVS = normalize(mul(_Global.matrixWStoVS, float4(tangentWS, 0.0))); let bitangentVS = vert.tangentOS.w * normalize(cross(normalVS, tangentVS)); out.positionCS = positionCS; out.instance = instanceID; out.positionVS = positionVS; - out.texCoord = vert.texCoord; + out.texCoord = texCoord; out.normalVS = normalVS; out.tangentVS = tangentVS; out.bitangentVS = bitangentVS; diff --git a/assets/shaders/skybox.slang b/assets/shaders/skybox.slang index 69b061c..5f0e7c7 100644 --- a/assets/shaders/skybox.slang +++ b/assets/shaders/skybox.slang @@ -18,7 +18,7 @@ struct Varyings { Varyings vertexMain(Vertex vert) { Varyings out; - let directionVS = mul(_Global.matrixWStoVS, float4(vert.directionWS, 0.0)).xyz; + let directionVS = mul(_Global.matrixWStoVS, float4(vert.directionWS, 0.0)); let directionCS = mul(_Global.matrixVStoCS, float4(directionVS, 0.0)); out.positionCS = float4(directionCS.xy, 0.0, directionCS.w); diff --git a/src/Chunk.zig b/src/Chunk.zig index 79fb435..02e36fc 100644 --- a/src/Chunk.zig +++ b/src/Chunk.zig @@ -119,13 +119,18 @@ pub fn refresh(self: *Chunk, blocks: *const Blocks, neighbors: Neighbors) !void inline for (@typeInfo(voxels.Orientation).@"enum".fields) |field| { const side = @field(voxels.Orientation, field.name); - const material = @field(block.walls, field.name).material; - if (material != .empty and self.getOpposite(side, ix, iy, iz, blocks, neighbors) == .empty) { + const wall: Blocks.Definition.Wall = @field(block.walls, field.name); + if (wall.material != .empty and self.getOpposite(side, ix, iy, iz, blocks, neighbors) == .empty) { const matrix = getMatrix(side, origin); try uniforms.append(allocator_frame, .{ - .matrixOStoWS = matrix, - .matrixOStoWSNormal = matrix, - .material = material, + .matrixOStoWS_i = matrix.getIVersor().dropW(), + .matrixOStoWS_j = matrix.getJVersor().dropW(), + .matrixOStoWS_k = matrix.getKVersor().dropW(), + .matrixOStoWS_t = matrix.getTranslationVector().dropW(), + + .texCoordTransform = wall.transform.getMatrix(), + + .material = wall.material, }); } } diff --git a/src/Game.zig b/src/Game.zig index ad67bc9..df1d1fc 100644 --- a/src/Game.zig +++ b/src/Game.zig @@ -909,7 +909,11 @@ fn render(self: *Game) !void { const ambient_light = vm.Vector3.init(0.01, 0.01, 0.01); self.global_uniforms_staging_ptr.* = .{ - .matrixWStoVS = matrix_ws_to_vs, + .matrixWStoVS_i = matrix_ws_to_vs.getIVersor().dropW(), + .matrixWStoVS_j = matrix_ws_to_vs.getJVersor().dropW(), + .matrixWStoVS_k = matrix_ws_to_vs.getKVersor().dropW(), + .matrixWStoVS_t = matrix_ws_to_vs.getTranslationVector().dropW(), + .matrixVStoCS = matrix_vs_to_cs, .matrixSSPXtoCS = matrix_sspx_to_cs, diff --git a/src/Player.zig b/src/Player.zig index df4e2ff..fc661ae 100644 --- a/src/Player.zig +++ b/src/Player.zig @@ -184,9 +184,9 @@ pub const blocks = [9][:0]const u8{ "Bricks.json", "ChiseledStoneBricks.json", "Cobblestone.json", - "DiamondBlock.json", - "GoldBlock.json", - "IronBlock.json", + "OakLogX.json", + "OakLogY.json", + "OakLogZ.json", "OakPlanks.json", "SmoothStone.json", "StoneBricks.json", diff --git a/src/shaders.zig b/src/shaders.zig index 7db26dc..5c0fdab 100644 --- a/src/shaders.zig +++ b/src/shaders.zig @@ -44,7 +44,11 @@ pub const Vertex = extern struct { pub const Index = u16; pub const GlobalUniforms = extern struct { - matrixWStoVS: vm.Matrix4x4, + matrixWStoVS_i: vm.Vector3, + matrixWStoVS_j: vm.Vector3, + matrixWStoVS_k: vm.Vector3, + matrixWStoVS_t: vm.Vector3, + matrixVStoCS: vm.Matrix4x4, matrixSSPXtoCS: vm.Matrix3x2, @@ -93,8 +97,13 @@ pub const Material = extern struct { }; pub const ObjectUniforms = extern struct { - matrixOStoWS: vm.Matrix4x4, - matrixOStoWSNormal: vm.Matrix4x4, + // Limited to a composition of translation and rotation + matrixOStoWS_i: vm.Vector3, + matrixOStoWS_j: vm.Vector3, + matrixOStoWS_k: vm.Vector3, + matrixOStoWS_t: vm.Vector3, + + texCoordTransform: vm.Matrix3x2, material: Materials.Id, }; diff --git a/src/voxels.zig b/src/voxels.zig index 9534f2c..5348aa8 100644 --- a/src/voxels.zig +++ b/src/voxels.zig @@ -59,6 +59,49 @@ pub const Transform = enum(u3) { mirror_rotate_cw = 5, mirror_rotate_ccw = 6, mirror_rotate_180 = 7, + + pub fn getMatrix(self: Transform) vm.Matrix3x2 { + return switch (self) { + // zig fmt: off + .identity => .identity, + .rotate_cw => .init( + 0, -1, + 1, 0, + 0, 1, + ), + .rotate_ccw => .init( + 0, 1, + -1, 0, + 1, 0, + ), + .rotate_180 => .init( + -1, 0, + 0, -1, + 1, 1, + ), + .mirror => .init( + -1, 0, + 0, 1, + 1, 0, + ), + .mirror_rotate_cw => .init( + 0, -1, + -1, 0, + 1, 1, + ), + .mirror_rotate_ccw => .init( + 0, 1, + 1, 0, + 0, 0, + ), + .mirror_rotate_180 => .init( + 0, 1, + -1, 0, + 1, 0, + ), + // zig fmt: on + }; + } }; // ┌──────────────────── x