Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Paint In 3D ✍️ Paint In Editor✏️ Paint In 2D

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

  1. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    There's currently no way to set sprites as decal shapes, but t's fairly easy to add, so I'll add support in an upcoming version.

    As for decal rotation, this is an oversight. You can rotate decals at runtime, but I forgot to add any such setting in the editor, oops! I'll add it in the next version.
     
  2. nosebleed_dre

    nosebleed_dre

    Joined:
    Jul 25, 2013
    Posts:
    23
    Hey Carlos,

    Sent you a DM anyway, but I finally figured out the bug and it's to do with linear colourspace vs. gamma. Here's the issue...

     
  3. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Yeah, thanks for going above and beyond with the testing and videos! I'll fix it really soon.
     
  4. Malzadore

    Malzadore

    Joined:
    Feb 13, 2017
    Posts:
    4
    Has anyone tried using this with PuppetMaster? I have been trying to use it, and it produces weird results. I can only paint the skinned mesh when its completely upright, but when it has moved, it wont paint at all. It is like PaintIn3D only has the original position stored and paints to that. I was checking the code but couldn't come to any conclusions. Any idea? I can provide an example if needed! Thanks!
     
  5. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Do you know how PuppetMaster deforms and renders the mesh? Paint in 3D either uses the current MeshFilter.sharedMesh, or bakes the SkinnedMeshRenderer.sharedMesh, both of which are done in LateUpdate. If it doesn't work properly then it sounds like the rendering may be overridden somehow.
     
  6. TonismoGames

    TonismoGames

    Joined:
    Jun 12, 2018
    Posts:
    111
    upload_2018-11-24_16-37-19.png
    Very awesome tool.The codes are very manageable.I made a few little changes and now it works great with my game!Thank you for all your hard work!
     
  7. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Looks great, thanks!
     
    TonismoGames likes this.
  8. TokyoWarfareProject

    TokyoWarfareProject

    Joined:
    Jun 20, 2018
    Posts:
    812
    Welp basically I whant to build somethink similar to @TonismoGames has done. I got in teh past an asset that I had not ime till now to test and now Its too late cause its closed code and I need to extend.

    1)I was coming to ask if in runtime I could read textures from an out of project folder, from that screenshot I guess its possible.

    2) Once I modify the texture can I save them to a file? can I control naming so I can append my own "_skin" + number
     
  9. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    1 - There's no Paint in 3D feature to do this. Keep in mind all of the UI you see in TonismoGames's screenshot is custom built. To load external textures you need to implement some kind of file browser, load the file binary with System.IO.File.ReadAllBytes(path), and then convert the binary into a Texture2D. You can then load it into Paint in 3D with: P3dHelper.Blit(yourPaintableTexture.Current, yourLoadedTexture);

    2 - Yes, you can just call yourPaintableTexture.Save(saveName), or .Load(saveName).
     
    TokyoWarfareProject likes this.
  10. bennes4

    bennes4

    Joined:
    Jan 22, 2013
    Posts:
    6
    Hi, i just bought this asset, its very nice and easy. Request; Its already 'radius' to control the size of the decal , but i want to be able control the size of decal on X and Y axis (stretching).
    I also want to be able input decal positioning manually/custom. Let say by typing input coordinate area where i want to put the decal on, or dragging decal only on one axis.. thanks..
     
    Last edited: Nov 28, 2018
  11. TokyoWarfareProject

    TokyoWarfareProject

    Joined:
    Jun 20, 2018
    Posts:
    812
    Awesome. I allready use a code to load textures for ui mods with www. Will try that then. And check the rradallbytes too as I believe in console www methods are restricted
     
  12. TokyoWarfareProject

    TokyoWarfareProject

    Joined:
    Jun 20, 2018
    Posts:
    812
    are you going to update soon?
    I'm planning to start integrating your asset and I could hold integration if newer version is coming. :D
     
  13. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Yes, I plan to release some updates soon (I released one 3 days ago!). However, I don't plan to make any massive changes that will break anything, so you should be fine to implement it (no promises :D ).
     
    TokyoWarfareProject likes this.
  14. TokyoWarfareProject

    TokyoWarfareProject

    Joined:
    Jun 20, 2018
    Posts:
    812
    testing teh demos the car one does not work very fine, I would have expected to work fine on the corners

    Also some weird fading occur
     
  15. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    You can adjust the decal painting settings like "Depth" and "One Sided" to alter how this behaves. Keep in mind decals don't "know" what surface they're painting on, so it may look strange in certain scenarios with certain meshes and with certain settings. You can also adjust the collision mesh to prevent painting on the corners, or if you split the car up into multiple meshes you can isolate which body part to paint on like some games do.
     
  16. TokyoWarfareProject

    TokyoWarfareProject

    Joined:
    Jun 20, 2018
    Posts:
    812
  17. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    @Darkcoder I'm trying to make a layer system (like photoshop or paint.net) is there a good way to do this without writing a shader with a bunch of texture inputs, or creating submeshes and targeting material slots? I suppose I could read out and use Texture2D but I can see that getting complicated fast. Am I overlooking anything?
     
  18. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    As long as your mesh has no submeshes (besides the default), you can add as many material 'layers' as you like, provided they're transparent. This would require a bit of code to manage, but it's probably the easiest and most flexible system.
     
  19. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    I thought of this, but not sure about the overhead. Unity gives a warning when you add multiple materials to a renderer that doesn't have submeshes so I assume they all get rendered at once (just tested, they do). You're right this is probably the easiest since I can set the P3D slot, but ideally it should be all in one shader pass. Might be time for me to go learn shader scripting to not rely on work arounds and Graphics.Blit lol.

    Edit: thanks though, I'll go with this as a temporary solution.
     
  20. TonismoGames

    TonismoGames

    Joined:
    Jun 12, 2018
    Posts:
    111
    upload_2018-12-3_18-9-13.png upload_2018-12-3_18-9-41.png
    Hi!I ran into a problem.I want to paint my body material and glass material at the same time.They are different materials on the same Mesh.Is there a feature for this?Or will I have to modify the the scripts?Thank You for making an awesome Asset.
     
  21. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    You can do this using the "Groups" feature.

    If you look at the "PBR Painting" demo scene, you can see each paint brush has two P3dPaintSphere components. The first paints to only Group 0, and the second paints to only Group 1.

    If you look at the "ChalkBoard/"ChalkBoard" GameObject, you can see it has two P3dPaintableTexture components, one for albedo on Group 0, and one for MeticallicSmoothness on Group 1.

    In your scene you can do the same thing, but if you have two materials then make sure you also change the "Slot" setting in each P3dPaintableTexture so you paint to material 0 and 1, and also make sure you add an extra P3dMaterialCloner for your material 1.

    You should now be able to paint two materials at the same time!
     
  22. Darren-R

    Darren-R

    Joined:
    Feb 11, 2014
    Posts:
    66
    Hi there!
    Is there any movement on the undo/redo example scene at runtime.
    I'm using Bolt to control most of the methods of P3d Paintable Texture and its working fine (Save,Load clear etc) but Undo/Redo have caused me problems.

    cheers!

    Edit: (I have got it to work but it's not super clean and it would be great to have it integrated into the painting tools instead of having to slap StoreState into places I have guessed at and hope it works ;)

    Oh and by the way I love Paint in 3d! it's a very nice package thats been really easy to integrate into my project.
     
    Last edited: Dec 5, 2018
  23. TonismoGames

    TonismoGames

    Joined:
    Jun 12, 2018
    Posts:
    111
  24. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Sorry for the late reply.

    The next version of Paint in 3D includes the "Override Size" setting in the P3dPaintDecal component, which allows you to manually control the width & height of decals.

    To paint using coordinates you'll have to write a custom script to do this, because it sounds like a very game-specific feature. If you look at the P3dPaintDecal code, you can see it's quite simple. You just need to call P3dPainter.Decal.SetMatrix with your brush position, rotation, and other settings. Then P3dPainter.Decal.SetMaterial and P3dPainter.Decal.SubmitAll with other settings which you could probably hard code, or add inspector settings for like the component does.

    Axis locked painting could be added as a demo scene, but I can't quite imagine how it would be used. If you have an example video or similar showing its use I can consider it.


    The next version includes the "Car Decals Undo Redo" demo scene, and "Runtime Undo Redo" documentation. Hopefully it should be out in a few days :)
     
  25. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Version 1.6.3 Out Now!

    This version includes runtime save/load built into most of the components. All you have to do is enable the "Store States" setting in your painting component like P3dDragRaycast, set the amount of undo/redo steps you want in each P3dPaintableTexture, add the P3dUndoAll + P3dRedoAll components to your buttons, and it will work like magic.

    See the new "Car Decals Undo Redo" demo scene for an example. This same setup can be used for all the other scenes. You can also read the new "Runtime Undo Redo.pdf" for more details.

    This version also includes the new P3dPaintDecal.OverrideSize setting, which as you might guess, allows you to control the width/height of the decal instead of it always being based on the decal texture size.
     
    marcipw likes this.
  26. keithejc

    keithejc

    Joined:
    Aug 30, 2018
    Posts:
    4
    Hi - I am investigating paint in 3d for our app, we want to draw polygons on a model from a stored list of vertices. For this reason we can end up with a lot of calls to the decal painter in one go. This can cause a big delay.

    Is there any way to optimize for this mode of operation? Or is this just a fundemental limitation of the method you use? I have done some profiling but i can't pin down what actually takes all the time...
     
  27. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    I'm not sure I follow, there is no polygon shape painting feature in Paint in 3D. You mean in your app you have written custom code to draw decals that fit into the shape of a polygon the user draws? If so, that's pretty cool. If your painting is done once per pixel inside your shape then it will no doubt be slow, because I imagine that would be thousands of paint operations done in an instant. To speed this up you should really write a custom paint operation that accepts your polygon shape vertices in the shader, and can then draw it in a single pass. This should be very efficient to do, and you could even tile the decal texture along the shape to simulate something similar to what you're doing now, but it might not be exactly the same without some pretty clever code. If you have a video or screenshots of your app in action I can more easily give suggestions.
     
  28. keithejc

    keithejc

    Joined:
    Aug 30, 2018
    Posts:
    4
    Here's a video of me demoing the app; showing a polygon then adding a new one.

    These annotations are loaded in a meta file with the model and shown to highlight areas of the model. They need to be shown quickly on demand and defined in 3d space so they can be shown in other 3d apps


     
  29. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Interesting, so it's just a line path. How many decals are you using to paint that? The higher the amount, the slower it will be, and the speed will also depend on the resolution of your texture. You can increase the spacing to improve this.

    To quickly hide/show them I recommend you store the final path on a separate texture, that way you don't have to re-paint the whole texture each time you modify it.

    In a future version I plan to add some kind of line drawing paint operation, which should make things like this more or less instant. This would also allow for high quality painting on surfaces that are at sharp angles relative to the camera view.
     
  30. bennes4

    bennes4

    Joined:
    Jan 22, 2013
    Posts:
    6
    @Darkcoder Ok, thanks for the direction , i'll try.. :)
     
  31. keithejc

    keithejc

    Joined:
    Aug 30, 2018
    Posts:
    4

    Hundreds of decals here probably. Could well be more, depends on the number of lines...

    Yeah - I was thinking i could write all to one texture and then just blat that on using your system, but I would need to place it correctly and i'm not sure how i would do that. It all needs to be accurately placed.
     
  32. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    I don't mean you save the shape in a single decal texture that you later paint on. I mean after you do this slow paint with hundreds of decals, you copy the final painted texture out. You can then layer these textures in separate materials and add/remove the to your meshRenderer's sharedMaterials array to instantly hide/show them, while still keeping the exact same paint coordinates. This would require you paint to a transparent texture though.
     
  33. dannyoakley

    dannyoakley

    Joined:
    Jun 18, 2016
    Posts:
    11
    @Darkcoder just bought the asset and love it. I'm trying to tie this in to a VR app and am trying to figure what I need to do to get a raycast hit from my controller to place a decal. I'm not sure which component I should be tying into. Any suggestions?
     
  34. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    In this scenario you don't need to have any custom code, you can just add the P3dBetweenRaycast component to your controller or tool GameObject, place two empty child Transforms to define the start + end points, and drag them into the PointA + PointB settings. You can then copy + paste or setup a P3dPaintDecal component on this GameObject, or one of its children.

    Out of curiosity, which VR asset are you using? I plan to make some actual VR examples soon.
     
  35. dannyoakley

    dannyoakley

    Joined:
    Jun 18, 2016
    Posts:
    11
    Thanks @Darkcoder! I’m using VRTK. I’ll follow your steps and report back, soon.
     
    Darkcoder likes this.
  36. dannyoakley

    dannyoakley

    Joined:
    Jun 18, 2016
    Posts:
    11
    @Darkcoder Following you directions works great! Its functioning as expected, I can see the preview of the decal. I'm still searching for what to call when I press the trigger on the controller to actually apply the decal. Forgive my lack of code expertise, I'm coming at this from the art side. :D
     
  37. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Great! Tying the trigger to paint is a little difficult if you're not a coder. You have to make a component that inherits from VRTK_InteractableObject, and overrides the StartUsing and StopUsing methods. Inside those methods you can enable and disable preview painting, or manually trigger painting once without preview. I'll make a demo scene for this soon.
     
  38. dannyoakley

    dannyoakley

    Joined:
    Jun 18, 2016
    Posts:
    11
    @Darkcoder Thanks so much! I got it working. I couldn't get it through my head that if it wasn't previewing then it was applying. :confused:
     
    Darkcoder likes this.
  39. dannyoakley

    dannyoakley

    Joined:
    Jun 18, 2016
    Posts:
    11
    Hey @Darkcoder Been getting great results so far with your decal solution and VRTK. Two questions after spending the day with it.
    1. Is P3DBetweenRaycast the only option for VR? I tried P3DDragRaycast, but can't seem to get anywhere.

    2. If P3DBetweenRaycast IS the only option, is there a way to add "Drag step" and "store states" to it?

    Now that I have decals working, I'd love to use the painting features for a glass whiteboard effect.

    Thanks so much for your help and patience.
     
    Last edited: Dec 9, 2018
  40. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    None of the current components were explicitly designed for VR, P3dBetweenRaycast is just the best candidate for easy integration. P3dDragRaycast works using the mouse coordinates, so it won't work in VR. To make undo work just call P3dStateManager.StoreAllStates(); once before you begin painting. To do sub-steps you must store the old position + rotation, interpolate between that and the current state, and then run the raycast code once for each step depending on how far your controller moved or rotated or whatever.

    I will make a proper integration demos soon.





    Hey everyone, on the 10th of December (Tomorrow) my assets will be given away in DevDog's Christmas event!

    Sign Up: HERE

    You will be in for a chance to win one of:

    Paint in 3D x 5

    Space Graphics Toolkit x 5

    Planet Pack - Space Graphics Toolkit x 5

    LeanTouch+ x 5

    Destructible 2D x 5
     
  41. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    Hello again, I added some code to the P3dGroupMask struct to be able to check if a group mask contains a certain group:
    Code (CSharp):
    1.         public static bool Contains(int mask, P3dGroupMask groupMask)
    2.         {
    3.             groupMask &= 1 << mask;
    4.  
    5.             return groupMask != 0;
    6.         }
    Might be useful for other people too.

    Also the replace blend mode does not seem to support the original alpha transparency (fills it in with white, or maybe the white is from the shape image idk) Is there a way to use a shape mask without loosing transparency that I am overlooking?
     
  42. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Nice, you can also use: P3dHelper.IndexInMask(index, mask);

    The replace blend mode should use all the source channels and blend using the shape mask. Can you post screenshots of your settings?
     
  43. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    1 - Yes, all features work the same on normal or skinned meshes.

    2 - I don't have Puppetmaster, so I don't know. If someone can give me details about how it deforms and renders meshes then I can have a better idea.
     
  44. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    Puppetmaster creates a mirror of a skmr where the rig animates where it usually would but it renders a blend between IK and the original animation + rig in conjunction with physics in a separate state. Colliders and the skmr will appear in a simulated position when the original rig (and possibly shared mesh) appears where Unity would render the mesh without puppetmaster (can be visualized via debug gizmos). I do not own puppetmaster but do own final IK, check out RootMotion's videos on the asset store for a good example. (it is pretty much one big skinned render offset, they probably need to offset the paint raycast to paint on the original position and not the simulated position; although the end user will only see the simulated (blended) position so I'm not sure. Depends on relative collider location).

    1) I based the code off of P3dHelper.IndexInMask, but the group mask does not inherit from the Unity layer system so I couldn't use that helper in my case (unless I used it wrong).

    2) I'll double check my settings and see.
     
  45. CoderPro

    CoderPro

    Joined:
    Feb 21, 2014
    Posts:
    325
    Hi @Darkcoder
    I am interested in to buy your asset, but i want to try undo/redo system that you said in 1.6.3 version. Can you provide WebGL demo or something that i can test that system ? I want to try before buy this. Thanks in advanced.

    And i have a request,
    Could you add function that when user click to decal texture, camera will be focus to that decal texture, and user can modify or remove that decal texture ?

    Example,
    Paint Decal A -> Paint Decal B -> Paint Decal C -> Paint Decal D -> .....v.v
    User click Decal B texture (on the model not from UI) -> camera focus to Decal B -> user can modify or move or change size or delete this decal.

    Some games i'm playing, They manage decal textures as layers. Each decal is a layer, so they can easy select or change that decal.

    And one other request,
    Add option automatic make mirror decal texture.
    Example,
    When user paint a decal texture to left side of car, when user select mirror option, the same decal texture will be automatic paint to right side of car.

    I think this asset would be great if you add them to the next update.

    Best Regards,
     
    Last edited: Dec 18, 2018
  46. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    If this Puppetmaster blending is done in the vertex shader then it won't be supported by Paint in 3D. If it works by moving bones normally then it should work, since the SkinnedMeshRenderer should automatically update it like it does with ragdolls. As long as it moves the bones or updates the Mesh vertices directly, then it should be paintable as long as you as the P3dPaintable component gets access to the right Mesh.

    1 - Both LayerMask and P3dGroupMask can implicitly cast to int, so they can both be used with IndexInMask. [edit] I see that IndexInMask actually takes a LayerMask instead of an int, this is a mistake on my part.


    You can try the Undo Redo example HERE.

    I'll see what I can do about the demo scene idea, I have some plans for a big update to the demo scenes and such.
     
    Last edited: Dec 18, 2018
  47. CoderPro

    CoderPro

    Joined:
    Feb 21, 2014
    Posts:
    325
    Thanks for your demo scene. I hope you will implement these in the next update.
    But before i missed your asset sale. Very sadly !
     
    Darkcoder likes this.
  48. JohnnyFactor

    JohnnyFactor

    Joined:
    May 18, 2018
    Posts:
    343
    A quick question-- Is there a built-in way for a gameObject to block paint, for example, if it's in front of the paintable surface? I don't see any evidence of this in the example scenes.
     
  49. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,400
    Yes, you should be able to place any 3D object with a collider in front of your paintable objects in any of the example scenes and have it automatically block your paint. However, it will still attempt to paint the object, and because each paint operation has a certain thickness (e.g. P3dPaintSphere.Radius, P3dPaintDecal.Depth), it's possible that the paint can go through your object and still paint the object behind it if your blocking object is too thin, or it overlaps it so much that the blocking surface is too close to the paintable surface. This shouldn't be an issue in most of the example scenes, but notably the "Zombie Blood" demo scene uses quite a thick P3dPaintDecal.Depth setting, because the zombie itself is given just a single BoxCollider to cover the extent of the whole animation. To improve blocking paint in this demo scene or one like it, you should make tighter fitting colliders, like attaching one per bone as you typically do in a ragdoll setup, then you could use a much lower P3dPaintDecal.Depth setting, and thus be able to block paint with much higher success.
     
    JohnnyFactor likes this.
  50. JohnnyFactor

    JohnnyFactor

    Joined:
    May 18, 2018
    Posts:
    343
    Thanks for the info, that helps a lot.
     
    Darkcoder likes this.