Dynamic Paint is a new tool that allows a whole new way for Blender objects to interact. Basically you can make any object or particle system to become a 3D-brush that can paint on other objects. Dynamic paint will be a great help in making realistic animations where objects have to interact with each other or with the environment.
You can for example make fluid simulation that saturates walls where fluid touches them, a character that wipes dust off a window or falls into ground and gets all smudgy, or simply a paint brush painting a house. Possibilities are endless. :)
Goal of this project is to greatly improve the user experience and functionality of Dynamic Paint from it's current state and eventually prepare it to become part of Blender. Dynamic Paint system can also be used as a platform for upcoming development of 2D surface effects and simulations.
Google Summer of Code 2011 Goals
Work will consist on adding following functionality and improvements:
- Ptex support
- Vertex level painting of colors, displacement and vertex weights.
- Point Cache implementation for Ptex and Vertex baking.
- Viewport preview for canvas vertex and Ptex types.
- Redesigning the user interface to allow easy and clear handling of multiple canvas types and output formats.
- Adding new functionality and surface types.
- Improving and finishing existing parts.
- Dynamic Paint related posts on my blog
- GSoC specific posts on my blog
- My YouTube channel
- Windows 32/64-bit Carrot branch builds
- GraphicAll.org builds
- Basic introduction to the user interface
- A step-by-step basics tutorial
- A complete guide to all settings (currently not up-to-date)
User Interface Improvements
Main reason for user-interface redesign was to allow adding new canvas formats (vertex and ptex) and new types (vertex weight, iWave) without flooding every single setting in the same panel. (like it was in old Dynamic Paint UI)
I implemented a basic version of new UI during the first week of GSoC. It still needs some cleaning and organizing, but I'll leave that for later this summer.
In new Dynamic Paint system, each canvas is now a collection of "Surfaces". These surfaces are sort of layers of paint, that work independently from each other. You can define individual settings for them, bake them separately and select what surfaces are active or previewed in 3D views.
Each surface has a certain format and type. Format determines how data is stored and outputted. Eventually there will be at least 3 formats:
- Image Sequences. The old Dynamic Paint type. You can bake results as UV wrapped image files.
- Vertex. A new format that operates on mesh vertex level. Results are stored by point cache and can be displayed in viewports.
- Ptex. A new format that operates on sub-face level. Results are also stored by point cache.
Each surface also has a "type" that defines what surface is used for. For GSoC period following types are to be implemented:
- Paint. Basic color surface that outputs color and wetness values.
- Displace. This type of surface outputs intersection data from brush objects.
- Weight. This type of surface outputs vertex weight groups that can be used by other Blender modifiers and tools. (Only available for vertex format)
- Waves. A new simulation type that produces simulated wave motion.
For brushes, I added a new icon-only menu that can be used to toggle what kind of settings are displayed. This way it is safe to add new and different Dynamic Paint modes yet keep UI clear and organized.
I also added new icons to clarify purpose of some settings.
Real-time preview in 3D view
New point cache based data formats make it possible to show results directly in Blender's 3D viewports. I added previews for vertex format surfaces during second and third week of GSoC. Displace preview is simply output from Dynamic Paint's modifier, other surface types are previewed using vertex colors.
In this video you see real-time preview of a displace type Dynamic Paint surface being painted by a particle system brush.
Vertex Level Painting
Vertex painting is a new Dynamic Paint surface format that operates on mesh vertex level. This is very useful especially for displacement, because there is no need for any further detail beyond vertices.
For vertex surfaces it's also possible to paint vertex group weights. This way brush objects can also interact with other Blender tools and modifiers through Dynamic Paint.
Point Cache Support
One of the tasks for first GSoC weeks was point cache integration. Upcoming vertex and Ptex surfaces have to save and read data each frame somehow and Blender's point cache system is a perfect way to do this.
"Paint Effects" System
During the fifth GSoC week I recoded Dynamic Paint's "effects" system, that is used to generate animated movement on wet paint. Old implementation was purely designed for image sequence output, so all data structures and methods needed at least some level of redesign to make it work with vertex surfaces.
Basically, the old system worked entirely in UV space. To work with new vertex surfaces, it had to be converted to 3D space where each point can have any number of neighbor points.
In the new version I also improved color mixing algorithm and extended "drip" effect to not only work in gravity direction, but to allow using Blender's force fields to affect dripping.
Later I also added ability to influence dripping by surface velocity and acceleration.
One special thing I was experimenting before GSoC was adding a simple 2D wave simulator for Dynamic Paint. Back then I was experimenting with iWave algorithm by Jerry Tessendorf. However, it had some issues and eventually I ended up implementing another algorithm instead. This time based on "Height Field Fluids" slides by Matthias Müller-Fischer. This was integrated during sixth coding week.
One could argue if a wave simulator should be it's own tool/modifier instead. However, over 90% of the code required (collision checks, adjacency searches, modifier itself, baking, multiple output formats, point cache etc.) was already part of Dynamic Paint, so implementing it as a separate tool would have required lots of extra work and and wouldn't still have been any better.
Here is a screencast of several wave surface test scenes:
During weeks 8-9 I focused on optimizing Dynamic Paint speed when using high resolution surfaces or lots of substeps.
There was three kind of optimization done:
1. Additional Collision Checking
- Previously Dynamic Paint used BVH trees to optimize ray checks used to determine whether brush touches certain surface point. Now additional checks were added to possibly avoid any raycasting in certain situations.
- Surface points are now divided into a 3D grid, each cell having 10.000 points by average. Before any rays are cast, a brush object bounding box is compared to surface bounding box and then to each grid cell to determine if it's even possible to have influence.
- This gives a nice speedup in situations where brush is far away from surface.
2. Only recalculate data if needed
- Now canvas stores it's location from previous frame to monitor whether there has been movement or not. This way surface data (global point coordinates and normals, surface grid, etc.) don't have to be recalculated each frame if surface remains still, which is often the case for Dynamic Paint.
3. General optimization on brush algorithms
- Heavy optimization was done specifically on particle brush code, when using random sized particles. In that case it's not possible to just check closest particle but all particles within randomized range have to be considered. A several new checks were added to effectively compare influence of closest particle to determine if it's even possible to have particles further away that have higher influence.
As a result, a very nice speedup was achieved when using high resolution surfaces. Here are some benchmark results:
Test 1, 2048x2048 image sequence surface, 5 substeps, 50 frames:
- Previous version: 3 min 52 s.
- New version + moving canvas: 47 s.
- New version + static canvas: 20 s.
Test 2, 1024x1024 image surface, 20.000 particles, high random radius:
- Previous version: 1 min 10 s.
- New version + moving canvas: 12s.
- New version + static canvas: 11s.
Velocity Based Brushes
Since 10th GSoC week, it's been possible to use brush or surface velocity to influence paint.
For example, you can set brush to paint only if it's relative velocity to canvas surface is high enough, or make it's color be defined the velocity (color ramp).
One of the coolest velocity based features is smudge. When this brush setting is enabled, it smears existing paint as it moves.
Here is an example of basic smudge:
And a particle system brush:
There was also lots of smaller improvements and bug fixes done. To check more details about those see the commit logs below.
- Ptex surface format
- Basic support when Ptex code becomes available
- 3D view previews
- Possibly work on Ptex rendering support
- Improving overall functionality
Revision: 36854 - 24/05/2011
Applied Dynamic Paint 1.18f patch as a codebase for GSoC.
Revision: 37548 - 16/06/2011
Committed changes from previous weeks, biggest changes are:
- Canvas can now have multiple "surfaces" that each can have specific format, type and settings.
- Renewed UI to support this new system.
- Aside from old "image sequence" output format, Dynamic Paint can now work on vertex level as well. Currently vertex paint and displace are supported.
- Integrated vertex level painting with Point Cache.
- Added viewport preview for Point Cache surfaces.
Due to massive amount of changes, old Dynamic Paint saves are no longer supported. Also some features are temporarily missing or may not work properly.
Revision: 37549 - 16/06/2011
Merge with trunk r37546
Revision: 37564 - 16/06/2011
- Fixed cmake compile.
- Fixed segmentation fault when closing Blender, caused by rna changes from earlier svn trunk merge.
Revision: 37602 - 17/06/2011
- Image sequence anti-aliasing works again.
- Vertex color viewport preview now works with GLSL and textured view modes too.
- Added a new "inverse" setting for "volume + proximity" brush. With it brush only has effect within volume but effect is lower near the mesh surface.
Revision: 37622 - 18/06/2011
- Added vertex weight painting.
- Added dissolve/fade setting for every surface type.
- Restored image format and displace type selection for image sequences.
- Fixed a possible crash when OpenMP enabled.
- Attempt to fix surface rna paths.
- Fixed compile warnings.
Revision: 37848 - 27/06/2011
- Fixed memory leak when baking image sequences.
- Fixed sub-steps when brush was controlled by a parent object.
- Added option to select active outputs for paint surfaces.
- Improved color mixing algorithm.
- Improved memory allocation behavior.
- Memory is now freed even in case of errors.
- Removed "initial color" setting, as it's better to adjust color from material.
- "Paint effects" system:
- Converted to use new data structures.
- Works now with any number of surrounding points.
- Re-implemented support for UV-image surfaces.
- Added support for vertex surfaces too.
- Improved color handling.
- Improved movement stability.
- "Drip" effect uses now Blender's force fields instead of just z-directional gravity like before. Now each surface point can have different force influence.
Revision: 37853 - 27/06/2011
Merge with trunk r37849
Revision: 38043 - 02/07/2011
- Added a new surface type "Waves" that simulates simple 2D wave motion.
- Optimized adjacency point searching for vertex surfaces.
- Separated adjacency code from effect system.
- Overall code cleaning and tweaking.
Revision: 38044 - 02/07/2011
Merge with trunk r38042
Revision: 38064 - 02/07/2011
- Some ui and rna tweaking.
- Effects ui panel is no longer visible for non-paint surfaces.
Revision: 38226 - 08/07/2011
- Canvas and brush can be now enabled simultaneously. This way it's possible for two canvases to interact.
- Added basic anti-aliasing support for vertex surfaces.
- 3D-view color preview now works even when there's subsurf modifier after Dynamic Paint in modifier stack.
- Added a new brush option to use proximity from object center.
- Default surface frame range now use scene's start and end values.
- Improved ray checks for volume brushes.
- Added new "non-closed" option for volume brushes. This way it's possible to use planar meshes as "volume" brushes with predefined ray direction.
- New carrot branch splash image by CGEffex.
- Improved brush affection code.
- Lots of smaller improvements.
- Fixed: Weight paint didn't work with particles.
- Fixed: Point cache didn't work for non-wave surfaces anymore.
Revision: 38227 - 08/07/2011
Merge with trunk r38225
Revision: 38231 - 08/07/2011
- Changed loop index back to signed, since OpenMP 2.x doesn't allow unsigned indexes.
Revision: 38282 - 10/07/2011
- Proximity brush color ramp should now work properly with any type of proximity brush.
- Dynamic Paint operators (adding surfaces, baking, etc.) now affect right object even when ui is pinned to a non-selected object.
- Fixed proximity falloff for vertex weight surfaces.
- Fixed possible color issue with low alpha brushes.
- Fixed a compiler warning.
Revision: 38283 - 10/07/2011
Merge with trunk r38281
Revision: 38620 - 22/07/2011
- Surface bake data is no longer recalculated every frame, but only when surface mesh has moved/transformed. Results in multiple times better performance on high resolution surfaces when using sub-steps or surface is still.
- Heavily optimized particle brushes when random particle size enabled. Up to 10x speedup with large radius particles.
- Added an additional "grid" space partitioning structure for surfaces.
- Added bounding box checks for brushes.
- Smaller overall optimization.
- Further OpenMP parallelization.
- Added physics tab link to modifier panel.
- Fix: "Point Density" texture cache wasn't properly updated. Brushes can now use Point Density textures as well.
- Fix: Paint dissolve resulted in black color.
- Fix: KD-tree checkups weren't completely thread safe. Fixes possible crash with OpenMP enabled particle brushes.
- Fix: When brush was set to use a specific material, it was saved incorrectly and resulted in potential crashes on next load.
Revision: 38623 - 22/07/2011
Merge with trunk r38281
Revision: 38661 - 24/07/2011
- Added alpha support for vertex color rendering. You can now easily render Dynamic Paint produced vertex colors by checking "Vertex Color" in material options.
- Added "Vertex Alpha" socket for "Geometry" material node.
- Fixed vertex surface color output issues.
Revision: 38662 - 24/07/2011 '
- Forgot to change node socket ids.
- Fixed "shrink" effect artifacts on wetmap.
Revision: 38664 - 24/07/2011
Merge with trunk r38663
Revision: 39001 - 03/08/2011
- Object velocity can now be used to determine brush influence and color.
- Brushes can now be set to "smudge" existing paint.
- Added new operators to easily add and remove surface output mesh data layers from Dynamic Paint ui.
- Fixed drip effect algorithm to work properly on forces pointing towards surface.
- Adjusted drip effect speed.
- Drip effect can now use canvas velocity and acceleration to influence drip direction.
- Fixed texture mapping for material enabled brushes.
- "Object Center" type brushes can now use "material color" as well.
- Improved surface partitioning grid generation algorithm.
- Fixed possible invalid brush collision detection when OpenMP enabled.
- Fixed incorrect random sized particle displace/wave influence.
- Fixed "Object Center" brush color ramp falloff.
- Fixed invalid zero alpha sampling when rendering vertex colors.
- Lots of smaller tweaking.
Revision: 39002 - 03/08/2011
Merge with trunk r39000
Revision: 39009 - 04/08/2011
- Smudge now works properly with substeps.
- Velocity brush speed clamping now works for all brush types.
- Small tweaking on velocity brush ui.
Revision: 39063 - 05/08/2011
- Added a new "color spread" slider for "spread" effect to adjust how much colors get mixed.
- Improved smudge behavior on "wet" paint.
- Displace can now be set "incremental". This way it's added on top of previous displace.
- Added "displace clamp" setting. You can use it to limit maximum amount of displace.
- Fix: velocity data wasn't always initialized, this could lead to no effect at all or crash.
- Fix: Vertex color rendering near zero alpha values was still incorrect.
Revision: 39064 - 05/08/2011
Merge with trunk r39062
Revision: 39099 - 06/08/2011
- Fix: Wave surface normals weren't calculated anymore since yesterday's commits.
Revision: 39590 - 21/08/2011
- Bake calculation memory is now freed if surface is deactivated or baked.
- Fixed possibly incorrect brush influence when using "Non-Closed" brush setting.
- Added new rna property descriptions.
- Added some comments and general code cleanup.
Revision: 39592 - 21/08/2011
Merge with trunk r39589