From a47d2c2b57dace249a6f9a4425fb49ddfa9fd6bd Mon Sep 17 00:00:00 2001 From: maelstrom Date: Sun, 6 Apr 2025 23:09:04 +0200 Subject: [PATCH] fix(renderer): studs were not properly tiled nor aligned --- assets/shaders/phong.fs | 25 ++++++++++++++++++++++--- assets/shaders/phong.vs | 20 ++++---------------- core/src/rendering/renderer.cpp | 5 +++++ 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/assets/shaders/phong.fs b/assets/shaders/phong.fs index c468124..965919b 100644 --- a/assets/shaders/phong.fs +++ b/assets/shaders/phong.fs @@ -39,8 +39,9 @@ const int FaceFront = 5; // I/O in vec3 vPos; +in vec3 lPos; in vec3 vNormal; -in vec2 vTexCoords; +in vec3 lNormal; flat in int vSurfaceZ; out vec4 FragColor; @@ -54,12 +55,13 @@ uniform DirLight sunLight; uniform Material material; uniform sampler2DArray studs; uniform float transparency; +uniform vec3 texScale; // Functions vec3 calculateDirectionalLight(DirLight light); vec3 calculatePointLight(PointLight light); - +mat3 lookAlong(vec3 pos, vec3 forward, vec3 up); // Main @@ -71,11 +73,28 @@ void main() { for (int i = 0; i < numPointLights; i++) { result += calculatePointLight(pointLights[i]); } + + vec3 otherVec = abs(dot(lNormal, vec3(0, 1, 0))) > 0.99 ? vec3(0, 0, 1) + : abs(dot(lNormal, vec3(0, 0, 1))) > 0.99 ? vec3(1, 0, 0) + : vec3(0, 1, 0); + // We use abs(lNormal) so opposing sides "cut" from the same side + mat3 transform = transpose(inverse(lookAlong(vec3(0, 0, 0), abs(lNormal), otherVec))); - vec4 studPx = texture(studs, vec3(vTexCoords, vSurfaceZ)); + vec2 texCoords = vec2((transform * lPos) * (transform * texScale) / 2) - vec2(mod((transform * texScale) / 4, 1)); + + vec4 studPx = texture(studs, vec3(texCoords, vSurfaceZ)); FragColor = vec4(mix(result, vec3(studPx), studPx.w), 1) * (1-transparency); } +mat3 lookAlong(vec3 pos, vec3 forward, vec3 up) { + vec3 f = normalize(forward); // Forward/Look + vec3 u = normalize(up); // Up + vec3 s = normalize(cross(f, u)); // Right + u = normalize(cross(s, f)); + + return mat3(s, u, f); +} + vec3 calculateDirectionalLight(DirLight light) { // Calculate diffuse vec3 norm = normalize(vNormal); diff --git a/assets/shaders/phong.vs b/assets/shaders/phong.vs index 1a9a9c3..989d10d 100644 --- a/assets/shaders/phong.vs +++ b/assets/shaders/phong.vs @@ -18,7 +18,9 @@ const int SurfaceInlets = 4; const int SurfaceUniversal = 5; out vec3 vPos; +out vec3 lPos; out vec3 vNormal; +out vec3 lNormal; out vec2 vTexCoords; flat out int vSurfaceZ; @@ -33,7 +35,9 @@ void main() { gl_Position = projection * view * model * vec4(aPos, 1.0); vPos = vec3(model * vec4(aPos, 1.0)); + lPos = aPos; vNormal = normalMatrix * aNormal; + lNormal = aNormal; int vFace = aNormal == vec3(0,1,0) ? FaceTop : aNormal == vec3(0, -1, 0) ? FaceBottom : aNormal == vec3(1, 0, 0) ? FaceRight : @@ -43,20 +47,4 @@ void main() vSurfaceZ = surfaces[vFace]; // if (surfaces[vFace] > SurfaceUniversal) vSurfaceZ = 0; - - switch (vFace) { - case FaceTop: - case FaceBottom: - // vTexCoords = aTexCoords * vec2(texScale.x / 2, fract(surfaceOffset + texScale.z / 12)); - vTexCoords = aTexCoords * vec2(texScale.x, texScale.z) / 2; - break; - case FaceLeft: - case FaceRight: - vTexCoords = aTexCoords * vec2(texScale.y, texScale.z) / 2; - break; - case FaceFront: - case FaceBack: - vTexCoords = aTexCoords * vec2(texScale.x, texScale.y) / 2; - break; - }; } diff --git a/core/src/rendering/renderer.cpp b/core/src/rendering/renderer.cpp index 46de714..7f96356 100644 --- a/core/src/rendering/renderer.cpp +++ b/core/src/rendering/renderer.cpp @@ -113,6 +113,11 @@ void renderParts() { shader->set("surfaces[1]", SurfaceStuds); shader->set("surfaces[4]", SurfaceInlets); + shader->set("surfaces[0]", SurfaceStuds); + shader->set("surfaces[2]", SurfaceStuds); + shader->set("surfaces[3]", SurfaceStuds); + shader->set("surfaces[5]", SurfaceStuds); + // Pre-calculate the normal matrix for the shader // Pass in the camera position