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. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

【50% OFF】 ⏱Paint In 3D ️️✏️ In Game & In Editor & Skinned Mesh Painting

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

  1. fleity

    fleity

    Joined:
    Oct 13, 2015
    Posts:
    218
    For anyone interested I made a fill tool for in editor painting.
    p3d_fill.gif upload_2022-10-31_11-40-8.png

    I had to make a few adjustments to make it work though:

    Code (CSharp):
    1.  
    2. // P3dHitScreenBase.cs line 247: Changed DoQuery to return a Transform
    3. protected virtual Transform DoQuery(Vector2 screenPosition, ref Camera camera, ref Ray ray, ref RaycastHit hit3D, ref RaycastHit2D hit2D)
    4. {
    5. ...
    6.             return hit3D.transform;
    7. }
    Code (CSharp):
    1.  
    2. // P3dHitScreenBase.cs line 274: Use new DoQuery transform
    3. Transform hitTransform = DoQuery(screenPosition, ref camera, ref ray, ref hit3D, ref hit2D);
    4.  
    5. // P3dHitScreenBase.cs line 298: PointsOnUV case does not create a valid p3dhit therefore we create one here before invoking hitcache
    6. else if (emit == EmitType.PointsOnUV)
    7.             {
    8.                 P3dHit p3dHit = hit3D.collider
    9.                         ? new P3dHit(hit3D)
    10.                         : new P3dHit
    11.                         {
    12.                                 Root = hitTransform,
    13.                                 First = hit3D.textureCoord,
    14.                                 Second = hit3D.textureCoord2
    15.                         };
    16.                hitCache.InvokeCoord(gameObject, preview, priority, pressure, p3dHit, finalRotation);
    17.  
    Code (CSharp):
    1.  
    2. // P3dHitScreen_InEditor.cs line 26: Change editor DoQuery to return a transform as well
    3. protected override Transform DoQuery(...
    4.  
    5. // P3dHitScreen_InEditor.cs line 32:
    6. Transform hitTransform = null;
    7.  
    8. // P3dHitScreen_InEditor.cs line 49: assign hitTransform if hit has been found
    9. hitTransform = model.transform;
    10.  
    11. // P3dHitScreen_InEditor.cs line 55:
    12. return hitTransform;
    13.  

    Code (CSharp):
    1.  
    2. // P3dWindow_Paint line 334:
    3.                 foreach (var paintFill in materialInstance.GetComponentsInChildren<P3dPaintFill>())
    4.                 {
    5.                     if (paintFill.Group == Settings.ColorGroup)
    6.                     {
    7.                         if (Settings.OverrideColor == true)
    8.                         {
    9.                             paintFill.Color  = Settings.Color;
    10.                         }
    11.                     }
    12.                
    13.                     if (Settings.OverrideModifiers == true)
    14.                     {
    15.                         paintFill.Modifiers.Instances.Clear();
    16.  
    17.                         foreach (var modifier in Settings.Modifiers.Instances)
    18.                         {
    19.                             paintFill.Modifiers.Instances.Add(modifier);
    20.                         }
    21.                     }
    22.                 }
    23.  
    24. // P3dWindow_Paint line 370:
    25.                     if (Settings.OverrideModifiers == true)
    26.                     {
    27.                         paintSphere.Modifiers.Instances.Clear();
    28.  
    29.                         foreach (var modifier in Settings.Modifiers.Instances)
    30.                         {
    31.                             paintSphere.Modifiers.Instances.Add(modifier);
    32.                         }
    33.                     }
    34.  

    Code (CSharp):
    1.  
    2. // P3dPaintFill line 64:
    3. P3dCommandFill.Instance.SetMaterial(blendMode, finalTexture, finalColor, finalOpacity, minimum);
    4.  
     
  2. Likesundayqaq

    Likesundayqaq

    Joined:
    Jun 13, 2022
    Posts:
    5
    I have a need, I have two models to be drawn, one model is a piece of paper with holes in it, and then I put another one like a wooden model under it, using P3D paint sphere and P3D hit Particles, and then the top model to draw, it will penetrate the paper, but I just want the bottom model to be drawn the shape I need.how to solve this problem.
    pls
     
  3. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,181
    Looks good! I'll check it out soon :D

    You must use the P3dMask component ("17 Mask" demo scene) on your paper with holes in.
     
  4. Abnormalia_

    Abnormalia_

    Joined:
    Jul 23, 2013
    Posts:
    75
    I am using your amazing asset in almost every project so thanks once more. I am away from PC ATM, so cannot test this, but if it’s possible to make game object paintable at runtime, do some painting and remove afterwards. Will it be too much performance wise? Thanks in advance.
     
  5. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,181
    The "73 Procedural Setup" demo scene shows you how to generate a new mesh and configure it to be paintable entirely from code. The performance should be the same as configuring it in the editor.
     
    Abnormalia_ likes this.
  6. Ceciaman

    Ceciaman

    Joined:
    Jul 30, 2013
    Posts:
    40
    Greetings,
    congratulations for the asset.
    I would have a problem.

    On a texture on a plane I make holes, and everything is fine.

    I would like that by putting this plane on a wall and painting on it I would like the color to pass only in the holes made.
    How can I do?
     
  7. Ceciaman

    Ceciaman

    Joined:
    Jul 30, 2013
    Posts:
    40
  8. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,181
    This can be done using the P3dMask component, which will block paint near the current GameObject using the texture mask you specify. There's a demo scene called Mask that shows how to use it.
     
  9. Ceciaman

    Ceciaman

    Joined:
    Jul 30, 2013
    Posts:
    40
    I've already seen the example.
    But I don't have preset masks.
    The texture is generated on the fly.
    Do I have to use the perforated texture as a mask?
     
  10. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,181
    The Texture you specify in the P3dMask component can be any Texture, including a RenderTexture or Texture2D generated in-game. If you want to set this to a P3dPaintableTexture's texture then you can access it via the .Current property.
     
  11. Ceciaman

    Ceciaman

    Joined:
    Jul 30, 2013
    Posts:
    40
    thank's
     
    Darkcoder likes this.
  12. shahryarsheikhwork

    shahryarsheikhwork

    Joined:
    Oct 17, 2022
    Posts:
    2
    Hi,
    I have been using this asset from a long time and it is a great asset but now i am facing an issue i am trying to create a activity to paint an spinning object and it is not behaving in the way i wanted it to. I am using paint sphere with P3D hit screen and it is skipping some points while painting i have tried different methods/components but they are all behaving in the same manner so kindly help me to figure out a solution.As you can see in the image below there is like a dotted line with spaces in between and i want to paint an smooth line.

    @Darkcoder
     

    Attached Files:

  13. fleity

    fleity

    Joined:
    Oct 13, 2015
    Posts:
    218
    Did you try the connect hits setting?
     
  14. shahryarsheikhwork

    shahryarsheikhwork

    Joined:
    Oct 17, 2022
    Posts:
    2
    Yes i tried that still the issue was there :( the only way i was able to solve it to some extent was by slowing down the object rotation but it was effecting the feel i wanted to create
     
  15. emrecangoktepe

    emrecangoktepe

    Joined:
    Jan 26, 2019
    Posts:
    2
    hello darkcoder.

    I am working on a coloring application. The current fill feature works by drawing a certain area and filling it. (I looked at all the examples and couldn't find what I wanted.).

    I followed a method like this. Using the P3D Paint Sphere class, if the fill option is selected, if it is pressed a certain amount, I fill it by enlarging the radius.

    To give an example of my application, there is a white heart mesh on the screen. I can fill this heart mesh exactly as I want by holding down.
    But the real problem is, let's say I draw a straight line down the middle of the heart. Afterwards, I apply the fill option to the left side of the heart. It works as I want on the heart edges, but I don't want it to go to the right of the red line.

    If I want to give a more detailed example. Suppose I draw a circle in the middle of the heart. When I press and hold inside the circle in the middle of the heart, I just want to fill the circle. How can I do that? In short, when you fill in photoshop or paint, other colors do not pass over.

    By the way, the slowly growing circle filling shape allows me to get exactly the image I want.
     

    Attached Files:

  16. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,181
    The ConnectHits setting connects the previous and current mouse/finger/controller positions together using a line. However, if your object is moving or rotating when it gets painted then from the perspective of the object, these connected lines are no longer connected, so you get these gaps.

    The only way to get these lines to connect is to manually calculate the object's local space paint point, store it, and then transform the points to world space before you apply each paint. Or... just don't rotate or move your objects when painting if you want connected hits.



    What you're describing is called Flood Fill, which Paint in 3D doesn't support. It's not supported because all painting is done on the GPU, and flood fill is difficult to implement on GPUs. If it were on the CPU then flood fill is very easy to implement, but copying data from the GPU and CPU is immensely slow. Flood fill is easier to implement with compute shaders, but they have platform and device restrictions, so I'd rather not use them. Maybe in the future I will implement this, but not now.
     
  17. magglemitch

    magglemitch

    Joined:
    Dec 8, 2013
    Posts:
    99
    When using undo/redo, is it easy to set a state limit if you're using the local command copy?
     
  18. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,181
    If you don't record all local commands, then it will be impossible to undo even one step without there being a massive change to the texture. The only solution would be to implement some kind of hybrid undo system that periodically stores snapshots of the texture at specific local command depths, and then deles commands older than the snapshot. This is tricky to implement and has some performance implications, so I haven't had time to look into it.
     
  19. emrecangoktepe

    emrecangoktepe

    Joined:
    Jan 26, 2019
    Posts:
    2
    Thanks for the reply.
    I decided to solve it with a different approach. I cut the mesh of the objects I want to paint and make them behave like a separate piece. It's fine for a now
     
    Darkcoder likes this.
  20. fleity

    fleity

    Joined:
    Oct 13, 2015
    Posts:
    218
    This sounds much more like a problem which should be solved in the controller class which calls the undo command. Simply count how often the user has pressed undo and do not call it if counter is at a certain number? (at least if that case concers during runtime)
     
  21. tianlinzhang

    tianlinzhang

    Joined:
    Mar 18, 2021
    Posts:
    7
    Hello! I have used your wonderful Paint3D for several days, most of time it works on URP well but I have found one problem: if the mesh has only one color, no texture is used, P3d cannot paint anything on top of it, I have tried second UV using second overlay material following your example, it still does not work, I have also tried the this kind of surface is very common, can you provide some clues on how to handle such mesh surface? thank you very much!
     

    Attached Files:

  22. Lemovision

    Lemovision

    Joined:
    Apr 6, 2020
    Posts:
    33
    Hi I would like to share this little project I made with Paint In 3D



    https://www.elephantparade.com/digital-artbox

    Mostly worked on this last year actually, but they finally decided to release it on their website today
    So the organization is Elephant Parade, who makes painted elephant statues with artists all around the world
    They have exhibitions and sell replicas, partly contributing to conservation funds for elephants in Thailand



    And to share this creative endeavor with their fans around the world, I suggested a digital painting experience
    This relies of course heavily on Paint In 3D, to which I added plenty of tools and painting options
    Also comes with a stamp library, and options to load any picture as a stamp from user's computer
    When painting is done, Unity exports the texture to the server, which creates a link to share with friends

    https://www.elephantparade.com/view/?e=5

    Thanks Carlos for this great plugin (my only wish for it would be pen pressure support on webgl...)
    If anyone try this, make sure to use the save and share button to upload your designs
    Have a good painting day!
     
    JoeStrout, Darkcoder and Jmonroe like this.
  23. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,181
    You must set the color to white, otherwise the final pixel color will always be tinted by the color you choose. The "10 Base Color" demo scene shows this.


    Wow, looks like a great use of the asset! Good job!!
     
  24. tianlinzhang

    tianlinzhang

    Joined:
    Mar 18, 2021
    Posts:
    7
    Thank you very much for your help!
     
    Darkcoder likes this.
  25. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,798
    Hi! I used this asset a couple years ago, but just today found I have a need for it in a new project. However I'm struggling with one issue: I can't get a soft brush to work, even in the Basic Setup demo.

    My P3DPaintSphere settings look like:
    upload_2022-12-2_7-48-48.png

    And the preview spot when I mouse over the model reflects this low hardness perfectly:
    upload_2022-12-2_7-49-28.png

    ...but when I actually click, I get:
    upload_2022-12-2_7-49-56.png

    For my purposes I need a very soft, extended gradient around the edges. What am I doing wrong?

    EDIT: Figured it out. In the P3DHitScreen component, I needed to change the Frequency from "Once Every Frame" to "Once On Press." I was getting over 500 fps in this scene, so my quick click was applying the paint probably dozens of times!
     
    Last edited: Dec 2, 2022 at 2:56 PM
    Darkcoder likes this.
  26. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,798
    Some of the objects we are painting are fairly thin — like a box only 10 cm thick. We are painting directly using P3dCommandSphere, like so:

    Code (CSharp):
    1.             P3dCommandSphere.Instance.SetState(false, 1);
    2.             P3dCommandSphere.Instance.SetLocation(position);          
    3.             P3dCommandSphere.Instance.SetShape(Quaternion.identity, Vector3.one * outerRadius, 0);
    4.             P3dCommandSphere.Instance.SetMaterial(
    5.                 P3dBlendMode.AlphaBlend(Vector4.one),
    6.                 outerRadius / (outerRadius - innerRadius),  // hardness
    7.                 color,
    8.                 1,  // opacity
    9.                 null,   // tileTexture
    10.                 Matrix4x4.identity,     // tileMatrix
    11.                 1,      // tileOpacity
    12.                 4       // tileTransition
    13.             );
    14.             P3dCommandSphere.Instance.ClearMask();
    15.             P3dPaintableManager.SubmitAll(P3dCommandSphere.Instance, position, outerRadius, -1, default, null, null);
    Works great, except for one issue. How do I keep it from applying paint to the "back" side relative to the given position?

    I'd be happy if it just computed the angle between each triangle normal and the vector to the sphere center, and skipped all the backfaces. Is that possible?
     
  27. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,181
    As the name suggests, the sphere painting feature just paints everything within the sphere radius you specify. To make it only paint on one side you must use the slightly more advanced decal painting feature, which has front/back thresholds for the normal of the decal relative to the paint surface. Of course, a decal even with a circle texture will produce slightly different results than a sphere, but with decal's Wrapping = 1 setting it will be close. I guess there's no technical reason why I couldn't add a similar setting for sphere painting, I just wanted to make a really simple alternative component as an example.
     
  28. Christin2015

    Christin2015

    Joined:
    Dec 1, 2015
    Posts:
    42
    Hello, I have found this asset at the Unity Asset Store. Does it support Oculus VR with OpenXR, or Unity XR Interaction Toolkit? I would need it urgently. Thanks in advance for any hint.
     
  29. Likesundayqaq

    Likesundayqaq

    Joined:
    Jun 13, 2022
    Posts:
    5
    I ran into a problem when I typed an apk sample scene running on the android 10 mobile version, and when I quickly swiped the screen, the dots that appeared were incoherent
     

    Attached Files:

    • 1.jpeg
      1.jpeg
      File size:
      211.5 KB
      Views:
      1