As for now, wires are rendered as sprites that get transformed.
Because of this, wire strictly vertical and wire shadow strictly horizontal get 1 pixel wide and not antialiased :
- Wires can't be made thicker verticaly
- Wires hide when big poles are out of view but wire still goes in the view
- Wire gets ugly because no antialiasing is done on sprite transformation.
What I would propose is to render wire using shaders.
- It would make wire width consistent
- It doesn't need a perfect bezier curve, 32 8 point makes a good aproximation for a wire going from a pole to another.
- It doesn't need transformation antialias
Re: Improve Wire Rendering
Posted: Sun Sep 28, 2025 12:06 am
by y.petremann
I know it's been near one year, I've got some update about that.
I tried with my humble programming background to write my first ever shader for wire rendering demonstration
// Example: draw one wire
struct Wire {
vec3 from;
vec3 to;
vec4 color;
float thickness;
float tension;
bool shadow;
};
struct PowerPole {
vec3 wire;
vec3 shadow;
};
float sdSegment(vec2 p, vec2 A, vec2 B) {
vec2 pa = p - A;
vec2 ba = B - A;
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
return length(pa - ba * h);
}
float sdBezier(vec2 p, vec2 A, vec2 B, vec2 C) {
const int N = 6; // number of segments (fewer = faster, more = smoother)
vec2 prev = A;
float minDist = 1e9;
for (int i = 1; i <= N; i++) {
float t = float(i) / float(N);
vec2 curr = (1.0 - t) * (1.0 - t) * A +
2.0 * (1.0 - t) * t * B +
t * t * C;
minDist = min(minDist, sdSegment(p, prev, curr));
prev = curr;
}
return minDist;
}
vec4 renderWire(Wire w, vec2 uv) {
vec2 A = w.from.xy;
vec2 C = w.to.xy;
float dz = w.to.z - w.from.z;
vec2 gravity = w.shadow ? vec2(-1.0, 0.0) : vec2(0.0, -1.0);
// Sag amount scaled by elevation difference
float sag = (1.0 - w.tension) * (0.5 + abs(dz) * 0.5);
vec2 B = (A + C) * 0.5 + gravity * sag * 50.0; // scale for visibility
float d = sdBezier(uv, A, B, C);
float alpha = smoothstep(w.thickness, w.thickness - 1.0, d);
return w.color.rgba * alpha;
}
vec4 blend(vec4 col, vec4 c) {
return mix(col,c,c.a);
}
// colors
const vec4 red_wire = vec4(0.8, 0.1, 0.1, 1.0);
const vec4 green_wire = vec4(0.8, 0.1, 0.1, 1.0);
const vec4 copper_wire = vec4(0.8, 0.1, 0.1, 1.0);
const vec4 shadow_wire = vec4(0.0, 0.0, 0.0, 1.0);
const vec4 shadow_alpha = vec4(1.0, 1.0, 1.0, 0.5);
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord;
//power poles
PowerPole pp1 = PowerPole(vec3(100, 150, 50), vec3(150, 100, 50));
PowerPole pp2 = PowerPole(vec3(100, 250, 50), vec3(150, 200, 50));
PowerPole pp3 = PowerPole(vec3(410, 150, 50), vec3(460, 100, 50));
vec4 shadow = vec4(0.0,0.0,0.0,0.0);
shadow = blend(shadow, renderWire(Wire(pp1.shadow, pp2.shadow, shadow_wire, 2.0, 0.0, true), uv));
shadow = blend(shadow, renderWire(Wire(pp1.shadow, pp3.shadow, shadow_wire, 2.0, 0.0, true), uv));
shadow = blend(shadow, renderWire(Wire(pp2.shadow, pp3.shadow, shadow_wire, 2.0, 0.0, true), uv));
shadow = shadow * shadow_alpha;
vec4 col = vec4(0.0,0.3,0.0,1.0);
col = blend(col, shadow);
col = blend(col, renderWire(Wire(pp1.wire, pp2.wire, red_wire, 2.0, 0.0, false), uv));
col = blend(col, renderWire(Wire(pp1.wire, pp3.wire, green_wire, 2.0, 0.0, false), uv));
col = blend(col, renderWire(Wire(pp2.wire, pp3.wire, copper_wire, 2.0, 0.0, false), uv));
fragColor = col;
}
I give factorio devs the right to use this code and modify as they like
Re: Improve Wire Rendering
Posted: Wed Oct 08, 2025 8:10 am
by y.petremann
Sorry for unknow reason, my shadertoy demo link has problems and the account too, so simple paste the code in a new shadertoy
Re: Improve Wire Rendering
Posted: Wed Oct 08, 2025 8:19 am
by mmmPI
It shows a triangle of red wire on green background. ( and their shadow )
Can you highlight which number to modify to change the position of one point of the triangle for someone with no background in programming to see how it looks when the point are placed differently ?
Re: Improve Wire Rendering
Posted: Wed Oct 08, 2025 4:19 pm
by y.petremann
mmmPI wrote: Wed Oct 08, 2025 8:19 am
It shows a triangle of red wire on green background. ( and their shadow )
Can you highlight which number to modify to change the position of one point of the triangle for someone with no background in programming to see how it looks when the point are placed differently ?
There is PowerPole with have two vectors which are the coordinates of the wire and it shadow
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord;
// HERE you can define new powerpoles
PowerPole pp1 = PowerPole(vec3(100, 150, 50), vec3(150, 100, 50));
PowerPole pp2 = PowerPole(vec3(100, 250, 50), vec3(150, 200, 50));
PowerPole pp3 = PowerPole(vec3(410, 150, 50), vec3(460, 100, 50));
vec4 shadow = vec4(0.0,0.0,0.0,0.0);
// HERE you add wires shadow rendering
shadow = blend(shadow, renderWire(Wire(pp1.shadow, pp2.shadow, shadow_wire, 2.0, 0.0, true), uv));
shadow = blend(shadow, renderWire(Wire(pp1.shadow, pp3.shadow, shadow_wire, 2.0, 0.0, true), uv));
shadow = blend(shadow, renderWire(Wire(pp2.shadow, pp3.shadow, shadow_wire, 2.0, 0.0, true), uv));
shadow = shadow * shadow_alpha;
vec4 col = vec4(0.0,0.3,0.0,1.0);
col = blend(col, shadow);
// HERE you add wires rendering
col = blend(col, renderWire(Wire(pp1.wire, pp2.wire, red_wire, 2.0, 0.0, false), uv));
col = blend(col, renderWire(Wire(pp1.wire, pp3.wire, green_wire, 2.0, 0.0, false), uv));
col = blend(col, renderWire(Wire(pp2.wire, pp3.wire, copper_wire, 2.0, 0.0, false), uv));
fragColor = col;
}
Re: Improve Wire Rendering
Posted: Sat Oct 11, 2025 4:03 pm
by mmmPI
Thanks for adding the comments I can't access the /new page from shadertoy atm, i guess they will fix this soon, and i'll try adding a power pole, that sound more interesting that just moving one around.
The arguments for the propostion are technical, i don't know how it would fit in game, it reminded me the curvy rails discussion,i wonder what is the complexity / performance tradeoff on this one.
Re: Improve Wire Rendering
Posted: Sun Oct 12, 2025 2:14 am
by y.petremann
Curved rails are managed by sprites and it seems reasonable becaus eit can became really complex because they hold a lot of details.
But the fact is that wires are monocolored and mostly empty sprite that is stretched and skewed, on some cases they are so thin that they are barely visible.
My proposal is for drawing wires using shaders so we can manage those edge cases in a better way,
I imagine that a better version could use a shader that use straight wire sprite, so modders could customise the sprite without touching the shader (this would allow to theme as christmas garland for example)
On the other hand some players could install mods that modify the shader for alternate pathing (like removing the curve or having orthogonal pathing)
Re: Improve Wire Rendering
Posted: Sun Oct 12, 2025 8:36 am
by mmmPI
y.petremann wrote: Sun Oct 12, 2025 2:14 am
Curved rails are managed by sprites and it seems reasonable becaus eit can became really complex because they hold a lot of details.
But the fact is that wires are monocolored and mostly empty sprite that is stretched and skewed, on some cases they are so thin that they are barely visible.
I didn't realized wire were sprites and the implications before reading your post but i knew rails are The reminiscence i guess came from seeing those bezier curves applied to some game objects, the position of the train on the rail while moving should match the sprite of the rail, the calculation for this was discussed on the forum with user showing some desmos graph to present formulas that would do that depending on how the rail sprites were going to be. Maybe it's not too similar i wanted to toy around to see what i could understand.
y.petremann wrote: Wed Oct 08, 2025 8:10 am
Sorry for unknow reason, my shadertoy demo link has problems and the account too, so simple paste the code in a new shadertoy
I have tried again today to access shadertoy and it still didn't work only the main page was accessible, tried 2 browsers and different settings for adblockers only to realize that i needed to be logged in to access the rest of the website. It wasn't the case for the first attempt (and others month ago) so i don't know what's going on currently and wether or not that impact the demonstration for other people than me but i wanted to let you know in case.
Eventually tho i was able to follow the instruction and add a 4rth power pole to try and make a rectangle . It felt a bit like magic to see the curvy shadow while the wire is straight and made more clear the differences between what describe the attach points location and what describe the existing connexions.
y.petremann wrote: Sun Oct 12, 2025 2:14 am
My proposal is for drawing wires using shaders so we can manage those edge cases in a better way,
I imagine that a better version could use a shader that use straight wire sprite, so modders could customise the sprite without touching the shader (this would allow to theme as christmas garland for example)
On the other hand some players could install mods that modify the shader for alternate pathing (like removing the curve or having orthogonal pathing)
I understand the argument for visibility in those edge cases were the streching and lack of anti aliasing could hinter visibility. Your customisation example made me think of planet with lower gravity where there could be a tweak to the formula so the wires are strung up, and on space platform, how there's no gravity there, the wire could be "floating", wobbly and possibly animated, slowly ondulating , then i remembered that the first part of your code is still a bit like magic to me, but at least it i could use the demo properly this time
It's still a bit like magic but also AI are magic, and you can solve magic with magic !
The side effects are i'm not sure how it works, and i don't know what's wrong with the wire color, i only used AI to modfiy the code with my silly idea after i made the rectangle to see if it would work, that's why the comment in the text.
Your setup looks more realistic
Re: Improve Wire Rendering
Posted: Sun Oct 12, 2025 6:44 pm
by y.petremann
Here it's totally unoptimised, consider that on every pixel, it will get to check if it's near a cable:
1) we have sdSegment that return the distance of any point to a segment defined by two points.
2) we have sdBezier which does a 12 point interpolation of a bezier curve, use sdSegment on each part of the segment, then use the minimum value
3) finaly we have renderwire that use sdBezier to check the distance of a point to the bezier curve (the wire) and use smoothstep so that wire edge is "antialiased"
Comparing to your demos, I tried to be faithfull to some rules about wires in factorio, the sun is from west and you look from south, so for a wire that goes from north to south, it's straight and it's shadow is curved, and for a wire that goes from east to west, it's curved and shadow is straight. I've seen that the devs had rejected similar proposals just because it didn't respect this rule (and they are totally right about it).
Re: Improve Wire Rendering
Posted: Mon Oct 13, 2025 8:09 am
by Ihmemies
You really get some thicc wires with the original sprite based mod (you can select which wires you want to be thicker)
Unless they are vertical in which case RIP (you can see the huge difference in readability in the screenshot below)
Vertical wires being the most hard to read anyways, and the mod not working with those, I endorse a rewrite for the wire rendering. With a better rendering method you could also change the wire colors to be more readable by color blind people. Especially the red-green combo used in current wires is not helpful at all for many color blind people.
Thanks.
Re: Improve Wire Rendering
Posted: Mon Oct 13, 2025 10:53 am
by mmmPI
y.petremann wrote: Sun Oct 12, 2025 6:44 pm
Here it's totally unoptimised, consider that on every pixel, it will get to check if it's near a cable:
1) we have sdSegment that return the distance of any point to a segment defined by two points.
2) we have sdBezier which does a 12 point interpolation of a bezier curve, use sdSegment on each part of the segment, then use the minimum value
3) finaly we have renderwire that use sdBezier to check the distance of a point to the bezier curve (the wire) and use smoothstep so that wire edge is "antialiased"
I have no idea what i'm doing, so thanks for letting me know
I have changed the 6 to 12 for the smoothness of the curve myself, i tried toying around with other values to see what would happen, sometimes it broke the shadows or change orientation, in the end i wanted to see how it would look if there was "no gravity" so the wire would be straight and animating an increase of gravity, but now i realize the vertical wire aren't affected in the first animation, maybe that's why it look a bit ridiculous like a hammock.
The animations are also further modfied by the sceen recording i suppose, so for the antialising, i can't tell wether it's your original code, something the AI did that i don't get, or the screen recording that's responsible the most. If the AI version have added antialiasing, i'm not aware, if your version had it already, i couldn't recognize it was happening
y.petremann wrote: Sun Oct 12, 2025 6:44 pm
Comparing to your demos, I tried to be faithfull to some rules about wires in factorio, the sun is from west and you look from south, so for a wire that goes from north to south, it's straight and it's shadow is curved, and for a wire that goes from east to west, it's curved and shadow is straight. I've seen that the devs had rejected similar proposals just because it didn't respect this rule (and they are totally right about it).
Now i realized i had it backward in the first animation, it's not just my vertical wires that were wrong, but also the shadow of the horizontal ones, that must participate in the silly look whereas your original proposal is strikingly similar to the game, except for the width of the wire For the second animation, it was supposed to be a space background, but then you couldn't see the shadows, and when considering what the shadow could look like in space i was a little puzzled and stop thinking about it x)
Also the tension is poorly defined, but when reducing the amplitude of the wooble it doesn't show as much that the wire oscillate top-bottom when horizontal and left right when vertical, which makes little to no sense, slower with a tiny bit of randomness can probably help making it look like wires are floating in 3D without gravity. ( and also kill any optimization probably )
I understand the main point is increased visibility and it was quite well demonstrated by @ Ihmemies, +1 for the suggestion
It's also fun to toy around x) thanks for sharing the code snippet and explaining a bit, now i'm thinking maybe when the space platform moves, the wire could reflect the drag by bending backward, or maybe some explosions like rockets could have their blast shakes the wires nearby, not as a suggestion, just to toy around with the shader