Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Paint In 3D ️️✏️ In Game & In Editor & Skinned Mesh Painting

Discussion in 'Assets and Asset Store' started by Darkcoder, Jul 10, 2018.

  1. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    This is very similar to my test code, though I do it recursively. While there is a way to greatly optimize CPU floodfill using a kind of RLE approach, the biggest issue will be copying the texture to the CPU, which is always slow. This can be done in async on most platforms to avoid stalls, but then the read would take several frames to run and the current painting system (especially preview painting) isn't designed for this. Doing this on the GPU would be ideal, but the biggest problem with using a blit based floodfill is that there's no way to know how many blits must be done as it cannot be done in one pass. It could be done with compute shaders, but their support is mediocre.

    I think I will just use the async approach and ignore issues that arise from painting between the floodfill request and the result. Perhaps in the future I could change the paint command system so you can have 'long' commands, that cause the next ones to queue up until the previous ones have completed.
     
  2. foxroxracer

    foxroxracer

    Joined:
    Feb 5, 2016
    Posts:
    3
    Hello Carlos,

    I'm interested in your asset because I need a good painting system in Unity, and from what I can see and read, it really is the best on the Unity asset store, thanks for that :)

    I do have two question regarding the uv seams:
    1) Would your tool be able to paint without having texture bleeding with the following unwrap?
    This is an example of an object I would like to paint:
    Blender_UV_Unwrap.PNG
    Or does the unwrapping have to be better in order for it to work good?

    2) When converting a normal mesh with UV seams to a fixed mesh without UV seams, does it stretch or deform the original texture of the model?


    Thank you!

    Kind Regards,
    FRR
     
  3. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    1 - Your UV islands are touching each other, so it's impossible to paint this without texture bleeding. If you add a few pixels gap between them then it will work though. If this is difficult to do or you have many meshes then you can always use Unity's automatic lightmap UV generation for painting, at least as a placeholder until you eventually improve the base UV.

    2 - No, it keeps the original UV data in tact, and just adds some extra triangles around your UV islands. These extra triangles are only used for fixing the seams, and don't alter the look of your mesh in any way.
     
    foxroxracer likes this.
  4. foxroxracer

    foxroxracer

    Joined:
    Feb 5, 2016
    Posts:
    3
    Great, I can easily change the island margins to give a gap between the islands :)
    And thanks for your very quick reply, I'll be buying this asset in the next few days :)

    Thank you!
    Kind regards,
    FRR
     
    Darkcoder likes this.
  5. foxroxracer

    foxroxracer

    Joined:
    Feb 5, 2016
    Posts:
    3
    Runs like a champ, very good asset!!! Thanks Carlos!
     
    Darkcoder likes this.
  6. syedmunimraza

    syedmunimraza

    Joined:
    Sep 16, 2019
    Posts:
    3
    I just imported the latest version of Paint in 3D with Unity 2019.4 (LTS).
    I have upgraded the shaders from unity and from the button which says to switch to the scriptable pipeline as I am working in URP.
    For the first time after importing I press play it works and your demo scene 46 works. After then it doesn't work no matter how many time I try again. Paint percentage starts increasing but there is no visible paint showing that its getting painted.

    Update: Findings --> Paint doesn't show when you have 2 materials(P3D Solid SRP shader in index 1 and URP lit shader in index 0). It works with only 1 material with P3D Solid SRP shader.
    Your help would be highly appreciated.
     
    Last edited: Jul 8, 2020
  7. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Thanks for pointing this out. I used the wrong shader on this Overlay material, instead of using the P3D Solid (P3d Solid SRP) shader, it should be using P3D Overlay (P3D Overlay SRP). If I make this change then it renders as expected in SRP. I'll fix this in the next version coming out soon!
     
  8. syedmunimraza

    syedmunimraza

    Joined:
    Sep 16, 2019
    Posts:
    3
    Thanks for the prompt response. Yes, it worked!
    I upgraded the URP to the latest (version 7.4.1) and switched the material to Overlay and pressed the button of switch to SRP again and it worked. Thanks a lot.
     
    Last edited: Jul 9, 2020
  9. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Great! Keep in mind the "Paint in 3D/P3D ___" shaders are for the standard pipeliene. The URP/HDRP ones are "Shader Graph/P3d ___ SRP".
     
    syedmunimraza likes this.
  10. Edeff

    Edeff

    Joined:
    Dec 9, 2019
    Posts:
    11
    I'd like to use this asset to draw temporary brush strokes on skinned meshes where each stroke will individually fade away over time, is that possible?
     
  11. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Yes, this is shown in the "Texture Fading" and "Shield Impacts" demo scenes. Although these examples work on static meshes, it will also work on skinned meshes provided they have colliders. The detail these colliders should be depends on how accurate & small your paint/decals are. If you just want to fade out bullet wounds in a healing zombie or something then not much accuracy is needed and you can just use one big BoxCollider (as seen in the Zombie Blood) demo scene.
     
  12. Realgar

    Realgar

    Joined:
    Sep 30, 2012
    Posts:
    52
    Hi Carlos, do you know how I could use your preview system to add just another PNG 2d sprite to make a precise curseur (like in Photoshop; a thin circlewith the radius of the choosen brush for exemple) ?
    It would be better than just move a UI circle in the center of the mouse, it would be the exact shape on the object...
    Yhank's a lot if you have the solution or an idea !
    Olivier
     
  13. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Hey everyone,

    Version 1.9.0 of Paint in 3D is now out!
    • Moved main build to Unity 2018.4.13f1.
    • Added support for the new input system (see documentation).
    • Fixed Auto Save Load demo scene.
    • Fixed Bullet Dents demo scene.
    • Fixed Overlay material to use the P3D Overlay shader.
    • Fixed P3dHitCache bug with triangles, quads, and coords.
    Enjoy :)


    The easiest way to do this is to add an extra setting to P3dHitScreen to disable 'real' painting. This can be done by changing the 'preview' argument from the P3dHitScreen.PaintAt method line to always be false, then you can have a preview paint setup, and a real paint setup that work separately. I'll see if I can make this setting built into P3dHitScreen.
     
  14. Realgar

    Realgar

    Joined:
    Sep 30, 2012
    Posts:
    52
    Thank's for you answer, it would be great if you could add this fonction !
     
  15. virendravishth

    virendravishth

    Joined:
    Sep 12, 2016
    Posts:
    7
    Can I simulate the spray painting (as in VR HVLP example) without using cursor or touch to control its movement. I want to control movement of HVLP gun in scene by tracking actual movement of a gun model in player's hand. I don't want to use costly VR trackers, instead want to use a simple optical tracker method using a webcam and IR led mounted on the gun model. Is it possible... and how..?
     
  16. knas01

    knas01

    Joined:
    Feb 24, 2018
    Posts:
    233
    Hi, how does this asset handle multiple copies of the same object with the same material? Will they all be painted in the same spot or are they treated completely independent?
     
  17. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    If you look at the HVLP GameObject in this scene, you can see the spray painting itself is triggered using normal events from the P3dVrTool component. If you want to manually do this then you can call the exact same ParticleSystem.Play/Stop methods from your own code/events. As for the position of the gun, you can just modify the Transform.position/rotation values based on your optical tracker values. Perhaps there's an example of this in the webcam tool you're using? This is outside the scope of what P3D was designed for so I can't help you there.


    They will be given unique materials when you add the P3dMaterialCloner component, and unique textures then you add the P3dPaintableTexture component, so they're treated completely independently. If you have an atlas setup and need them to share the same material and/or texture then this is possible too using the P3dModel component and dragging and dropping them together based on how you want them linked.

    Just a heads up, Paint in 3D will go on sale later today so you want to hole off a little bit before purchasing :)
     
  18. virendravishth

    virendravishth

    Joined:
    Sep 12, 2016
    Posts:
    7
    Thanks for your prompt reply. Will surely try it.

    Awesome asset and equally nice its developer is.
     
  19. LuiBroDood

    LuiBroDood

    Joined:
    Mar 13, 2019
    Posts:
    84
    quick question,
    with this asset, do my models need good UVs?
    or can the painter paint UV independently?

    ... lets say i have a cube, and i use 1 plane UV for all 6 sides,
    typically all 6 sides would get same color, say red

    when i go to paint, can i paint each side a different color?
    or does this asset use my UVs? .. so all sides will be same color ?

    would be awesome if it was UV independent ability
     
    Last edited: Jul 15, 2020
  20. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    The paint is applied using the UV data in your mesh. This can either be manually made (ideal), or automatically generated by Unity (works well, but may waste a lot of UV area).

    Automatically generated UV data is placed in the second UV channel, so to use it you can either be copy it to the first channel (Paint in 3D comes with a tool to do this), or you can use a custom shader that uses the second UV channel (Paint in 3D comes with shaders to do this).
     
  21. BjoUnity3d

    BjoUnity3d

    Joined:
    Jul 24, 2012
    Posts:
    56
    I just upgraded an existing project to 1.9.0 and immediately this error appeared in the console:

    [CompilerError] 'P3dHitCache' does not contain a definition for 'InvokeRaycast' and no accessible extension method 'InvokeRaycast' accepting a first argument of type 'P3dHitCache' could be found (are you missing a using directive or an assembly reference?)
    Compiler Error at Assets\PaintIn3D\InGame\Scripts\P3dHitExplosion.cs:120 column 14
     
  22. BjoUnity3d

    BjoUnity3d

    Joined:
    Jul 24, 2012
    Posts:
    56
    I fixed the above error by deleting the PaintIn3D folder and reinstalling. But now my coverage counter is not working. Before updating the channel counter reported 100% coverage if I painted the whole front of my object. Now it says 36% :(
     
  23. BjoUnity3d

    BjoUnity3d

    Joined:
    Jul 24, 2012
    Posts:
    56
    This is what it's supposed to look like. I reverted to my previous commit before updating to 1.9 and when I paint the whole thing it says 100%. After updating the channel counter looks different. It has a Mesh Mask slot and a Texture Mask slot. And when I paint it only says 36% coverage. The only reason I updated is because I'm trying to use the Seamless Mesh feature, but for the life of me I can't follow the instructions. It says to click the gear icon on the model to run the seamless tool but I can't find any way to run the seamless tool. I see in 1.9 it appears on the model importer dialog. But if I update to 1.9 channel counter stops working.

    upload_2020-7-16_20-24-44.png
     
  24. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    In the latest version the .Mesh setting on the counter components was renamed to MaskMesh, and MaskTexture was also added so you can specify a custom mask. Make sure your MaskMesh is set to the original (non seam fixed) mesh.

    The seam fixer tool is available in all recent versions of Paint in 3D. Originally it was only available in the Mesh inspector context menu, but in the latest version it's also available in the mesh importer itself:

    upload_2020-7-17_10-27-39.png

    Clicking the gear icon at the top right there will reveal this.
     
    BjoUnity3d likes this.
  25. BjoUnity3d

    BjoUnity3d

    Joined:
    Jul 24, 2012
    Posts:
    56
    Thank you Darkcoder. I finally found the menu item for Fix Seams.

    I guess that means I can use the old version, but I'd like to be able to use the latest and greatest. I still can't figure out what's wrong with my setup. In v1.8.8, not using the seam fixed mesh, I just added the channel counter and selected the original mesh for the Mesh slot. As you can see in the previous screenshot that made it work, showing 100% coverage. If I remove the mesh from the mesh slot, it only shows 36%.

    In v1.9.0 even though I selected the same mesh for the new Mask Mesh slot, it shows 36%. Whether I select a mesh or not, it shows 36%.

    upload_2020-7-17_6-42-19.png
     
  26. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Can you send me this mesh via private message or email so I can test it myself?
     
    BjoUnity3d likes this.
  27. Syllvia

    Syllvia

    Joined:
    Mar 26, 2013
    Posts:
    16
    Howdy,I can't seem to get the in-editor painting to work. none of the demos for that function, and following the insturctions on the docs don't seem to work either. All of the in-game demos work just fine, but the in-editor stuff isn't responding.

    I can move the camera around, ic an change the kind of thing that'll be painted, the p3dhitscreen and ect are created in the hierarchy, but nothing is painted in the dmeo or via my own setups. I don't know if i'm just doing something wrong or what.

    I do have the old and new input systems both installed, could there be some conflict or issue there? I tried changing it from mouse 0 to something else, no dice. nothing else seems to have this input issue.

    I can send any scenes/record any sort of video you'd need to figure out what's up.

    --
    Also, totally seperate question, do you know if this asset plays nice with UMA? I'm planning to have the user be able to put patches on their jackets or emblems on their mech parts and the items are all gonna be UMA-built, so applying and saving those matters. I assume it'll be fine given the demo that supports meshes loaded in via code, but i'm curious if there's anything i need to look out for.
     
    Last edited: Jul 20, 2020
  28. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Did you paint in the Game window? I just tested the latest version of Paint in 3D in Unity 2019.4.0f1 with the new InputSystem, and it seems to work as expected:

    upload_2020-7-20_11-30-41.png

    I think I tried painting UMA assets before and noticed no issues besides some UV overlap on the clothing or something. As long as the meshes are rendered using the mesh UV data (most do) and this UV data isn't overlapping or tiled it should work fine.
     
  29. Syllvia

    Syllvia

    Joined:
    Mar 26, 2013
    Posts:
    16
    Aaaaa wait, wait, I forgot to set the actual material in the paint window. It was set to erase albedo by default and just kinda asssumed it was preloaded with something and poked at everything except that one button. (IE i saw a big symbool on Materail and assumed it was supposed to be there and didn't think much about it.) Gah, my bad. Much appreciated.
     
    Darkcoder likes this.
  30. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Yeah I think by default it picks the first tool/material/shape it finds in the project. Perhaps I should make it null so you must actually pick one, or somehow define the initial setup so you can quickly see something.
     
  31. LucentGames

    LucentGames

    Joined:
    Feb 28, 2017
    Posts:
    8
    Hi Carlos/Darkcoder!

    Firstly wanted to say your asset is awesome and it's really cool to see the frequent updates! I wanted to create a whiteboard/drawing module to add to my application and unfortunately having a bit of an issue where the line I'm drawing has regular gaps between the painted texture (see attached, excuse programmer art).

    Do you have any advice for how to avoid this? I was hoping to achieve something as smooth looking as in your demo. Really appreciate any assistance!
     

    Attached Files:

    • gaps.PNG
      gaps.PNG
      File size:
      442.5 KB
      Views:
      338
  32. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Which version are you using? This looks about 2 years old.
     
  33. Gssev7

    Gssev7

    Joined:
    Jul 9, 2014
    Posts:
    17
    Hi, is it possible to paint a height map for tessalation etc using this?
     
  34. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Yes, you can paint any kind of texture. One thing to keep in mind is that the paint is applied using the mesh, so it doesn't know how your shader will deform the vertices/fragments. A tessellation shader will typically deform the mesh, so there may be some kind of visual 'offset' from where you paint vs where the paint appears. As long as your tessellation offset isn't too significant this won't be an issue though.
     
  35. Gssev7

    Gssev7

    Joined:
    Jul 9, 2014
    Posts:
    17
    Great, So I could have a flat plane as my canvas and paint on it the tessellated material.
    How do I add a material to the paint 3d menu that has height or tessellation?
    Like a substance material or unity tessellation material?
     
  36. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    Yes, if your height is stored in the alpha channel for example you can just paint using the additive/subtractive blending modes, with a color of 0,0,0,1. The P3dPaintableTexture component allows you to specify which material and texture slot you want to paint, so you would set this to _HeightTex, or whatever it's called in your shader.
     
  37. FamilyGamesTime

    FamilyGamesTime

    Joined:
    Apr 27, 2017
    Posts:
    21
    Hi, I've been struggling with this for a while and hoping you can help. What I want to do is combine the paintball example and the '64 Under' example, so that paint can be thrown onto a mesh - and I then want to detect what color paint has been thrown onto that mesh at particular pre-determined points on the mesh.

    Basically I have a crumpled up t shirt that I allow the user to paint, and I want to detect what paint they have put where. I've worked around it by putting invisible objects just above the mesh that detect the paintball moving through it with a collider, but this doesn't work that well.

    Any advice? When I copy the 'Paint' object and 'Red button' object from the 64 example into the paintball scene, it never fires an event that indicates the paint has changed when I throw a paintball at the point where the Paint line object intersects the map mesh.

    Is it actually possible for the P3ReadColor class to read the color if it has been changed by someone painting it, or does it only work on a static image?

    Latest version btw, 1.9.0.
     
    Last edited: Jul 23, 2020
  38. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    The P3dReadColor component requires UV data so it knows where to read from. If you set P3dHitCollisions.Draw to PointsOnUV then it will send this and work. You can see which components it's sending data to at the bottom of the inspector, but it may be hard to spot this. For the paint to look good PointsIn3D looks better though, so perhaps I need to think up a way to support both at the same time without it being difficult to use.
     
  39. FamilyGamesTime

    FamilyGamesTime

    Joined:
    Apr 27, 2017
    Posts:
    21
    Thanks, I tried changing P3dHitCollisions.Draw to PointsOnUV on Tools -> Paint (Yellow) -> Ball in the paintball scene and I can see what you mean by it doesn't look as good. It colors whole sections of the mesh instead of just where the paint lands, which isn't what I'm after. It also didn't trigger the OnColor event anyway.

    That's ok, I'll try to improve the collider solution I came up with - thanks.
     
    Last edited: Jul 23, 2020
  40. FamilyGamesTime

    FamilyGamesTime

    Joined:
    Apr 27, 2017
    Posts:
    21
    Actually I just realized what you meant about sending hit events to other objects. I can see the ball is sending events to p3dPaintDecal and has the position in the HandleHitPoint function - that should be more reliable to use than the collider objects I had setup.
     
  41. Gssev7

    Gssev7

    Joined:
    Jul 9, 2014
    Posts:
    17
    OK, thanks. I've got it working, I'll have a go to make a preset. Plenty of options to play with . Many thanks.
     
    Darkcoder likes this.
  42. dannyoakley

    dannyoakley

    Joined:
    Jun 18, 2016
    Posts:
    11
    I am saving out an image file as a byte array using P3dPaintableTexture.GetPngData(). Then I clear the paint using P3dPaintable.ClearAll(). If I just load that saved image into the _BaseMap of the material, I'm no longer able to paint on the surface. How would I load that texture image back in and be able to add to or erase it? Hope that makes sense.
     
  43. RadioactiveBullfrog

    RadioactiveBullfrog

    Joined:
    Jul 8, 2017
    Posts:
    55
    How hard would it be to add the ability to load mesh and textures from files at runtime? I am wanting to turn this into a painting application for a specific purpose. Kind of like a distant cousin to Armor Paint or Substance Painter. I don't need to be able to save the mesh or changes to the textures… Only the painted texture finished result like it does now. I'm just wondering if all this is feasible.
     
  44. dannyoakley

    dannyoakley

    Joined:
    Jun 18, 2016
    Posts:
    11
    Figured out I needed to use P3dPaintableTexture.LoadFromData(). That will take in the saved byte array and keep it editable.
     
    Darkcoder likes this.
  45. Realgar

    Realgar

    Joined:
    Sep 30, 2012
    Posts:
    52
    Hi Carlos, I just saw that I had a bug since the last update or the one just before. When I clic on a button tool, it desactivates the others (with Button Isolate component) but now, when I clic another time on the same button, it desactivate it also... It's a problem for because I have a special tool wich open a modal box with several textures, and I re-clic on the button to select another texture, Button Isolate desactivate it ! Perhaps did you change the Button Isolate in the last update ? Thank's !
     
  46. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    This would be easy to do. The "Procedural Setup" demo scene shows you how to paint an object from an empty GameObject, so in your scenario you just need to add the ability to save the texture when you finish painting (e.g. close the app), and then load it again when you start again. Each paintable texture on your object is defined by the P3dPaintableTexture component, so you just need to grab the byte[] data from yourPaintableTexture.GetPngData, and you can load it back with yourPaintableTexture.LoadFromData. The actual file io and storage of which model was painted would have to be done by you though, using System.IO.File or something.
     
  47. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,337
    I changed the behavior of the isolate buttons because the old implementation required me to add a 'dummy' button for camera rotation, which I think looked bad because on desktop you can always right click to rotate. You can always change the P3dButtonIsolate code line 39 to something like: child.gameObject.SetActive(child == target);

    This may break right click rotation though.
     
  48. media_unity

    media_unity

    Joined:
    Nov 12, 2019
    Posts:
    2
    I'm having a similar issue. I cannot get my percentage to read out to 100% with a decent UV Map the closest I've gotten to is 60% coverage. I'm using the change counter. I plugged the original mesh(Non-Seamed) into the mesh mask and nothing has allowed me to achieve 100% coverage. Any help is greatly appreciated.
     

    Attached Files:

  49. jimmying

    jimmying

    Joined:
    Sep 20, 2017
    Posts:
    105
    Hey Carlos,

    I'm having an issue with getting Undo to work with an existing texture. Not sure if it's a setup issue or issue with the asset itself.

    Below video shows the setup and issue.

    Basically, I attach a texture via the Texture property on the Paintable Texture. Then I paint and undo. The undo doesn't properly undo -- it leaves some faces of the mesh still painted until I paint a new stroke.

    This is using version 1.8.5.



    Also to note, in version 1.9.0 (latest) the undo example doesn't work at all for me. I'm more interested in 1.8.5 though since that's the version I'm using.
     
  50. Gwynbleidd00

    Gwynbleidd00

    Joined:
    Jul 16, 2018
    Posts:
    1
    Hey Carlos,
    I'm trying to handle this problem a help could be nice;
    How can I detect the count of Decay's?
    Scenerio; I have a tattoo and I want to know if user select a tattoo and clicked to the character.