Fix seam bleeding of non-manifold sections of the mesh, by copy-ing pixels that are covered by the brush stroke.
As manifold parts are already handled, the pixel copy-ing solution can be very straight forward.
- Pixels are copied from the same tile. So we don't need a mechanism that copies and merges pixels from other tiles.
- Pixels are copied from the closest pixel that is being painted on. We don't need to consider that that pixel can be in different areas of the tile.
When we copy a pixel, we find the closest pixel in UV space that is being directly influenced by a paint brush. We also look for the second closest pixel, which is still a neighbor from the closest pixel. We can mix both pixels together and store it in the destination. A mix factor is calculated using the closest non manifold edge as a guidance.
The result of this step is a list of copy and mix commands that can be executed to fix the seam bleeding for non-manifold sections of the mesh.
| Destination | Source 1 | Source 2 | Mix factor |
|---|---|---|---|
| 1780,1811 | 1780,1810 | 1779,1810 | 0.000000 |
| 1781,1811 | 1781,1810 | 1782,1811 | 0.168627 |
| 1828,1811 | 1828,1810 | 1827,1811 | 0.156863 |
| 1829,1811 | 1829,1810 | 1828,1810 | 0.188235 |
| 1830,1811 | 1830,1810 | 1829,1810 | 0.188235 |
| 1831,1811 | 1831,1810 | 1830,1810 | 0.188235 |
| 1832,1811 | 1832,1810 | 1831,1810 | 0.188235 |
| 1833,1811 | 1832,1810 | 1832,1810 | 0.000000 |
In the end we go over this list mix the sources and store the result at the destination.
tile_buffer[destination] = mix(tile_buffer[source_1], tile_buffer[source_2], mix_factor);
Encoding
When using a large textures or large seam margins this table can grow large and reduce performance as data retrieval is slower, than the operations it has to perform. To improve the performance we encode the
table so less data retrieval needs to be done.
- first DeltaCopyPixelCommand is delta encoded from CopyPixelGroup#start_destination and start_source_1. The others are delta encoded from the previous DeltaCopyPixelCommand.
- For performance reasons PixelCopyGroup#pixels are ordered from destination (left to right)
- for each row a new group would be created as the delta encoding most likely doesn't fit.
- When pixels cannot be delta encoded a new group will also be created.
Compression rate
When using Suzanne the compression rate is around 36% when using a seam margin of 4 pixels. The compression rate may vary depending on seam margin and model. For Suzanne the compression rate was around 365 for various resolutions.
| Texture resolution | Seam margin | Decoded size (bytes) | Encoded size (bytes) | Compression rate |
|---|---|---|---|---|
| 2048x2048 | 4 px | 353.052 | 128.101 | 36% |
| 4096x4096 | 4 px | 700.140 | 255.137 | 36% |
| 8192x8192 | 4 px | 1.419.320 | 513.802 | 36% |
| 2048x2048 | 8 px | 721.084 | 193.629 | 26% |
| 4096x4096 | 8 px | 1.444.968 | 388.110 | 26% |
TODO
- UDIM tiles aren't supported yet. This needs to be added before this patch lands.
- Threading isn't added, but should before this patch lands.
- TODO's have to be resolved including some performance improvements by reducing the search radius.





