-
-
Notifications
You must be signed in to change notification settings - Fork 21.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add primitive 2D meshes #100574
base: master
Are you sure you want to change the base?
Add primitive 2D meshes #100574
Conversation
Join the 3-Vertex-CircleShape-Club. |
I like it, but to be honest, I'm not sure whether this really closes the linked proposal. |
9fd8bb4
to
d6338d6
Compare
The A leftover from the Godot 3 days that used opengl canvas item triangle arrays while Godot 4 uses actual meshes. |
I was going to object, pointing out the
The proposal asks for the ability to draw simple 2D shapes. It's not clear if those who voted on it also wanted outlines and fake anti-aliasing (or different kinds of triangles).
It is meant to fill a feature gap (primitive 2D meshes). It's partly an alternative to that PR.
I do agree those are nice features. Outlines should be achievable with this PR, e.g. with a material. I don't know much about how to achieve fake anti-aliasing, but I'll look into it. Edit: One way to add an outline to a shader_type canvas_item;
uniform float outline_width = 5.0;
uniform vec4 color: source_color;
void vertex() {
vec2 direction = normalize(VERTEX);
if (length(direction) > 0.0) {
VERTEX += direction * outline_width;
}
}
void fragment() {
COLOR = color;
} |
For meshes, is it really expected that fake antialiasing is supported, when there is real 2D edge antialising available by using MSAA? If we go by parity with 3D meshes, there shouldn't be an expectation that meshes antialias themselves, IMO. (I'm also not sure if this closes the linked issue, but that seems like a separate concern) |
this is very useful for those of us directly using the rendering server who want easy to use pre made meshes 👍 |
d6338d6
to
c5f4f8c
Compare
From the notes of the rendering team meeting on 19/12/2024:
The latest push adds an (Anti-aliasing is disabled for the procedural shapes on the right.) Testing / reviews welcome! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked only RectangleMesh2D generation, left some comments.
Vector2 rect_size = size; | ||
Vector2 uv_scale = Vector2(1, 1); | ||
Vector2 uv_offset = Vector2(0, 0); | ||
if (antialiased) { | ||
rect_size -= Vector2(FEATHER_SIZE, FEATHER_SIZE); | ||
uv_scale = Vector2(rect_size.x / (size.x + FEATHER_SIZE), rect_size.y / (size.y + FEATHER_SIZE)); | ||
uv_offset = Vector2(FEATHER_SIZE / (size.x + FEATHER_SIZE), FEATHER_SIZE / (size.y + FEATHER_SIZE)); | ||
} | ||
Vector2 start_pos = rect_size * -0.5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the uvs I'm not sure if it's desired that toggling antialiasing makes the texture "move":
Shouldn't it be shown exactly the same within the original rect regardless of the antialiasing, plus for antialiasing just add additional "smears" around? 🤔 (I think this would need more vertices for the corners though so it would interpolate correctly)
Also is it supposed to be FEATHER_SIZE
-wide on each side, or FEATHER_SIZE * 0.5
on each side? Cause currently the original rect size is growing by FEATHER_SIZE
, not by 2 * FEATHER_SIZE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now turning on antialiasing shrinks each shape by FEATHER_SIZE * 0.5
and adds a border of size FEATHER_SIZE
, so that the halfway point between solid and transparent lines up with where the border used to be. I did it that way to preserve the visual size, which works well at sizes a bit bigger than your tiny 5px rectangle. Maybe we could scale the feather size with the regular size (for tiny shapes), but it would become a bit unintuitive.
I would have liked to keep the texture shown the same way when antialiasing is toggled, but since there is no general UV scale/offset available to manipulate I think the only way would be to give the non-antialliased shape a shrunk UV map, which would be awkward as well for people who just want to use a normal primitive shape.
Allows drawing (anti-aliased) 2D shapes using MeshInstance2D. Based on the code for primitive 3D meshes.
c5f4f8c
to
34b0ed6
Compare
I tested this PR and #99210 is much better UX-wise. Although the proposal pretty much only requests something to draw shapes, so this PR does the job too I guess. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The icons are the same as for Shape2D.
You could make them filled at least.
I don't have the ability to comment on UX and code quality stuff but i can say that that PR does not offer near the same convenience for certain work flows . For example this PR allows making meshes you can pretty much directly throw at the rendering server. for the other pr such usage would require instantiating the node in code then generating the meshinstance2D from the nodes drop-down then getting and saving the mesh from that meshinstance and then using it on the rendering server, which is comically obtuse maybe i'm wrong and a step or two can be spared but it stands that these do not ( imo ) target the same use cases an should not be seen as true alternatives ( not necessarily saying you are treating them as such ) |
Note that this also adds these options to MeshInstance3D as well. They work, so I don't think it is an issue. When a capsule is at its minimum height to radius ratio and anti-aliasing is on a line shows: Using the circle to make polygons would be better if they pointed up instead of down. There is no way to make a right triangle with these, but I don't know how much demand there is for it. Compared to #99210 sizes are changed from 128x128 to 20x20, I feel like that is a bit small but maybe its just me. This could have custom handles like the CollisionShape2DEditor for better usability so resizing doesn't scale. There is no conversion to other types, and it is trickier since it is not stored as a polygon. I was thinking that there could be an alternate way to define the 2D shapes to make the code smaller and easier to use. Since they are all 2D, they can be defined by a polygon (a list of points). It can convert the points into the required mesh vertices, indexes, and UVs. This would be on top of the regular functionality so it is optional. All the antialiasing (or outlines if added) could be added there and generically used for all of the shapes. If it is stored it would also be useful to convert into other types in the Editor. I guess its is pretty similar to what Polygon2D does, but saved in a Mesh Resource.
If all of this can be done, I think the UX would be better than #99210. |
Adds
RectangleMesh2D
,CircleMesh2D
, andCapsuleMesh2D
, inheriting from the virtual base classPrimitiveMesh2D
.Allows drawing 2D shapes by using the existing (but so far perhaps underused)
MeshInstance2D
node:Example project: godot-primitive-mesh-2d.zip
The two fancy shapes on the right are obtained by applying vertex shaders to primitive meshes (kind of silly, but it works).
If you want a triangle, use aPolygon2D
instead.The code is based on the code for primitive 3D meshes.