-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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
Allow overriding face materials & UVs for CSGBox, CSGCylinder, and CSGPolygon #59266
base: master
Are you sure you want to change the base?
Conversation
This is a good idea (one that I've been thinking about for a while). However, I'm not sure if this will be very usable in practice since you have to apply the material on faces one-by-one (without being able to drag and drop materials onto faces). This is especially the case if you've rotated the CSG node beforehand, which means that the top face may not be at the top anymore (for instance). SaracenOne is working on implementing material drag-and-drop support in The changes mentioned above would definitely break compatibility with existing projects, so this needs to be considered before 4.0 is released.
I'd say yes and yes 🙂 Also, CSGCylinder and CSGPolygon should probably have an override property for the "sides". This is useful when you only want to override the sides material, not the top and bottom. This would also be more consistent with CSGBox having 6 material properties (rather than just 5). |
f334651
to
f47abf1
Compare
I couldn't think of a cleaner way to expose these at the moment. I thought of just exposing them as indices like in After #56597 is merged, we can do some face normal comparisons to determine what face is under the mouse pointer and set the correct material.
This is now done 👍 |
d479d59
to
5d1f51d
Compare
This comment was marked as outdated.
This comment was marked as outdated.
After some thinking, I think that this approach to defining face materials is not good in the long run. It is too limited and offers no way for future extension. Instead, I think the correct way would be to expose the surfaces as an arbitrarily long array of surface overrides. In the future these surface overrides can be extended to allow specifying uv transformations as well. I am going to rewrite this PR soon, if anyone has opinions on this I would like to hear them. |
Isn't this done for CSGMesh already? On the other hand, I agree that the approach in this PR will show significant limitations if you use it for CSGPolygon (where you may want to apply a specific texture on one part of the sides only). |
CSGMesh yes, but not others I think. |
I accidentally added UV editing while I was refactoring 😅 Kooha-04-08-2022-15-40-23.mp4I'll do some minor clean up, then this should be ready to go! |
5d1f51d
to
d3567cb
Compare
837d35c
to
740f506
Compare
I think this should now be ready for review. One thing that bothers be is that there's awful lot of repetition here, would it be good to move these override getters/setters under |
3a9e713
to
08868b6
Compare
08868b6
to
7164629
Compare
Does this PR only duplicate surfaces when needed? For performance reasons, we should avoid duplicating surfaces when they use the same material (or no material at all). |
I'm not sure what you mean. The default material is used for surfaces that are not overridden. Or do you mean that when same material is used twice (or more) on different surfaces, it'd point to the same material and they'd be rendered in the same pass? |
Yes 🙂 This should also apply to the fallback material (i.e. when a face doesn't have any material set). That said, the number of surfaces is different from the number of materials. If you want rendering to be able to use instancing (dynamic batching), it needs to avoid using multiple surfaces, not just multiple materials. Otherwise, each surface will be in its own draw call. |
Hmm.. I have no idea how to do this. Can anyone help? Also, I would like if someone could review the code. 🙏 |
@gaudecker @Calinou any update on this? Is it abandoned or can we assume it will be shipped in some (hopefully not that far) future? TBH this is a great and powerful improvement and Godot could really use it. |
You can consider this abandoned. I assume this never moved forward for the same reason as #59386, there should've have been a proposal first. I personally don't have time or energy for that at this point. |
Shall I go ahead and mark this as salvageable? And someone can pick it up if you end up not coming back to it 🙂 |
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.
Leaving these for a future salvager of this PR
face_uv_transforms.set(p_face, transform); | ||
_make_dirty(); | ||
} | ||
Vector2 CSGBox3D::get_face_uv_offset(int p_face) const { |
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.
Vector2 CSGBox3D::get_face_uv_offset(int p_face) const { | |
Vector2 CSGBox3D::get_face_uv_offset(int p_face) const { |
Separate methods
face_uv_transforms.set(p_face, transform); | ||
_make_dirty(); | ||
} | ||
float CSGBox3D::get_face_uv_rotation(int p_face) const { |
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.
float CSGBox3D::get_face_uv_rotation(int p_face) const { | |
float CSGBox3D::get_face_uv_rotation(int p_face) const { |
face_uv_transforms.set(p_face, transform); | ||
_make_dirty(); | ||
} | ||
float CSGBox3D::get_face_uv_skew(int p_face) const { |
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.
float CSGBox3D::get_face_uv_skew(int p_face) const { | |
float CSGBox3D::get_face_uv_skew(int p_face) const { |
face_uv_transforms.set(p_face, transform); | ||
_make_dirty(); | ||
} | ||
Vector2 CSGCylinder3D::get_face_uv_offset(int p_face) const { |
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.
Vector2 CSGCylinder3D::get_face_uv_offset(int p_face) const { | |
Vector2 CSGCylinder3D::get_face_uv_offset(int p_face) const { |
face_uv_transforms.set(p_face, transform); | ||
_make_dirty(); | ||
} | ||
float CSGCylinder3D::get_face_uv_rotation(int p_face) const { |
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.
float CSGCylinder3D::get_face_uv_rotation(int p_face) const { | |
float CSGCylinder3D::get_face_uv_rotation(int p_face) const { |
face_uv_transforms.set(p_face, transform); | ||
_make_dirty(); | ||
} | ||
float CSGPolygon3D::get_face_uv_rotation(int p_face) const { |
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.
float CSGPolygon3D::get_face_uv_rotation(int p_face) const { | |
float CSGPolygon3D::get_face_uv_rotation(int p_face) const { |
face_uv_transforms.set(p_face, transform); | ||
_make_dirty(); | ||
} | ||
float CSGPolygon3D::get_face_uv_skew(int p_face) const { |
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.
float CSGPolygon3D::get_face_uv_skew(int p_face) const { | |
float CSGPolygon3D::get_face_uv_skew(int p_face) const { |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians")); | ||
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians")); |
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.
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians_as_degrees")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians_as_degrees")); |
New syntax
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians")); | ||
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians")); |
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.
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians_as_degrees")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians_as_degrees")); |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians")); | ||
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians")); |
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.
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians_as_degrees")); | |
p_list->push_back(PropertyInfo(Variant::FLOAT, "face_overrides/face_" + itos(i) + "/uv_skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians_as_degrees")); |
@kryztoval Please don't bump without contributing significant new information. Use the 👍 reaction button on the first post instead. However this has been abandoned by the original contributor so someone else will have to pick it up and make it ready |
Leaving a note on this as my map designer has requested this functionality and if I get tired of hearing him complain about not having it, I'll likely pick this up and get it refactored for the latest codebase. |
Add unique face materials and UV transforms for select CSG nodes.
This is in response to godotengine/godot-proposals#937 and godotengine/godot-proposals#2879
This is backwards compatible, since the old
material
property is used as a fallback when any of the new materials arenull
.Simple demo project:
csg-faces-demo-3.zip