From 0d43bb28fe2510ffca5ed1bb515971adc35ddf69 Mon Sep 17 00:00:00 2001 From: LouisQuepierts <97670116+LouisQuepierts@users.noreply.github.com> Date: Fri, 29 May 2026 21:38:41 +0800 Subject: [PATCH 1/6] feat(rendering): add segment rendering support to SDF graphics --- .../lib/v2/rendering/sdf/Sdf2d.java | 5 +++ .../lib/v2/rendering/sdf/SdfGraphics.java | 36 ++++++++++++++----- .../lib/v2/rendering/sdf/SdfParameters.java | 5 +++ .../lib/v2/rendering/sdf/SdfRenderType.java | 4 ++- .../shaders/core/sdf_graphics.fsh | 20 +++++++---- 5 files changed, 54 insertions(+), 16 deletions(-) diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java index 23aa4918..cc6c7def 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java @@ -98,6 +98,11 @@ public static float sd( shape.x, shape.y, shape.z ); + + default -> sdRect( + px, py, + rect.z, rect.w + ); }; if (params.isOnion()) { diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java index 7b1aef1b..dd4dbc3f 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java @@ -109,6 +109,26 @@ public SdfGraphics egg( return this; } + public SdfGraphics segment( + float x0, float y0, + float x1, float y1 + ) { + var left = Math.min(x0, x1); + var top = Math.min(y0, y1); + var width = Math.abs(x1 - x0); + var height = Math.abs(y1 - y0); + + var halfWidth = width * 0.5f; + var halfHeight = height * 0.5f; + + this.parameters .getRect() + .set(left, top, width, height); + + this.parameters .segment( -halfWidth, -halfHeight, +halfWidth, +halfHeight); + + return this; + } + public SdfGraphics color(int color) { this.parameters .color(color); return this; @@ -233,10 +253,10 @@ private static void _draw( ); } - var x0 = -0.5f; - var y0 = -0.5f; - var x1 = +0.5f; - var y1 = +0.5f; + var x0 = rect.x; + var y0 = rect.y; + var x1 = rect.x + width; + var y1 = rect.y + height; pose .rotate(Mth.DEG_TO_RAD * parameters.getRotation()) .scale(width, height); @@ -313,10 +333,10 @@ private RenderState( @Override public void buildVertices(VertexConsumer consumer) { - consumer.addVertexWith2DPose(this.pose(), this.x0(), this.y0()).setUv(0, 0).setUv1(this.index(), 0).setColor(this.color()); - consumer.addVertexWith2DPose(this.pose(), this.x0(), this.y1()).setUv(0, 1).setUv1(this.index(), 0).setColor(this.color()); - consumer.addVertexWith2DPose(this.pose(), this.x1(), this.y1()).setUv(1, 1).setUv1(this.index(), 0).setColor(this.color()); - consumer.addVertexWith2DPose(this.pose(), this.x1(), this.y0()).setUv(1, 0).setUv1(this.index(), 0).setColor(this.color()); + consumer.addVertexWith2DPose(this.pose(), -0.5f, -0.5f).setUv(0, 0).setUv1(this.index(), 0).setColor(this.color()); + consumer.addVertexWith2DPose(this.pose(), -0.5f, +0.5f).setUv(0, 1).setUv1(this.index(), 0).setColor(this.color()); + consumer.addVertexWith2DPose(this.pose(), +0.5f, +0.5f).setUv(1, 1).setUv1(this.index(), 0).setColor(this.color()); + consumer.addVertexWith2DPose(this.pose(), +0.5f, -0.5f).setUv(1, 0).setUv1(this.index(), 0).setColor(this.color()); } @Override diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfParameters.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfParameters.java index 8e457c2d..f152f001 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfParameters.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfParameters.java @@ -74,6 +74,11 @@ public void egg(float topRadius, float bottomRadius, float height) { this.shapeParams .set(height, bottomRadius, topRadius, 0.0f); } + public void segment(float x0, float y0, float x1, float y1) { + this ._renderType(SdfRenderType.SEGMENT); + this.shapeParams .set(x0, y0, x1, y1); + } + public void smooth(float smooth) { this ._smooth(smooth); } diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfRenderType.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfRenderType.java index ed5cd227..fc12cdfb 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfRenderType.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfRenderType.java @@ -7,7 +7,9 @@ public enum SdfRenderType { SECTOR, PIE, CAPSULE, - EGG; + EGG, + SEGMENT + ; private static final SdfRenderType[] VALUES = values(); diff --git a/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/sdf_graphics.fsh b/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/sdf_graphics.fsh index e375d52a..eb960171 100644 --- a/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/sdf_graphics.fsh +++ b/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/sdf_graphics.fsh @@ -20,6 +20,7 @@ layout(std140) uniform SDFParameters { #define RT_PIE 4 #define RT_UCAPSULE 5 #define RT_EGG 6 +#define RT_SEGMENT 7 #define PASS_FILL 0 #define PASS_LIGHT 1 @@ -74,13 +75,6 @@ float sdPie(in vec2 p, in vec2 c, in float r) { return max(l,m*sign(c.y*p.x-c.x*p.y)); } -// from https://iquilezles.org/articles/distfunctions2d/ -float sdSegment( in vec2 p, in vec2 a, in vec2 b ) { - vec2 pa = p-a, ba = b-a; - float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); - return length( pa - ba*h ); -} - // from https://iquilezles.org/articles/distfunctions2d/ float sdUnevenCapsule( vec2 p, float r1, float r2, float h ) { @@ -106,6 +100,15 @@ float sdEgg( in vec2 p, in float he, in float ra, in float rb ) return length(vec2(p.x+ce,p.y))-(ce+ra); } +// from https://iquilezles.org/articles/distfunctions2d/ +float sdSegment( in vec2 p, in vec2 a, in vec2 b ) +{ + vec2 ba = b-a; + vec2 pa = p-a; + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length(pa-h*ba); +} + void main() { Sdf params = SDFs[vIndex]; vec4 shape = params.Shape; @@ -135,6 +138,9 @@ void main() { case RT_EGG: d = sdEgg(p, shape.x, shape.y, shape.z); break; + case RT_SEGMENT: + d = sdSegment(p, shape.xy, shape.zw) - uCornerRadius; + break; } float aa = max(fwidth(d) * 0.5, uSmoothRadius); From 732a1a5a219a32b98dd6e40496c6907cdd6156de Mon Sep 17 00:00:00 2001 From: LouisQuepierts <97670116+LouisQuepierts@users.noreply.github.com> Date: Sat, 30 May 2026 12:21:36 +0800 Subject: [PATCH 2/6] fix(rendering): fixed rotation and AABB problems in non-center mode for SdfGraphics --- .../lib/v2/rendering/sdf/SdfGraphics.java | 57 ++++++++++++++++--- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java index dd4dbc3f..d92151dc 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java @@ -24,6 +24,7 @@ import net.neoforged.neoforge.client.event.ConfigureMainRenderTargetEvent; import org.jetbrains.annotations.NotNull; import org.joml.Matrix3x2f; +import org.joml.Vector3f; import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; @@ -37,6 +38,8 @@ public final class SdfGraphics { @Getter public static final SdfGraphics instance = new SdfGraphics(new SdfParameters()); + private static boolean debug = false; + private final SdfParameters parameters; public SdfGraphics box(float x, float y, float width, float height) { @@ -227,6 +230,10 @@ public static void init(ConfigureMainRenderTargetEvent event) { ); } + public static void debug(boolean enable) { + SdfGraphics.debug = enable; + } + private static void _draw( @NotNull GuiGraphicsExtractor graphics, @NotNull SdfParameters parameters @@ -243,27 +250,52 @@ private static void _draw( var ex = (round + smooth + stroke) * 2.0f; var width = rect.z + ex; var height = rect.w + ex; + final var hw = width * 0.5f; + final var hh = height * 0.5f; + + final var rotation = parameters.getRotation(); + final var radian = rotation * Mth.DEG_TO_RAD; + final var cos = Mth.cos(radian); + final var sin = Mth.sin(radian); + float cx; + float cy; if (parameters.isCenter()) { pose .translate(rect.x, rect.y); + + cx = rect.x; + cy = rect.y; } else { pose .translate( - rect.x + width * 0.5f, - rect.y + height * 0.5f + rect.x + hw, + rect.y + hh ); + + cx = rect.x + hw - hw * cos + hh * sin; + cy = rect.y + hh - hw * sin - hh * cos; } - var x0 = rect.x; - var y0 = rect.y; - var x1 = rect.x + width; - var y1 = rect.y + height; + if (rotation != 0.0f) { + pose.rotate(Mth.DEG_TO_RAD * rotation); + } - pose .rotate(Mth.DEG_TO_RAD * parameters.getRotation()) - .scale(width, height); + if (!parameters.isCenter()) { + pose .translate(-hw, -hh); + } + + pose .scale(width, height); rect.z = width; rect.w = height; + var extX = Mth.abs(hw * cos) + Mth.abs(hh * sin) + 1.0f; + var extY = Mth.abs(hw * sin) + Mth.abs(hh * cos) + 1.0f; + + var x0 = cx - extX; + var x1 = cx + extX; + var y0 = cy - extY; + var y1 = cy + extY; + var offset = index * SDF_PARAMETER_SIZE; var slice = ubo.slice(offset, SDF_PARAMETER_SIZE); var state = new RenderState( @@ -276,10 +308,17 @@ private static void _draw( null ); + if (debug) { + graphics.outline( + (int) x0, (int) y0, + (int) (x1 - x0), (int) (y1 - y0), + 0xFF0000FF + ); + } + parameters .upload(encoder, slice); graphics .submitGuiElementRenderState(state); - rect.z = z; rect.w = w; From 67de7f9a8b298f7b37c32ea084169a77ad516fc1 Mon Sep 17 00:00:00 2001 From: LouisQuepierts <97670116+LouisQuepierts@users.noreply.github.com> Date: Sat, 30 May 2026 12:21:58 +0800 Subject: [PATCH 3/6] fix(rendering): fixed collision problem in Sdf2d --- .../lib/v2/rendering/sdf/Sdf2d.java | 53 ++++++++++++++----- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java index cc6c7def..14d98241 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java @@ -20,6 +20,13 @@ public static float sd( var width = rect.z + ex; var height = rect.w + ex; + final var hw = width * 0.5f; + final var hh = height * 0.5f; + + var rotation = params.getRotation(); + var radian = rotation * Mth.DEG_TO_RAD; + var cos = Mth.cos(radian); + var sin = Mth.sin(radian); float cx; float cy; @@ -31,23 +38,17 @@ public static float sd( } else { - cx = rect.x + width * 0.5f; - cy = rect.y + height * 0.5f; + cx = rect.x + hw - hw * cos + hh * sin; + cy = rect.y + hh - hw * sin - hh * cos; } var px = x - cx; var py = y - cy; - var rotation = params.getRotation(); if (rotation != 0f) { - var r = -rotation * Mth.DEG_TO_RAD; - - var s = (float)Math.sin(r); - var c = (float)Math.cos(r); - - var tx = px * c - py * s; - var ty = px * s + py * c; + var tx = px * cos + py * sin; + var ty = py * cos - px * sin; px = tx; py = ty; @@ -85,6 +86,12 @@ public static float sd( px, py, shape.x, shape.y, shape.z + ); + + case SEGMENT -> sdSegment( + px, py, + shape.x, shape.y, + shape.z, shape.w ) - round; case CAPSULE -> sdUnevenCapsule( @@ -99,10 +106,6 @@ public static float sd( shape.z ); - default -> sdRect( - px, py, - rect.z, rect.w - ); }; if (params.isOnion()) { @@ -264,4 +267,26 @@ public static float sdEgg( ) - (ce + ra); } + public static float sdSegment( + float px, float py, + float ax, float ay, + float bx, float by + ) { + float bax = bx - ax; + float bay = by - ay; + float pax = px - ax; + float pay = py - ay; + float dot = pax * bax + pay * bay; + float h = Mth.clamp( + dot / (bax * bax + bay * bay), + 0.0f, + 1.0f + ); + + return Mth.length( + pax - h * bax, + pay - h * bay + ); + } + } From 60be30df519807f5dfbfd7b83890396529bbc15b Mon Sep 17 00:00:00 2001 From: LouisQuepierts <97670116+LouisQuepierts@users.noreply.github.com> Date: Sat, 30 May 2026 12:22:52 +0800 Subject: [PATCH 4/6] test(rendering): update SdfGraphicsLayer logic for testing --- .../v2/test/client/gui/SdfGraphicsLayer.java | 53 +++++++++---------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java b/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java index 16298a65..e2d0e117 100644 --- a/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java +++ b/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java @@ -5,7 +5,9 @@ import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.gui.screens.ChatScreen; import net.minecraft.resources.Identifier; +import net.minecraft.util.Mth; import net.neoforged.neoforge.client.gui.GuiLayer; import org.jspecify.annotations.NonNull; @@ -23,36 +25,11 @@ public void render( this.timer += tracker.getGameTimeDeltaTicks(); var minecraft = Minecraft.getInstance(); - if (minecraft.screen != null) return; + if (!(minecraft.screen instanceof ChatScreen)) return; int xMouse = (int)minecraft.mouseHandler.getScaledXPos(minecraft.getWindow()); int yMouse = (int)minecraft.mouseHandler.getScaledYPos(minecraft.getWindow()); - /*SdfGraphics.getInstance() - .center(true) - .color(0xFFFFFFFF) - .rotate(this.timer) - .stroke(0) - .box(32, 40, 40, 20) - .fill() - .draw(graphics) - .box(30, 65, 40, 20) - .round(2) - .fill() - .draw(graphics) - .round(0) - .circle(80, 50, 20) - .fill() - .draw(graphics) - .arc(130, 50, 45, 20, 5) - .fill() - .draw(graphics) - .sector(180, 50, 45, 20, 5) - .fill() - .draw(graphics) - .pie(230, 50, 45, 20) - .fill() - .draw(graphics) - .reset();*/ + SdfGraphics.debug(true); var sdf = SdfGraphics.getInstance() .reset() .rotate(this.timer) @@ -62,15 +39,33 @@ public void render( .fill(); this.draw(graphics, sdf, 0, xMouse, yMouse); + SdfGraphics.debug(false); - sdf.stroke(2); + /*sdf.stroke(2); this.draw(graphics, sdf, 50, xMouse, yMouse); sdf.stroke(0).light(5); this.draw(graphics, sdf, 100, xMouse, yMouse); sdf.stroke(2); - this.draw(graphics, sdf, 150, xMouse, yMouse); + this.draw(graphics, sdf, 150, xMouse, yMouse);*/ + + // test segment + + /*var min = 25; + var mx = 75 + Mth.sin(this.timer * 0.05f) * 25.0f; + var my = 75 + Mth.cos(this.timer * 0.05f) * 25.0f; + + if (minecraft.screen != null) { + sdf + .segment(min + 5, min + 5, mx + 5, my + 5) + .rotate(0) + .round(2.0f).color(0xFFFFFFFF) + .draw(graphics) + *//*.segment(min, min, mx, my) + .light(5.0f) + .draw(graphics)*//*; + }*/ sdf.reset(); } From eb45744f54f9d6277edc480604cba1eee5d75e53 Mon Sep 17 00:00:00 2001 From: LouisQuepierts <97670116+LouisQuepierts@users.noreply.github.com> Date: Sat, 30 May 2026 13:10:09 +0800 Subject: [PATCH 5/6] feat(rendering): add TRIANGLE_EQUILATERAL and TRIANGLE_ISOSCELES shape for Sdf rendering and collision --- .../lib/v2/rendering/sdf/Sdf2d.java | 72 +++++++++++++++++++ .../lib/v2/rendering/sdf/SdfGraphics.java | 20 +++++- .../lib/v2/rendering/sdf/SdfParameters.java | 10 +++ .../lib/v2/rendering/sdf/SdfRenderType.java | 5 +- .../shaders/core/sdf_graphics.fsh | 42 +++++++++-- 5 files changed, 143 insertions(+), 6 deletions(-) diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java index 14d98241..2851a7cd 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/Sdf2d.java @@ -106,6 +106,19 @@ public static float sd( shape.z ); + case TRIANGLE_EQUILATERAL -> sdEquilateralTriangle( + px, py, + shape.x - round * 2.0f + ) - round; + + case TRIANGLE_ISOSCELES -> sdIsoscelesTriangle( + px, + py - (shape.y * 0.5f - round * 2.0f), + shape.x - round, + round * 2.0f - shape.y + ) - round; + + default -> Float.POSITIVE_INFINITY; }; if (params.isOnion()) { @@ -289,4 +302,63 @@ public static float sdSegment( ); } + public static float sdEquilateralTriangle( + float px, float py, + float r + ) { + final float k = (float) Math.sqrt(3.0); + + px = Math.abs(px) - r; + py = py + r / k; + + if (px + k * py > 0.0f) { + var tx = (px - k * py) * 0.5f; + var ty = (-k * px - py) * 0.5f; + px = tx; + py = ty; + } + + px -= Mth.clamp(px, -2.0f * r, 0.0f); + + return -Mth.length(px, py) * Mth.sign(py); + } + + public static float sdIsoscelesTriangle( + float px, float py, + float qx, float qy + ) { + px = Math.abs(px); + + float dotQ = qx * qx + qy * qy; + float h1 = Mth.clamp( + (px * qx + py * qy) / dotQ, + 0.0f, 1.0f + ); + float ax = px - qx * h1; + float ay = py - qy * h1; + + float h2; + if (qx != 0.0f) { + h2 = Mth.clamp(px / qx, 0.0f, 1.0f); + } else { + h2 = px > 0.0f ? 1.0f : 0.0f; + } + float bx = px - qx * h2; + float by = py - qy; + + float s = -Mth.sign(qy); + + float da = ax * ax + ay * ay; + float sa = s * (px * qy - py * qx); + + float db = bx * bx + by * by; + float sb = s * (py - qy); + + float dDist = Math.min(da, db); + float dSign = Math.min(sa, sb); + + return -(float) Math.sqrt(dDist) + * Mth.sign(dSign); + } + } diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java index d92151dc..75304500 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfGraphics.java @@ -126,12 +126,30 @@ public SdfGraphics segment( this.parameters .getRect() .set(left, top, width, height); - this.parameters .segment( -halfWidth, -halfHeight, +halfWidth, +halfHeight); return this; } + public SdfGraphics triangleEquilateral(float x, float y, float radius) { + var actual = radius * (1.0f / 1.2f); + + this.parameters .getRect() + .set(x, y, radius * 2, radius * 2); + this.parameters .triangleEquilateral(actual); + + return this; + } + + public SdfGraphics triangleIsosceles(float x, float y, float width, float height) { + final var factor = 1.0f / 1.2f; + this.parameters .getRect() + .set(x, y, width * 2.0f, height); + this.parameters .triangleIsosceles(width * factor, height * factor); + + return this; + } + public SdfGraphics color(int color) { this.parameters .color(color); return this; diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfParameters.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfParameters.java index f152f001..04963a39 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfParameters.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfParameters.java @@ -79,6 +79,16 @@ public void segment(float x0, float y0, float x1, float y1) { this.shapeParams .set(x0, y0, x1, y1); } + public void triangleEquilateral(float radius) { + this ._renderType(SdfRenderType.TRIANGLE_EQUILATERAL); + this.shapeParams .set(radius, 0.0f, 0.0f, 0.0f); + } + + public void triangleIsosceles(float base, float height) { + this ._renderType(SdfRenderType.TRIANGLE_ISOSCELES); + this.shapeParams .set(base, height, 0.0f, 0.0f); + } + public void smooth(float smooth) { this ._smooth(smooth); } diff --git a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfRenderType.java b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfRenderType.java index fc12cdfb..f55b43d3 100644 --- a/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfRenderType.java +++ b/module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/sdf/SdfRenderType.java @@ -8,7 +8,10 @@ public enum SdfRenderType { PIE, CAPSULE, EGG, - SEGMENT + SEGMENT, + + TRIANGLE_EQUILATERAL, + TRIANGLE_ISOSCELES, ; private static final SdfRenderType[] VALUES = values(); diff --git a/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/sdf_graphics.fsh b/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/sdf_graphics.fsh index eb960171..01d09ce0 100644 --- a/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/sdf_graphics.fsh +++ b/module.rendering/src/main/resources/assets/anvillib_rendering/shaders/core/sdf_graphics.fsh @@ -21,6 +21,8 @@ layout(std140) uniform SDFParameters { #define RT_UCAPSULE 5 #define RT_EGG 6 #define RT_SEGMENT 7 +#define RT_ETRIANGLE 8 +#define RT_ITRIANGLE 9 #define PASS_FILL 0 #define PASS_LIGHT 1 @@ -109,6 +111,29 @@ float sdSegment( in vec2 p, in vec2 a, in vec2 b ) return length(pa-h*ba); } +// from https://iquilezles.org/articles/distfunctions2d/ +float sdEquilateralTriangle( in vec2 p, in float r ) +{ + const float k = sqrt(3.0); + p.x = abs(p.x) - r; + p.y = p.y + r/k; + if( p.x+k*p.y>0.0 ) p = vec2(p.x-k*p.y,-k*p.x-p.y)/2.0; + p.x -= clamp( p.x, -2.0*r, 0.0 ); + return -length(p)*sign(p.y); +} + +// from https://iquilezles.org/articles/distfunctions2d/ +float sdIsoscelesTriangle( in vec2 p, in vec2 q ) +{ + p.x = abs(p.x); + vec2 a = p - q*clamp( dot(p,q)/dot(q,q), 0.0, 1.0 ); + vec2 b = p - q*vec2( clamp( p.x/q.x, 0.0, 1.0 ), 1.0 ); + float s = -sign( q.y ); + vec2 d = min( vec2( dot(a,a), s*(p.x*q.y-p.y*q.x) ), + vec2( dot(b,b), s*(p.y-q.y) )); + return -sqrt(d.x)*sign(d.y); +} + void main() { Sdf params = SDFs[vIndex]; vec4 shape = params.Shape; @@ -116,18 +141,21 @@ void main() { float alpha = 0.0; float d = 1e5; + + float r = uCornerRadius; + float r2 = r + r; switch (uRenderType) { case RT_BOX: - d = sdRect(p, shape.xy - vec2(uCornerRadius)) - uCornerRadius; + d = sdRect(p, shape.xy - vec2(r)) - r; break; case RT_CIRCLE: d = sdCircle(p, shape.x); break; case RT_ARC: - d = sdArc(p, shape.xy, shape.z, shape.w) - uCornerRadius; + d = sdArc(p, shape.xy, shape.z, shape.w) - r; break; case RT_SECTOR: - d = sdRing(p, shape.xy, shape.z, shape.w) - uCornerRadius; + d = sdRing(p, shape.xy, shape.z, shape.w) - r; break; case RT_PIE: d = sdPie(p, shape.xy, shape.z); @@ -139,7 +167,13 @@ void main() { d = sdEgg(p, shape.x, shape.y, shape.z); break; case RT_SEGMENT: - d = sdSegment(p, shape.xy, shape.zw) - uCornerRadius; + d = sdSegment(p, shape.xy, shape.zw) - r; + break; + case RT_ETRIANGLE: + d = sdEquilateralTriangle(p, shape.x - r2) - r; + break; + case RT_ITRIANGLE: + d = sdIsoscelesTriangle(p - vec2(0.0, shape.y * 0.5 - r2), vec2(shape.x - r, r2 - shape.y)) - r; break; } From 41ecf6a39a6df2c5a664360ff973e53b5d434e70 Mon Sep 17 00:00:00 2001 From: LouisQuepierts <97670116+LouisQuepierts@users.noreply.github.com> Date: Sat, 30 May 2026 13:10:37 +0800 Subject: [PATCH 6/6] test(rendering): add triangle to SdfGraphicsLayer.java for testing --- .../anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java b/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java index e2d0e117..9295a7a7 100644 --- a/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java +++ b/module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/gui/SdfGraphicsLayer.java @@ -117,13 +117,13 @@ private void draw( this.draw( graphics, - sdf.capsule(280, 50 + shift, 8, 10, 18), + sdf.triangleEquilateral(280, 50 + shift, 20), xMouse, yMouse ); this.draw( graphics, - sdf.egg(330, 50 + shift, 2, 10, 12), + sdf.triangleIsosceles(330, 50 + shift, 20, 40), xMouse, yMouse ); }