Mesh Normals and Auto Smooth in 4.1 #93551
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
22 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#93551
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Background
This document describes changes to the calculation of mesh normals meant to address some of the performance and usability problems, non-exhaustively listed here:
short2
in a special coordinate space defined by the automatically calculated normals. Converting to and from this coordinate space is expensive.Solutions
Procedural Custom Normals
Two new geometry nodes features can allow reading and writing custom normals in a procedural context.
For the "plain vector" format, the regular
float3
attribute type can be used. Potentially, meta-data could tell geometry processing algorithms to interpolate the attribute differently if they support it (a simple case is the "Transform Geometry" node). But generally the existing custom normals spaceshort2
storage should be used if better interpolation is necessary.Curve Normals
Custom normals should be possible for curves too, though with a separate node since the options are different. The existing "Set Curve Normal" node can be used to set custom per-point normals. These may be automatically changed later to make them perpendicular with the tangents.
The creation of a per-curve "up" vector attribute to influence the starting direction used for normals calculated automatically with the existing modes could be supported too.
Replace "Auto Smooth"
The existing auto smooth option
By writing to the
sharp_edge
attribute, we can have the same effect as auto smooth with a geometry nodes modifier. Versioning code replaces the property with this modifier.The modifier that replaces the property
The modifier keeps the same behavior as before, but often it isn't necessary to change the sharp edges in the modifier stack-- doing it once in edit mode is enough. Similarly, applying the modifier can avoid changing sharp edges over deformation and give better performance. Using a modifier also gives an intuitive way to disable the effect in the viewport, without requiring drivers.
This existing edit mode operator is also useful
To keep the existing behavior accessible, an new operator with the same "Auto Smooth" name can add this modifier. Eventually though, the node group should be moved to the Essentials asset bundle. That can happen as soon as we have a quick way to add node groups assets as modifiers in the property editor.
Combined with the next auto-domain-choice change, this gives proper control of split face corner normals to geometry nodes. Without the auto smooth option, joining meshes with different sharp/smooth attributes would just work, without relying on the first mesh having auto smooth set. Having the final sharp edge status as part of the visible state of the mesh is essential to make this work.
Using modifiers for this sort of behavior unifies Blender's design to use user-controllable geometry nodes for geometry processing operations. This design is more obvious in the big picture considering a future where "everything nodes" improves the consistency, power, and reliability of Blender features, makes UX more consistent, and improves the development process.
Automatically Determine Necessary Domain
With the
sharp_edge
andsharp_face
boolean attributes, we have all the information we need to know whether we need normals per-face, per-vertex, or per-face-corner. This information is important, because the performance difference between the three is quite large. When the mesh is entirely sharp, face normals are enough. When the mesh is entirely smooth, we need to calculate vertex normals. If there is a mix, we need "split" face corner normals.This change makes the "Auto Smooth" property unnecessary, since one of its main uses was to avoid the performance cost of face corner normals. It's easy to figure the necessary normals automatically, completely removing this step in using mixed smooth and sharp shading, without paying a performance cost in the simpler cases.
The previous workflow:
The new workflow:
Partially this is just a performance optimization (enabled by the removal of auto smooth as a property), but it's also a conceptual change. After the change, the sharp shading status is clearly part of the visible state of the mesh that can be "frozen", it's only the shading that's automatic. Before, both of those things were automatic, happening only internally.
FAQ / Common Concerns
Technical Info
A function
eAttrDomain Mesh::normal_domain_all_info() const;
gives us this information. We can use its result to optimize normal sampling in many places. Viewport drawing would be one important example.Corner normals are now shared with a
SharedCache
, meaning they don't have to be recomputed just because a mesh is copied.Implementation TODOs
Related PRs: #108014
Follow-up design document: #120230
Mesh Smoothing and Normals Design Changesto Mesh Auto Smooth and Normals Design ChangesRemove
shade_smooth
and replace it withedge_sharp
? Does it mean all meshes will be smoothed by default and only be unsmoothed by assigning sharps?Having a geometry node for setting sharps is great, but please retain a simple checkbox and angle slider for this somewhere. Adding modifiers, changing views and editing node trees would make this previously simple task slow, cumbersome, unintuitive and non-discoverable.
Alternatively, make this into a standalone modifier that shares the geometry nodes code.
Edit: Ah. Missed the bit about the modifier in the versioning section. No objections then :)
On the user level, no.
Hmm how does it work then? You said from the user level, does it mean that the user would still think of it as shade smooth, but under the hood it is actually backwards, it is assigning sharp edges rather than assigning smooth flags? I still don't think I get it
Yes, something like that. We could also invert the
edge_sharp
flag and store it asedge_smooth
internally, that doesn't affect the user though. The main point is to get rid of the smooth/sharp option on faces because it's redundant with the smooth/sharp flag on edges.I have a few questions or problems with this proposal.
1 - Removing 'smooth face' flag
This will make some behaviors from user perspective not possible anymore. For example, how do you handle 'set face smooth' operation on a flat face sharing an edge with another flat face?
Point being, you cannot say that edge and face flags are fully redundant, they are both combined to define the final sharp vs. smooth state of edges.
2 - Removing autosmooth from mesh and make it a geometry node
While I agree in general with the idea, imho the fact that it enforces generating a separate evaluated mesh for each object is an issue. And I definitely do not see the proposed 'work around' of using object instancing as an acceptable solution here.
Was wondering if having some obdata-level nodetree was ever considered? That would enable some different level of procedural processing of geometry, with some limitation regarding available 'context' info obviously (no object info...).
3 - Split evaluated normals vs. custom normals
I do not really understand what is the issue that is being addressed here, nor what is the proposed solution. Those two data are already very well separated?
Thanks for the feedback!
Good point. I think it's fair to say they are redundant from the perspective of normal calculation, but from the editing perspective the task isn't quite right.
I think this is okay though, we can offset with better tools for creating edge selections if necessary. That specific change might be for the better.
If users just control the data that's used by normal calculation directly, things might be more intuitive.
That's fair. I guess it would nullify the object-data-sharing design we have now. Though I do think it shows that the design as a whole isn't very scalable.
Object-data level node trees is an interesting idea, but I sort of doubt it would be high enough on the priority list now, so I hope we could find a design that wouldn't depend on that.
I wonder if automatically de-duplicating object evaluation when meshes are shared and modifiers are the same would work.
I think they are better separated than I thought when I wrote this task, at least internally. So the point is a bit unclear I guess. Here are some more specific suggestions:
Also, separate point-- I think it makes sense to allow setting custom normals directly as 3D vectors from a performance perspective, which would make more sense in a procedural context.
I do not understand all the details of the discussion, but as someone who is already working a lot with Normals in Geometry Nodes, I can attest that it would be very convenient if we had full access to Normals of each Domain, and Custom Normals, and the ability to properly set them from within GeoNodes.
I am giving this feedback to show that there is interest in these features among some users (Stylized/Toon/NPR artists). I know that these sorts of features would not be used in many workflows, but I hope we'll still get these options.
Currently, I am doing all sorts of extra/redundant edge splitting and interpolation to achieve within GeoNodes things that are standard outside of it. The lack of access to Custom Normals has also been a major blockage. If we also had UV Tangents available in GeoNodes for Normal Mapping, we would have full flexibility.
I'm not sure how to understand normals for all types of domains.
Since the render object is a polygon, it is logical that it is the only one that has a normal.
But since we won't have enough vertices for complex normals for several polygons, it is logical that we are talking about a face corner.
I'm not sure how edge normals should blend correctly for face corners as they do for vertices.
Ah yes, I mean Face, Vertex, and Face Corner (which all end up as Face Corner). I don't think much can be done with Edges Normals except perhaps some curvature stuff.
Been trying to make game art tree meshes with a GeoNodes network. Surprisingly, it's been very simple, up until the point at which I actually need to transfer the normal information to the final mesh. Being able to set & bake down custom normals per Face Corner / Vertex would be excellent. I've been able to view exactly the normals I want to achieve with the viewer node in the 3.4 beta, but I have no way to actually bake these down to face corner data.
From the dummy artists to the folks who implement this on the code side, ty for working on this. GeoNodes are immensely cool and starting to finally come into their own with regards to generating game ready assets.
The most important part I can control if the edge to be "Hard" or "Soft".
this will make life easier.
adding sharp edge and soft edge will be great step.
This solution may solve this task: #107376
I started to work on this here: https://projects.blender.org/HooglyBoogly/blender/src/branch/refactor-mesh-corner-normals-lazy
That branch contains most of the changes except for the ability to set custom normals in geometry nodes.
Hans Goudey referenced this issue2023-05-02 14:45:37 +02:00
Mesh Auto Smooth and Normals Design Changesto Mesh Normals and Auto Smooth in 4.0The workaround is a bit simpler actually, the new modifier can be applied to the mesh (or the same thing can be done with an operator in edit mode). For non-deformed meshes, the results will be the same. For deformed meshes, they would have had a separate evaluated mesh per object anyway. We can't really do this automatically though.
Some feedback on the design:
Applying a modifier is final and definitive, you cannot edit the values anymore. You would need to add the modifier again, and apply it again, every time you need to change the settings. So I don't think this properly replaces the current autosmooth feature either.
The current autosmooth behaves like an ObData-level modifier/geometrynode tree. Moving it to Object level is anything but a trivial decision. I would like to see a more strong compelling reason than those exposed so far for this change.
On a technical note, adding or removing modifiers (like any other object-mode-level operation) should be avoided at all cost in Edit modes, this is not well supported by undo system currently.
Sorry that was unclear, I'm not proposing that we do that. The operator in edit mode just works as it does now, just changing the sharp edge data directly.
We'll most likely be able to hide these panels in 4.0, luckily, as part of the work on node panels. As part of more general "assets as modifiers" work, we could consider hiding the node group selector by default, just like we do for nodes. I don't see this as blocking though.
Yes, I agree about this. Ways to add node group assets directly as modifiers are planned, but I don't think we'll have time to get to it for 4.0. Again, not blocking for this specific change IMO, but it does make it a bit more urgent.
I get your point, but in the longer term I think the consistency of having features built out of visible, editable node group assets will be very important. Users can tweaking, and learn from builtin groups. And giving a generic interface for user-created and builtin features is a huge opportunity for Blender as a whole.
The point is to make the behavior more generic, so it becomes more predictable, more performant, and more consistent with the rest of Blender and user created tools. The fact is, we don't have object-data level modifiers/nodes, and I don't think we will any time soon. Actions are applied to geometry on the object-level, that's just how things work.
Also, the benefit of the old "procedural" auto smooth behavior compared to running a static operator is questionable. Users may run the operator to set sharp edges more often, or computation might be duplicated between objects before the modifiers are applied, but I see those downsides as far outweighed by unified, consistent behavior that actually mirrors what's happening internally.
I don't mind it being built on geometry nodes by itself. My main concern is that users will ask how to do the equivalent of the old autosmooth in 4.0, and if the answer is that they have to manually create a geometry nodes modifier and add an autosmooth node in a node editor, that's not very satisfactory.
If we can integrate bundled node group assets into the modifier add menu somehow it would be fine, but I'm not sure if something like that will be in 4.0?
My idea was to include an operator in the Mesh menu in object mode called "Add Auto Smooth" which would add the modifier with the specified angle. That would be an alternative to the operator editing the "sharp_edge" attribute directly. It could also be part of the existing "Auto Smooth" operator, as an "As Modifier" option. That's the one thing I didn't get to implement in the branch yet though.
I'd love to say it would be in 4.0 but I don't think that's realistic unless we skip working on something like node tools. That operator setup I mentioned could be replaced when assets and the add modifier menu are integrated though.
I agree with Brecht.
Autosmooth is often massively applied over a huge number of an objects simultaneosly, autosmooth as modifier is a concept which is hard to handle and control its distribution.
For example, eliminating it for the objects that also has different modifiers stacks will be problematic.
For what it's worth, here's my two cents. Having control over custom normals from geometry nodes would be very useful, however, as someone who does quite a bit of hard-surface work and uses Auto Smooth, having to manually add an asset/GeoNodes modifier would be kind of a massive pain. I agree with Brecht that just adding an Edit/Object mode operator which automatically appends and applies an AutoSmooth nodegroup feels like a workaround in order to prevent the feature from being unwieldy. As Brecht says, anyone who used this feature will say 'well how do I do it now?' and be a bit sad upon opening older files to find that Auto Smoothed objects are all just smooth (or flat) now and need extra work. I mean I was asking myself what the alternative method would be halfway through reading this proposal.
The other point I wanted to mention was the 'Add Auto Smooth' idea of an operator which does the smooth shading and applies it there and then. Almost every use I've found for the Auto Smooth option it's a procedural, non-destructive workflow. I.e. you set that flag, and then you can just start work modelling and your mesh will appear smoothed appropriately as you work, so you can see what it looks like in real time and inform creative (as well as technical) decisions. Based on the fact that it's literally called Auto Smooth, I'd strongly be on the side of non-destructive being the default behaviour, and 'applying' those edge and face sharpness flags to the mesh destructively as a final step: case in point, for a lot of hard surface work the very final step is to apply split normals data, then go through and split/mark sharp any other edges you want finer control over.
The only solution I can think of would be to more closely integrate asset GeoNode modifiers with built-in modifiers, for instance by splitting the 'Add Modifier' selection pane to have an extra column for GeoNode assets from libraries (that way Auto Smooth is still one click away, no going to the asset browser and appending, then going back to modifiers, etc etc), or to break that 'Add Modifier' dropdown button in half, and have the right side bring up a similarly formatted pane which lists GeoNode assets which are available.
However, this is rather a bigger proposal (though I think one which would be very useful beyond just fixing Auto Smooth).
To be clear, the node group is added by versioning code. The results of existing files or meshes do not change.
Yes, I agree with this. Considering the points above, it probably makes sense to do this for 4.0. The add modifier menu should change into a search menu, and geometry node group assets can have an "Is Modifier" option to make them show in the add menu. Ideally we can do this in a separate step from the initial change though, we'd just need to agree on a design.
I still think an operator to add or remove the modifier asset would be useful though. Like you said, that could be the default behavior-- that sort of thing can be easily changed during a polishing phase.
FBX, and possibly other exporters, use
create_normals_split()
and then access the corner normals. This gets the normals taking into accountuse_auto_smooth
andauto_smooth_angle
(and faces/edges marked as sharp and custom normals).With the change to move Auto Smooth to a Geometry Nodes modifier, as far as I can tell, to access the normals after the effect of Auto Smooth would require either applying the Geometry Nodes modifier or accessing the normals from the evaluated mesh.
A possible problem I see currently is that FBX supports exporting shape keys, which is done by using the mesh directly without evaluating it. Loading a .blend into a newer Blender version that replaces
use_auto_smooth
with a Geometry nodes modifier through versioning code would currently result in exporting normals without Auto Smooth taken into account compared to exporting that same .blend in an older Blender version.The FBX exporter has an option for applying modifiers, but that is done by using the evaluated mesh, which means shape keys can't be exported.
Thanks for bringing that up. In some cases the
set_sharp_from_angle
Mesh API function might be helpful in some situations. But I'd imagine that the exporter would want to detect the modifier and node group to find the angle. That seems not ideal from an implementation perspective, but as Blender adds more node-based features in the future that will probably only happen more.I added some common concerns / a FAQ to the design task.
Hello,
First question: Is it only for "auto smooth", or also for "Custom Split Normals data" (that requires to have auto smooth ON) ?
I can see impact on glTF importer in case we can't create some normal layer anymore.
Like FBX exporter, for glTF, I not sure how to manage exporter if we have only the modifier instead of autosmooth. Applying modifier to get the normal data will prevent exporting shapekeys.
Hi! For the first question, this only affects auto smooth. Using custom normals gets a bit simpler actually, since it doesn't require turning on an "Auto Smooth" option anymore.
Second, could you clarify why applying the modifier would prevent exporting shape keys? Making a local copy of the mesh and setting sharp edges based on the same angle as the modifier should work too.
If it doesn't require it anymore, how can you preview the smoothed mesh normals without deleting the custom normals layer? It's kind of important to be able to do this when working with, say, models from CAD apps because it allows you to easily see problems with the imported mesh.
I think that would be possible once custom normals (the ability to set and clear them) is exposed to geometry nodes, which is the next step.
I think he meant that in order to export to FBX or GLTF modifiers needs to be applied, however, if an object has shape keys you can't apply modifiers anymore.
I guess it's more a modifier/shape keys issue ...
Bastien, Campbell, and I just met about the state of this task/PR, we agreed to move this from 4.0 to 4.1.
In the extra 2.5 weeks I'll cover the TODO items mentioned in this task above.
Pros of 4.0
Pros of 4.1
Mesh Normals and Auto Smooth in 4.0to Mesh Normals and Auto Smooth in 4.1sounds like you’ve got this under control. looking forward to when we see this in 4.1!
Thanks for this great summary of the meeting Hans! Would suggest to move the bullet points in the task itself (under e.g. a
TODO for 4.1 merge
section or so)? Easier to keep track of these then.Thanks for the status.
Feel free to contact me for any question regarding glTF I/O
Hi @HooglyBoogly,
Feedback following tests...
When opening older files, wonder if informing people
Auto smooth
has been renamed toSmooth by angle
, and keeping just one modifier is simpler?Rationale:
Smooth by angle
name.Auto smooth
modifier when searching the modifiers list.Smooth by angle
modifier has the extra useful 'Ignore Sharpness' feature, plus layout appears simpler and cleaner.In case helpful, noticed some differences when opening older files, appears if there's a
WeightedNormal
modifier,Auto smooth
/Smooth by angle
modifiers need to be automatically added just before it, or not added at all?Kind regards.
Would it be possible to simplify this further by just have a single shading normals attribute that's updated whenever the connected vertices are moved. Adding a 'lock_shading_normals' attribute per vertex would indicate the shading normals should be the calculated normals + offset, and unlocked = calculated smoothed normals.
Marking a face or edge as sharp, would just modify the shading normals and mark them as locked.
It's a bit confusing now for example if you have a smooth by angle modifier followed by a weighted normals modifier, because when you apply them, you end up with a combination of edges automatically marked as sharp for you in edit mode, plus custom split normals get created when applying the weighted normal modifier. Would be far simpler for both to just modify a single shading normals attribute and not generate sharp_edge or sharp_face data.
I think the sharp_edge and sharp_face attributes could probably be ditched and just calculate the overlays and 'is edge smooth'/'is face smooth' from the single shading normals attribute of connected vertices. Maybe store them in a non user facing variable to avoid recalculating unless modified.
for performance, don't store the attributes in the actual mesh, attach a separate table for each attribute to the mesh, then you don't have to traverse the entire mesh when reading an attribute that might only be set to something meaningful for a few verts/faces/edges, row 1 = default to be used if a record isn't created for a certain element index. This will also save a lot of memory on large models, where only a few indices have the attribute set to something other than default.
I have some concerns that this is listed as a breaking change for 4.0, but there is no solution for breaking instancing for those objects.
For production scenes which are geometry heavy, and rely on instancing, this would be a major issue.
Has there been any proposal on fixing this issue?
With the current design, I think the smooth by angle option in the context menu should create a modifier rather than adding sharp edges, because that will result in the same expected behaviour found in previous blender versions, where the shading would constantly update to adhere to the selected angle when modifying the mesh. Maybe have 2 options in the context menu: shade by angle (current shape), and shade by angle (continual update). Or maybe better still the context menu could have: 'add shade by angle modifier' and 'generate sharp edges from angle'.
The sharps should only be created when modelling is complete and the user chooses to apply the modifier (although having a single shading normals attribute that gets modified instead of creating sharp edges would still be my preference).
Sorry, but let me add small user feedback.
Nodes and modifiers are great!
But please do not forget that some still use a Blender for CAD modeling. Where bevels/chamfers are so often needed to tweak an angle-based smoothing. Sharp or Smooth is quite unusable, as a manual mark edges sharp.
Tweakable angle-based smoothing is important for linear/CAD, hardsurface and organic modeling domains, since provide visual feedback about surface curvature.
Has there been any work on the concerns about this change to Blender 4.1? It seems like a significant step backwards.
I've been waiting for "Start implementation of custom normals geometry nodes" so much! Thanks a lot for your hard work.
Well, any generative stuff will be useful, but only for generative workflows.
Big picture design task has been implemented. There are still some followup fixes, not tracked here though.
I'd like to get basic "dumb vector" custom normals support in geometry nodes in 4.2, but I can't be sure I'll have time for that yet.
Blender 4.2 > FBX > Unreal Engine 5 = no custom normals :(
I am using data transfer modifier to transfer vertex normals from continuous model onto split model, so it would appear seamless in game. In Blender it looks as it suppose to look:
but in UE it doesn't:
I tried all kind of FBX export settings in Blender, coupled with FBX Import settings in UE - nothing works.
Best to report a bug with a file that reproduces the issue. Thanks.