Flat shading in sculpt mode

Spent a little time today looking at improving one small aspect of sculpt drawing: flat-shaded faces in solid view mode with VBO enabled.

In current trunk, flat shading in sculpt mode looks quite different depending on whether VBO is enabled or not. When VBO is not enabled, and immediate mode is used to draw the mesh, each face (triangle or quad) gets drawn separately. Before drawing the face, a single averaged normal and mask value is calculated. The normal and mask values are used for each vertex of the face. In contrast, VBO drawing uses a shared vertex normal and mask value for every face that uses the vertex. This behavior is correct for smooth shading, but looks strange for flat shading.

The benefit to using a shared vertex value is lower storage requirements; the mesh’s faces can simply reference vertices with an index (and the index can usually be a short, so two bytes per index.) When flat shading is enabled, however, OpenGL uses only a single vertex’s value for the entire face. On any particular face this generally looks OK, but the problem is evident when adjacent quads appear to have the same normal despite facing different directions.

Flat shading in sculpt mode
Click to embiggen
Left: current trunk. Middle: averaged normals and interpolated mask. Right: averaged normals and averaged mask.

I’ve implemented a simple fix for this, available from the sculpt-flat-shading branch on Github. If the mesh is flat shaded, the index buffer is scrapped in favor of duplicating vertex values. The GPU storage requirements are in general slightly higher, but the output looks much more correct.

In the image above you can see two variations of the fix. Both have flat-shaded normals, but the middle uses interpolated mask values while the right uses a single average mask value. Using an averaged mask value seems to look a bit better, although it’s technically a bit inaccurate as sculpt brushes operate on vertex mask values, not the average.

One further issue which affects smooth shading is that interpolation over quads doesn’t look very good with OpenGL. Mask values and normals don’t look smooth because OpenGL tessellates quads into two triangles. The vertex values are interpolated within each triangle, without regard to the missing corner. It’s technically possible to solve this with shaders. Instead of using regular vertex attributes, the vertices just get texture coordinates and the attributes are put into a texture. A bilinear (or even bicubic) interpolation can then be coded in the shader. Such fanciness is probably of questionable usefulness though, and at the very least will have to wait on the completion of other improvements to the various drawing systems in Blender.

My current plan is to wait until 2.64 is released, then commit the flat-shading fix (with averaged mask values.)

Sculpt masking merged to trunk

At long last, sculpt masking is in trunk!

Big thanks to everyone who helped out with uploading test builds and providing feedback on features and bugs. Thanks in particular to Brecht for doing code review, and to the Blender Development Fund for sponsoring the work.

Documentation is on the wiki. We’re getting pretty close now to feature-parity with SharpConstruct ;)

Edit: With masking safely in trunk, I’ve removed the masking branch from github and merged the updates to the skin-modifier branch. If you have previously saved files using the skin-modifier branch, the skin data (i.e. vertex size and root markings) will be lost. This is due to the skin data and paint mask data sharing a CustomData layer identifier until now.

Southern Coding

Have been a bit silent here the past week; I just moved back to South Carolina with all the business that entails.

Work continues on the skin modifier though. If you try out the latest updates in the github branch, you should find that it’s a bit closer to the goal of always generating a manifold mesh. It also has a new smoothing option for smoothing the vertices around branch nodes. This needs further thought still; I’d prefer to just get the output looking nicer in the first place.

Some news regarding sculpt masking from the Sunday #blendercoders meeting, Brecht says he plans to review the patch next week (unless someone else can volunteer to do it.)

Also spent some time today playing with the code style checking script (“make test_style”, or “source/tools/check_style_c.py <paths>”.) Fixed up some of the sculpt/paint code in trunk, as well as updates to the masking and skin modifier code. Will try not to waste too much time on pedantic code formatting though :)

A day for patches

Spent most of today working on updates to the convex hull operator. As mentioned yesterday I submitted it for patch review; Campbell got on that right quick with helpful feedback. Finally got that work finished a half hour ago: lots of bug fixes and new options to control the output. Branch and code review updated if you’re curious.

In related news, reviewed a patch from Jason Wilkins that adds a handy feature for sculpt: pressing numpad period while in sculpt mode will center the view on the last sculpted area. Blender 2.4x had such a feature, but got lost somewhere along the way. You can expect that feature in trunk soon.

And lastly, the sculpt masking patch is now uploaded to code review.


Sculpt masking, last looks

The sculpt masking code is now finished-ish. I’ve just completed my own review of the code, checking each commit and fixing various bugs.

I’ll be submitting it for code review soon (no rush since it won’t be going into trunk until the start of the 2.64 release cycle), but before I do there’s time for more user testing. No doubt there are still bugs there just waiting for you to find them! Check also the masking documentation on the wiki in case there is anything missing there.

The code is as always available from the masking branch of my github repository. Post builds on GraphicAll if you got ’em.

Builds update:

Continue reading Sculpt masking, last looks

Quick masking update

Here’s an updated masking patch that should apply cleanly against current trunk: masking-03.diff

Note that in this update, material colors aren’t working correctly. I’m pondering how best to address this and other drawing problems now.

Past couple days I’ve been committing some code cleanups to the non-sculpt drawing code. It’s still a lot of code to wade through, but it’s at least a little less verbose now.