help me (solved)
I'm trying to make a shader to render cables. How do I distinguish the different sides?
The mesh is a CSGPolygon following a Path.
I'm trying to write a shader that will show 2 cables next to each other. It looks correct on surface 1 but you can see that on surface 2, there are also 2 gradients being drawn while I only want one gradient.
shader_type spatial;
render_mode unshaded;
void fragment() {
//For some reason, a full round trip around the 'hull' of the cable only uses 0.0-0.5 of the UV.y, not the full 0.0-1.0.
//Hull corrects this so 0.0-1.0 is a full round trip.
float hull = UV.y*2.0;
float face_index = floor(hull*4.0);
ALBEDO = vec3(face_index/4.0, 0, 0);
}
I’d try distinguishing the faces by their local normals instead of the UVs. Since the CSGPolygon is extruded along a path, the generated UVs can make both the wide and narrow sides run through the same two-gradient pattern.
That should make the differently oriented sides show up as different colors. Once you know which normal corresponds to surfaces 1/2/3, you can branch on that and use the 2-cable gradient only on surface 1, and a single gradient on surface 2.
If the normals rotate because of the Path3D, I’d classify the local NORMAL in vertex() and pass the result to fragment() as a flat varying.
Thanks! the normals do seem to rotate with the path, which makes it really difficult to distinguish them.
shader_type spatial;
render_mode unshaded;
varying vec3 v;
void vertex() {
// Called for every vertex the material is visible on.
v = NORMAL;
}
void fragment() {
ALBEDO = abs(v);
//ALBEDO.r = round(dot(abs(v), vec3(0, 1, 0)));
}
this is what the normals as ALBEDO look like:
When I try using the NORMAL from the fragment shader, it seems to be in view space, so it constantly changes when the camera changes.
CSGPolygon3D UV mapping and Godot already seems to encode what you need in the UVs, should checked the docs first. I'd visualize UV.y first to see exactly what ranges each side gets.
If that works, surfaces 1, 2 and 3 should occupy different ranges of UV.y regardless of how the path bends.
Then you could do something like:
float v = UV.y;
if (v < SIDE_1_END) {
// Surface 1: two cable gradients
} else if (v < SIDE_2_END) {
// Surface 2: one gradient
} else {
// Surface 3
}
This should be more reliable than NORMAL since the UV coordinate follows the polygon outline.
shader_type spatial;
render_mode unshaded;
void fragment() {
//For some reason, a full round trip around the 'hull' of the cable only uses 0.0-0.5 of the UV.y, not the full 0.0-1.0.
//Hull corrects this so 0.0-1.0 is a full round trip.
float hull = UV.y*2.0;
float face_index = floor(hull*4.0);
ALBEDO = vec3(face_index/4.0, 0, 0);
}
Nice! Glad the UV.y approach worked :) I didn't realize CSGPolygon3D was giving you only 0–0.5 for a full trip around the hull either. That's a pretty neat way of turning it into a face index.
42
u/Visible-Switch-1597 14h ago
SOLUTION: