Page MenuHome

New sculpting brush cursor
Needs ReviewPublic

Authored by Pablo Dobarro (pablodp606) on Aug 11 2018, 1:24 AM.
Tokens
"Love" token, awarded by ace_dragon."Love" token, awarded by symstract."Love" token, awarded by mankysee."Love" token, awarded by ish_bosamiya."Love" token, awarded by TheFlow."Love" token, awarded by kioku."Like" token, awarded by capnm."Burninate" token, awarded by billreynish."Love" token, awarded by Largerous."Love" token, awarded by shomyshomy."Love" token, awarded by 0o00o0oo."Love" token, awarded by svankirk."Love" token, awarded by Jaydead."Love" token, awarded by TheCharacterhero."Like" token, awarded by ebarranco."Like" token, awarded by Loner."Love" token, awarded by ofuscado."Love" token, awarded by ThinkingPolygons."Love" token, awarded by elbox01."Yellow Medal" token, awarded by KloWorks."Love" token, awarded by monio."Love" token, awarded by kyjelblue."Love" token, awarded by hjrabi."Love" token, awarded by jmztn."Like" token, awarded by gobb_blend."Love" token, awarded by d.viagi."Love" token, awarded by barracuda."Love" token, awarded by sephirothtbm."Love" token, awarded by julperado."Love" token, awarded by Noss."Mountain of Wealth" token, awarded by Zino."Love" token, awarded by JimMorren."100" token, awarded by shader."Love" token, awarded by JulienKaspar."Like" token, awarded by TheRedWaxPolice."Love" token, awarded by plyczkowski."Love" token, awarded by RyanJEC."Love" token, awarded by jonathanl."Love" token, awarded by johnsyed."Love" token, awarded by eoinoneill.yokai."Love" token, awarded by andreasus."Like" token, awarded by Schamph."Love" token, awarded by fiendish55."Love" token, awarded by xrg."Love" token, awarded by amonpaike."Love" token, awarded by KINjO."Love" token, awarded by pablovazquez."Love" token, awarded by miclack."Love" token, awarded by Alrob."Party Time" token, awarded by Scaredyfish."Mountain of Wealth" token, awarded by charlie."Love" token, awarded by wo262."Like" token, awarded by fclem."Burninate" token, awarded by DotBow."Like" token, awarded by erickblender."Like" token, awarded by Samirosman.

Details

Summary

This patch adds a new brush cursor with surface normal and vertex preview.

I've been testing this for a while and I think that using the face normal is always a better option, even with high poly meshes. The vertex normal calculation with big brushes doesn't give you any useful information about the surface. On high poly surfaces with noise, the brush moves a lot if you are using the face normal, but I think that is the expected behavior. For now, both methods are implemented in this patch for testing purposes.

Diff Detail

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

@Brecht Van Lommel (brecht) @William Reynish (billreynish)

From my experience, I strongly prefer the face normal version. It is not that smooth, but it gives much more precise information about the placement of the cursor in the model, especially on the edges. When sculpting, that preview is much more useful than the real sculpting normal. Furthermore, I don't think the preview normal should change depending on the size of the brush when the placement in the model is the same.

I agree with @Pablo Dobarro (pablodp606)
Williams proposal is also really interesting but could become incomprehensible on more complex surfaces and thin/small forms.
The big worry I have with the face normal preview is that it becomes incresingly jittery the more detail the surface has. On higher resolutions with high frequency detail the brush preview would become out of control.
So perhaps the brush preview could be an overlay option with a slider from 0 -1 that changes the normal.

  • 0 would be the single face value under the center of the brush.
  • 1 would be the average of the full brush size
  • The default could be at something like 0.1 or lower to give an accurate representation of the normal under the curser position but without jittering when above high frequency detail.

I don't know about the performance cost though. Maybe when set to 0 it would simply disable the averaging of the normals anyway, so it's a good alternative.
A checkbox beside this slider to turn off the normal preview also makes sense then.

Also as a sidenote: If something like this would be added then maybe not in the Overlays popup. It's jarring when disabling the overlays that certain essential options (like curve handles) are not affected by this, even though they are among those overlay options.
This is a different issue, I know but it's something to consider.

From my experience, I strongly prefer the face normal version.

Exactly. The face normal option is the most useful for sculpting, no doubt.

jittery

Actually this is nothing, really. Zbrush works pretty much like that, it never was an issue.

Anyway, the author said he can make an option to choose between the 2 modes, so I guess it's all good. 🙂

@ThinkingPolygons (ThinkingPolygons)

Actually this is nothing, really. Zbrush works pretty much like that, it never was an issue.

I just checked the difference. While the single face normal Blender cursor goes completely crazy on high frequency detail, Zbrush seems to have some sort of averaging on a small scale to prevent that. The cursor rotates only slightly there.

This sort of thing would be pretty distracting while sculpting:

@Julien Kaspar (JulienKaspar) @ThinkingPolygons (ThinkingPolygons) I'm pretty sure ZBrush is using the drawing buffer information to sample the normal, so as long as the high frequency detail doesn't appear on screen it will not be taken into account. Also, that method has no performance penalty on high poly meshes and the cursor movement can be smooth even across edges in low poly meshes. I think this would be the ideal solution. I don't know if that is possible to do in Blender neither how hard could it be, but in any case, the whole cursor system would need to be rewritten from scratch to support that.

Won't the 'Sampled Normal' version give smoother results on high frequency detail?

@ThinkingPolygons (ThinkingPolygons)

Actually this is nothing, really. Zbrush works pretty much like that, it never was an issue.

I just checked the difference. While the single face normal Blender cursor goes completely crazy on high frequency detail, Zbrush seems to have some sort of averaging on a small scale to prevent that. The cursor rotates only slightly there.

This sort of thing would be pretty distracting while sculpting:

Zbrush is more smoother in this cases, yeah, and that's why we need both modes.

@William Reynish (billreynish) Yes, but in low specs systems it could be a problem.
Maybe the best option for now is to add the option to enable/disable sampled normal. After that, I could make a patch adding a normal radius option to sculpt mode. That will provide more advanced features in brushes (see D4235) and it will be possible to control how smooth the cursor is using the sampled normal method.

Could it be possible to use the normal of a lower subdivision when using multires mesh modifier as a workaround for that zbrush-style behavior? Basically, when given the option, you use the resolution of the preview to guide a smoothing algorithm so that the brush preview is more subtle on high res models? I don't know what could be done about using dynotopo, but for cases like the above, I would imagine the really high resolution details would be utilizing the multires modifier anyway.

The way I see it in pseudo code:

brush_preview_normal = normalize( (high_res_normal + low_res_normal) )

As I understand it that "normal radius" option is intended to make both the preview and the actual sculpting follow the surface more closely. I think that makes sense, it's the inconsistency that I find problematic. I suggest to use a weighted average with falloff. Simply blending the average and face normal will still be jittery, and a sharp normal radius cutoff will be less smooth.

For better performance average normals, there are a few strategies.

  • Write a normal buffer as part of drawing, and downsample that on the GPU to get an average normal. This is probably fast enough, but actually quite different than the current average which is in 3D space. So it would not match the actual sculpt normal unless that was switched to the screen space method as well.
  • Cache averaged normals per BVH node. This would give a speedup, but not enough as partially overlapping BVH nodes still need to be averaged per vertex
  • Monte Carlo sampling. By averaging a fixed number of random vertices within the brush radius we can likely get a good normal estimate cheaply. Efficient implementation is a bit tricky and may work poorly in some (hopefully rare) cases, testing would need to reveal that. Dyntopo data structures would need changes to support random access. To me this seems the most promising though I might be a bit biased :).

Probably we'd need one such optimization before the normal preview can be enabled by default.

There's this open source online sculpting app https://stephaneginier.com/sculptgl/ which also has this brush cursor feature. Not sure which method it uses but it feels quite nice. Maybe worth take a look?

@Brecht Van Lommel (brecht) The problem might be that, in some task, you are only concerned about the cursor placement and not the sculpting normal. In fact, previewing the sampled normal could give you misleading information about the volume you are dealing with. For example, when you are using the grab brush to tweak the silhouette of the model you expect the brush preview to turn away from you as you approach the edge, and if we use the real sculpting normal that won't happen in some cases. I think we should give the option to the users to preview a "wrong" normal that follows the surface as long as they know what they are doing.

We should also think of making the cursor behavior consistent and give enough options if we want to support other modes in the future. Relying only on a sampled normal for a hypothetical normal projection mode in texture paint won't work, and maybe riggers prefer the face normal when painting weights on low poly models.

I would suggest the following:

  • Add a user preference to this patch to switch between the old cursor, the face normal mode and the sampled normal mode.
  • Make another patch adding normal radius and weighted falloff to calc_area_normal_and_center_task_cb, so it can be used with the cursor and the brushes. In fact, adding support for different falloffs there could be super useful for tweaking the brush behavior.
  • Add an option to the cursor to let the user fix the normal sampling radius to control how closely the cursor will follow the surface depending on the task.

Regarding optimizations, I think that the best idea may be using the normal buffer. It is the only method that can smooth the brush transition over an edge, and I would say that it will give us the behavior that most users are expecting. That was my original plan but I have no idea on how to implement that, I'm not familiar with the rendering code. If we stick to this implementation, I could also take a look at implementing Monte Carlo sampling, I think that could also be useful to make a "smooth strong" brush in the future to erase high-frequency detail faster.

Keep in mind that the vast majority of users will just use the default setting anyway, and while they are sculpting, you don’t want to have to care about setting this feature correctly. The ‘make it an option!’ reflex is a normal urge when something is difficult to solve, but I would suggest to try and find a solution that doesn’t require users to fiddle with this, and add more cruft to the UI.

I did not test the patch.
But cursor should be consistent with sculpt plane. A cursor following normals does not make sense if sculpt plane of brush is View Plane or X, Y, Z plane.
You probably don't expect a cursor following normals when 2D Falloff option is ON.
Texture overlays have to stay consistent, too.

@William Reynish (billreynish) My point is if we enable sampled normal by default, even if it is optimized, or we make the cursor strictly follow the sculpting plane even when it is fixed, most users are going to find that behavior wrong. I can think of two solutions right now:

  • Ignore the fact that the preview normal and the sculpting normal won't match in some cases. Then, we have the option to use face normal if we want it to be fast or sampled normal with a fixed small radius with falloff if we want it to be smoother.
  • Change the normal calculation code to follow the surface more closely. This will also change the behavior of the brushes, but it will match the cursor. Then, we can find a good default value and hide the option, make it configurable or make it an option per brush.

I don't know for sure, but I would probably expect that 'sampled normal with a fixed small radius with falloff if we want it to be smoother' would be just fine in practice, and would solve the high frequency jitteriness, correct?

@William Reynish (billreynish) Yes, but it won't match the sculpting normal if we fix a small radius by default. That is why I wanted to make it configurable, to at least give the user the option to display the sculpting normal without changing the current brushes.

Is the issue that some brushes like grab do not use the normal (unless you enable normal weight)? For such brushes we can show some other normal, but for brushes that do it use it why not show the actual normal?

We should also think of making the cursor behavior consistent and give enough options if we want to support other modes in the future. Relying only on a sampled normal for a hypothetical normal projection mode in texture paint won't work, and maybe riggers prefer the face normal when painting weights on low poly models.

A sampled normal could work for paint too, using faces instead of vertices.

Regarding optimizations, I think that the best idea may be using the normal buffer. It is the only method that can smooth the brush transition over an edge, and I would say that it will give us the behavior that most users are expecting.

Using screen space data would quite different from how sculpting works now. It has different trade-offs, for example at a silhouette the average normal would not be orthogonal but always point towards the viewer as backfaces are not taken into account. Brushes that are partially outside the viewport would need extra care, subpixel detail may not be taken into account, etc.

I'm not sure what exactly is meant by "smooth the brush transition over an edge", it's not clear to me why 3D space averaged normals would not support that.

@Brecht Van Lommel (brecht) I'm starting to think that this is an issue with the normal calculation code itself, and now it becomes more evident because we are able to see it in real time as we move the cursor over the mesh. That is why a lot of users complain about problems while sculpting hard surface or when trying to flatten surfaces while preserving edges.

In this patch ( http://pasteall.org/1473920/diff ) I'm ignoring backfaces and I'm reducing the sampling normal radius by 0.2. Now the cursor behaves as it should, the preview normal is the real sculpting normal, and in my opinion, it is making the brush behavior a lot better. If we are willing to change the brushes, maybe this is the way to go.

In fact, changing the brushes is not even needed. We can add an extra parameter called normal radius to all brushes and set it to a low value by default. To get the old behavior the user will just need to set it back to 1.

Disable the new cursor when a texture or alpha overlay is active, as it is not supported for now to maintain compatibility with other modes.

Add a normal radius parameter to all brushes. Now the cursor behaves as it should and it matches the sculpting normal in all cases, high frequency detail can be ignored and the new parameter makes all brushes more useful in tasks like hard surface sculpting.

Could we also hide the mouse pointer for sculpt mode, and just use a small dot in the center? It seems as if the mouse pointer really gets in the way.

@William Reynish (billreynish) I can add this to the patch (http://pasteall.org/1475896/diff) but I do not know if that is the right way to do it. I read somewhere that it is not that easy.

The mouse pointer is already hidden in Grease Pencil Draw Mode - maybe it could be done the same way?

@William Reynish (billreynish) I think that is the code that changes the cursor in edit mode, I only added a check that hides the mouse cursor if there is a sculpt session active in the active object.

Why not display a crosshair cursor like in most sculpting apps (zbrush etc...)?

Mouse cursor is now hidden when the stroke starts, similar to grease pencil, as @William Reynish (billreynish) requested.
Added a location preview with symmetry during the stroke. It is using the StrokeCache data, so it should not have any performance penalty.

Mouse cursor is now hidden when the stroke starts, similar to grease pencil, as @William Reynish (billreynish) requested.

Sorry if I'm missing something, but in grease pencil when doing a stroke, the cursor (that dot) vanishes completely, You know it doesn't work well for sculpting, right?
So what will be displaying in place of the old mouse cursor?

Re the cursor, here's a few options:

I think there needs to be *something* visible at all times, just not a pointer arrow. IMO we could display a small dot or a small cross hair, like so:

If we did this, I think it should should just always display like this, while in Sculpt Mode. Many painting and sculpting apps do something similar, and show something other than the regular arrow pointer.

@Pablo Dobarro (pablodp606) Ah, okay, Mudbox style (dot). It's not too bad, even though I still prefer the type of cursor from c4d/zbrush and others...

@William Reynish (billreynish) I like Alt 2, but each one of them have a different "feel" while sculpting.
Maybe it's asking too much, but can we have an option to choose among those 3 cursor types? 🙂

The default value (0.2?) of Normal Radius doesn't seem to be reflected in Active Tool settings. When the Normal Radius is 0.0, I can't sculpt at all. Because sculpt_brush_test_sphere_sq returns 0 ?

@Jun Mizutani (jmztn) If you set the normal radius to 0 the brush should not produce any deformation along the normal, that's expected (it is like setting the strength to 0). Currently, you need to change this value for every brush, and this needs to be fixed for the final version. I don't know why the default value is not taken into account, maybe we need to update the startup.blend file with new brushes that have this value set by default?

Would be possible to hide the cursor when pressure sensitive for size "radius" is enabled, like the strength Pressure sensitive? A little dot or a cross like zbrush or mudbox, I think it would be better and less distracting. Thank you Pablo, you are doing a great job.

@Pablo Dobarro (pablodp606) This looks great already, especially with the symmetry preview. This is a huge step forward for the Sculpt mode.

However, why is the arrow cursor showing at first, but then disappears?

@William Reynish (billreynish) It disappears when you click on the viewport, like grease pencil draw mode. Is this a bug?

For Grease Pencil, they have it so the arrow pointer disappears while you click to draw. The problem with that, is that then you see *nothing* which makes it hard to draw using a mouse

In all the paint and sculpt modes, I think we should just show a circle + dot, and hide the mouse arrow always. Most painting and sculpting apps do this. No need for an arrow cursor at all.

@Brecht Van Lommel (brecht) @William Reynish (billreynish) If we are going to hide the mouse cursor in all paint modes, is it ok to change it in view3d_main_region_cursor like this? http://pasteall.org/1475896/diff

I'm not sure - it requires testing. We must make sure there's always *some* cursor showing. If we just hide the arrow cursor without making sure something else is visible, that's obviously not going to work.

Hide the mouse cursor by default, show it when "show brush" is disabled.

Clever - that seems like the correct solution.

Pablo Dobarro (pablodp606) edited the summary of this revision. (Show Details)

Fix cursor preview size on translated objects

Seems like most issues are solved now, looking great!

Any other code tweaks you'd like to do or is up to the developers to give another review pass on this?


Thanks for keeping the patch updated and taking feedback so well btw, the review process can be tough and can get new devs easily discouraged. You rock @Pablo Dobarro (pablodp606)! 🤘

Can someone share a build or did you guys check this in dyntopo?

@Pablo Vazquez (pablovazquez) The brush presets need to be updated to include the normal radius default value. Also, the grab brush preview on low poly meshes is a little bit weird, but it can not be done properly without an unnecessary hack.
Regarding optimizations, maybe adding Monte Carlo sampling only for the cursor is not worth it. If a computer can not run the cursor in real time it will not be able to sculpt. Furthermore, the cursor is disabled when a stroke is active, so sculpting performance should not be affected.
I think the rest of the functionality should be fine right now.

@Pablo Dobarro (pablodp606) Given the enormous value of what you are doing here, I just want to make sure this is followed up on. Do you have all you need to proceed, or do you need developers to review?

@William Reynish (billreynish) I would like to have a code review, I can always make small changes to the functionality in the future if that is needed.

Since there are still so many todo's and unfinished features for 2.8x, would hold off on this feature until after 2.80 initial release.

Since there are still so many todo's and unfinished features for 2.8x, would hold off on this feature until after 2.80 initial release.

That is, this function will not be in the initial version 2.8?

hold off on this feature until after 2.80 initial release.

Now that's what I call bad news.
It's sad, this is such an amazing improvement.

Since there are still so many todo's and unfinished features for 2.8x, would hold off on this feature until after 2.80 initial release.

I was reading this thread for a while and finally decided to register after your comment.

I'm strongly disagree with this notion and eagerly asking you to reevaluate it.

I do understand that there are many todo's and unfinished features that are waiting for their time but the difference is -- unlike todo's this feature is already implemented and sooner users start to use it sooner there will be more development in this department that was, almost literally abandoned for three years. Postponing it for another half to year(let's be realistic here: there are always more urgent things to do and the initial release itself most probably is more than three months away from now) is basically means killing it and making obsolete by the time you got your time to look at it closer(due to fatigue of the developer and neck breaking speed of development right now among other things).

Right now it's an amazing feature that make something really useful and greatly improves productivity unlike some other features that are already implemented(I totally respect and like features like shadows in workbench for example but it's usefulness kinda lacking comparing to this patch and lacking greatly). And the sooner it will be available for more users so they can give feedback and evaluate it the better.

If Pablo made the promise to fix any issues his sculpting patches bring up (as opposed to leaving it to the core team), then I don't see why it shouldn't be committed, especially as there's nothing in dev. discussion mentioning a feature freeze.

My opinion anyway.

If Pablo made the promise to fix any issues his sculpting patches bring up (as opposed to leaving it to the core team), then I don't see why it shouldn't be committed, especially as there's nothing in dev. discussion mentioning a feature freeze.

My opinion anyway.

Because it is not well tested yet, look at Pablo's video most of them are without Dyntopo, i don't know about multires. I stand by the core devs. there is no need to rush feature. @Pablo Dobarro (pablodp606) Please provide a build so people can test and give feedback.

In D3594#101059, @Erick Tukuniata (erickblender) wrote: Please provide a build so people can test and give feedback.

He already did. It's on his Twitter page.

Jun Mizutani (jmztn) added a comment.EditedThu, Mar 7, 2:55 PM

This patch will make Sculpt Mode menu "Brush/Reset Brush" work as expected.

diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 346066b961a..859a2661349 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -71,6 +71,7 @@ static void brush_defaults(Brush *brush)
        brush->size = 35; /* radius of the brush in pixels */
        brush->alpha = 0.5f; /* brush strength/intensity probably variable should be renamed? */
        brush->autosmooth_factor = 0.0f;
+       brush->normal_radius_factor = 0.2f;
        brush->topology_rake_factor = 0.0f;
        brush->crease_pinch_factor = 0.5f;
        brush->sculpt_plane = SCULPT_DISP_DIR_AREA;
Jun Mizutani (jmztn) added a comment.EditedSat, Mar 9, 8:55 AM
In D3594#97225, @Pablo Dobarro (pablodp606) wrote: Currently, you need to change this value for every brush, and this needs to be fixed for the final version. I don't know why the default value is not taken into account, maybe we need to update the startup.blend file with new brushes that have this value set by default?

This patch will update factory settings for normal_radius_factor. This patch was made against v2.80.47.

Affected by changes in struct Main(commit 8f817de0cbef41dac81e6c7665ada509c3fe2988), the element "brush.first" needed to be changed to "brushes.first".

@Jun Mizutani (jmztn) Thanks! I added it to the sculpt-mode-features branch

Great job overall. Thanks Pablo.
Ive tested your improvements and ive found that you have changed behavior of cursor ring.
Right now when im making stroke, the outer ring that shows size of brush dissapears. I think that this is not a good idea. I understand that you try to mimic zbrush but from user perspective its always nice to know how big brush is and how big can become with max pressure. Right now im unable to judge this. So im asking for a little revert to 2.79 behavior with new surface normal behavior (its basicly, same as 3dCoat) or a little checkbox would do the job just fine.
Another thing is that if you enable tablet pressure sensitivity button (next to radius bar), while stroking outer ring is visible (thats good) but does not follow surface normals.

Best regards.