Currently, atomic additions in vertex normal calculation introduce
non-determinism that can influence the result of other operations,
sometimes causing non-reproduceable renders (in cases like #100250).
This is because the order used during threading when accumulating face
normals changes.
This commit fixes that non-determinism, using a vertex to face topology
map to calculate vertex normals normals without atomics. When the map is
already available, this can be faster too.
Internally, a new "fast" code path is available too. This avoids
weighting face normals by the corresponding corner angle when averaging
them to create face normals. This significantly reduces the necessary
computation and memory bandwidth for vertex normal calculation.
The "fast" option is included in this PR as a way to potentially reduce
the peformance impact of requiring the topology map.
TODO:
- [ ] Run performance tests in differenct smooth shading use cases
- [ ] Large mesh build from scratch every frame
- [ ] Armature deformation of large mesh without subdivision
- [ ] Test "fast" option and expose toggle in UI if it's worth it
In the longer term future, this method of vertex normal calculation
means it will be easier to do partial recalculations when only part
of a mesh changes. That might be essential for cases like transforming
small selections in a non-BMesh edit mode.