Search Unity

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

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

  1. th3z0d1ac

    th3z0d1ac

    Joined:
    May 14, 2014
    Posts:
    15
    Hey I already wrote you an email 3-4 days ago, but I received no support or answer so I try to get some guidance here.

    I would like to use your asset in a Android app, however I experiencing issues with devices with older Mali 400 GPU. The shaders are completely invisible, they're not rendered.

    Anyone have idea how to make Paint3D work with Mali 400 devices?

    I did some testing, devices with Mali 400 MP and with Mali 450 MP are unable to render Paint 3D objects. I always using the official test scenes provided with the asset. I even tried it with URP and without it, but no success. The objects are completely invisible on the device.

    Hope someone can help me somehow.
     
  2. vorokoi

    vorokoi

    Joined:
    Oct 18, 2019
    Posts:
    39
    Anyone else running into an issue with 1.8.7? My PaintSphere and PaintDecals are hit or miss, and either need a scene restart or Unity editor restart to work again, and often times will paint for a split second before disappearing from the paintable texture.

    "UnassignedReferenceException: The variable current of P3dPaintableTexture has not been assigned.
    You probably need to assign the current variable of the P3dPaintableTexture script in the inspector."

    This error will appear and disappear depending on whether or not I get a 'good' scene restart or editor restart. I'm not using and save/load either.
     
    Last edited: May 24, 2020
  3. Darkcoder

    Darkcoder

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

    Mali 400-470 only support OpenGL ES 2.0, and the example Paint in 3D shaders are marked as "#pragma target 3.0", so this may be the issue. You can try removing this line in the example shaders, or using a different shader (e.g. legacy ones) instead.


    Do you experience this issue in the example scenes, or only your scenes? Regarding "UnassignedReferenceException", which script is this error coming from?
     
  4. altepTest

    altepTest

    Joined:
    Jul 5, 2012
    Posts:
    1,117
    Hi, I've purchased your Paint in 3D assets and it does exactly what I need it to do. Just great. Not sure how to prove the purchase but if you need this info let me know how.

    I have a few questions if you can give me some indications on the best steps to achieve this.

    I'm using Playmaker as main driver for game logic. I'm able to extend implement custom code, create custom actions if needed.

    I have a Skinned Mesh Renderer with multiple materials where I've prepared "Material Cloners" and "Paintable Textures" as required.

    So what do I want to do depending on my game logic flow (I'm using the Paint Decal) :

    I need to enable disable the paint functionality globally but keep the setup and textures already painted till the moment when I disable the painting. Then resume as many times as I want.

    I would also like to enable or disable some of these "Paintable Textures". So on the same Mesh Renderer I would like to have Material Cloner 0, 3 and 5 to be paintable, and have 4 and 7 locked.

    Can you give me some broad indications on how to approach this, where is, if this exist, a "master switch On/Off pause" of the asset, and what steps to take to paint on enable only some of the paintable textures if is possible.

    Also maybe too much to ask, I would rather have the answers to questions above but it is possible to have something like this?:

    turn Paint On,
    no decal preview,
    one click/touch will show the decal on texture/3D model but
    two buttons Apply Delete appears, (any click apart clicking on these buttons will not paint)
    if Apply is selected the decal remains
    if Delete is selected the decal is removed (this most likely can be done by an undo redo)
    we can repeat.

    But how to constrain the painting functionality to wait for these steps? Click, suspend the paint, resume it, suspend it.

    Finally for now, sorry, :)

    using the steps above, how to move the decal preview using interface arrows?

    Meaning, after the touch/click the decal appears on the material texture, on the model,
    then the Apply Delete buttons appears like above but also 4 arrows buttons Up Down Left Right appears.
    when clicking these buttons the decal will move left or up or right for a certain amount but keeping track of the UV projection / polygon orientation in 3d space.

    (This I like to implement for scale and rotation also)

    Don't worry about how the buttons appears or are added I will add those buttons and probably using the undo redo functionality will help with the Apply Delete.

    Thank You
     
  5. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    There's no global way to turn painting on/off, but you can get something similar by activating/deactivating the GameObject used to paint your objects. In most of the example demo scenes this is the 'Paint' or 'Tools' GameObject.

    The other features you mention can be done using the P3dHitNearby component (Live Painting demo scene). This allows you to paint at the current Transform position+rotation. To make the decal move with buttons you need to use some kind of custom script on the live painting GameObject to move it. This can be done with my LeanTouch+ asset's LeanManualTranslate component, which can be controlled from UI buttons or touch gestures, but I imagine there's a script somewhere out there that does something similar. To make it so clicking a button actually applies the paint you must change the P3dHitNearby component's Preview setting to false for one frame then back to true, or: set it to false, manually call the "ManuallyHitNow" method, and then set Preview back to true. In the next version I will make the ManuallyHitNow method automatically toggle the Preview setting to make this easier.
     
  6. altepTest

    altepTest

    Joined:
    Jul 5, 2012
    Posts:
    1,117
    awesome, Thank You I will check all this and let you know how it worked. For having active only parts of materials/textures active I've disabled and enabled the paintable texture component couple of time while playing, looks like it doesn't mess anything up
     
  7. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Great. Also, I've just added a simple component that allows you to move live decals with UI buttons. I'll submit this next version in a few days :)
     
  8. altepTest

    altepTest

    Joined:
    Jul 5, 2012
    Posts:
    1,117
    oh man that would be awesome!
     
    Darkcoder likes this.
  9. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Hello Darkcoder

    This asset is awesome, however I cannot do one thing. Im trying to separate my gameobjects into modules, so I would like to add the Paintable scripts to a different Gameobejct where the Mesh is. How can I do this? is there a way to decouple this that I am able to select a target mesh?

    Thank you.
     
  10. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    I have another problem, I have a skinned mesh renderer with multiple materials, some of the slots use the same material. This is causing weird issues in which only 1 part of the mesh will get painted but not others.

    It seems altho I add a PaintableTexture and Cloner for each slot, is cloning the same material thus only 1 section of the mesh gets painted.

    Look when I run it the material gets cloned twice



    I appreciate your help.
     
    Last edited: Jun 1, 2020
  11. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    You can kind of do this using the "Atlas Painting" demo scene setup, then your main visual GameObject only needs the P3dModel component. If you need to to be completely separate then you must modify the code to expose cachedRenderer, and make it manually set.

    That's a lot of materials! If your mesh has multiple materials that are the same then they will automatically be shared. For example:

    Your renderer has 3 materials: MaterialA, MaterialA, MaterialB
    You have a P3dMaterialCloner that targets slot 0.
    Material slot 0 will be cloned, and set into slots 0 and 1.
    You now have MaterialA (Clone), MaterialA (Clone), MaterialB.

    In this scenario you shouldn't have a P3dMaterialCloner for slot 1, becuase it will probably re-clone and overwrite slots 0 and 1 again.

    If you don't want slot 0 and 1 to have the same material, then you should duplicate your material so they're different.
     
  12. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Thanks, I already tried many things, I tried only using 1 cloner but only the last material in the list gets painted, even when I only specify a single cloner for 1 slot all of them with the same material get assigned the cloned material.
     
  13. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Yes, as I said it will find+replace all identical materials. If you don't want this behaviour then you must manually make unique materials for each slot so they are different, even if they ultimately have the same settings.
     
  14. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Thanks that will work.
    The reason Im trying to find a better way of doing this is because my SkinnedMeshRenderer has 6 materials that need to be painted. Do I need to add 1 PaintableTexture plus 1 Material cloner for each of them in the same GameObject?

    Another problem I got is when I add a Gradually Fade script. it will only fade one of the materials of the mesh, even if I have different materials per slot. Im not sure how to do this, do I have to specify 1 Gradually Fade per each Paintable Texture?
     
    Last edited: Jun 2, 2020
  15. Euricius

    Euricius

    Joined:
    Sep 3, 2017
    Posts:
    25
    Hello Darkcoder

    Can't find API to add P3dModifier from code. Is it possible? v.1.8.7
     
  16. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Yes to both.

    Yes, just make a serializable class that implements P3dModifier, and override one or more of the OnModify___ methods. You also have to define a: public static string Group; and Title;

    You can copy+paste the code for P3dModifyAngleRandom or the others to make things easier. I'll improve the P3dModifier documentation for the next version.
     
  17. Euricius

    Euricius

    Joined:
    Sep 3, 2017
    Posts:
    25

    I meant how to add from code any of P3dModifier to e.g. P3dPaintDecal?
     
  18. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Good question, you can't right now. I'll send you a new version later today!
     
    Euricius likes this.
  19. Euricius

    Euricius

    Joined:
    Sep 3, 2017
    Posts:
    25
    It's not in a hurry. It'll be good to have this possibility in future updates. Thanks!
     
    Last edited: Jun 2, 2020
  20. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Thanks for the help, I appreciate it.

    I have another question, is it possible to use the Gradual fade to fade in and then out?
     
  21. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Do you have an example of what you mean? If you want to pulse the painted texture or something then you should modify the material settings directly, P3dGraduallyFade modifies the actual paint, so you will lose data as it fades.
     
  22. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    The use case is a hand slap on the skin, at first it doesn't leave mark but as seconds pass a hand print on the skin starts to become visible, it gets to a maximum and then fades away.
     
  23. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I see, this would require a custom shader then. Your shader could have a 'slap texture' that you paint with a hand decal, and the strength of the slap is stored in the alpha channel, which you would fade out with P3dGraduallyFade using the Subtractive blending mode with a color of RGBA 0,0,0,1. Your shader would then apply the slap color based on the current slap alpha value, where a value of 1 means no visibility, 0.5 is full visibility, and then 0 is no visibility again. You could control this using a sine wave or similar.
     
  24. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Sorry for too many question, you support is awesome. I have another issue, Im using a character that has an IK manipulating the position of the ragdoll colliders. This is interfering with the painting since at the moment the raycast hits on the ragdoll collider, the mesh is at a position but when the paint is put into the texture is drawing it on a different position.

    This could be because in a single frame, on Update the colliders are at one position, then later on the frame those colliders are moved to a position specified by IK calculations, by the end of the frame the mesh might be in a different position than where the painter is trying to put the decal.

    I tried to set the script execution order of P3dHitScreen and P3dPaintDecal to be executed after the IK script, but still decals are being miss placed.

    Do you have any idea on which other components are involved in painting so that I might need to change their execution order? Or anything that might be helpful?

    Thank you.
     
  25. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Figured this one, was a tough one. Even tho I set the Script executable order of many Paint3D scripts including P3dPaintableManager, it was not working. Why? Because P3dPaintableManager is managing its own executable order and is set to 100 while I need it to be above 5000.

    I just put 5000 in there and now it is working fine and is painting in the right position because now is calculating it at the very end of the frame and after every other script

    Thanks again for your support, it is very helpful and this asset is awesome.
     
    Darkcoder likes this.
  26. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I'll fix that so it sets 100 as the default rather than forcing it.
     
  27. zeromao

    zeromao

    Joined:
    Jun 4, 2020
    Posts:
    1
    Hi,I have a question . How to adjust the projection depth to prevent backface painting ?
    Thanks.
     
  28. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    This can be controlled with the P3dPaintDecal.Normal___ settings. For example:

    NormalFront = 1 and NormalBack = 0 means you only paint on surfaces facing toward the paint hit.

    NormalFront = 1 and NormalBack = 1 means both sides will be painted.

    NormalFront = .5 and NormalBack = .5 means only half of the front and half of the back will be painted.

    You can see the Decal / Normal Front and Normal Fade demo scenes for a visual example.
     
  29. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Hello Darkcoder, got another question.

    I have a gameobject with a custom HitCollision script that can swap PaintDecals at runtime, the problem is that when I swap the decal to use a different one it is still painting the previous decal.

    This is because the P3dHitCache I think.

    What is the best way to accomplish what I need, do I need to invalidate the cache everytime? Does it supports caching multiple PaintDecals? if so how can I set it like that?

    For now I found a workaround in which I instantiate 2 caches , one for each decal like this:
    Code (CSharp):
    1.        
    2. if (isPunch) {
    3.     punchHitCache.InvokePoint(this.punchDecal, false, 0, 1, finalPosition, finalRotation);
    4. } else {
    5.     slapHitCache.InvokePoint(this.handPrintDecal, false, 0, 1, finalPosition, finalRotation);
    6. }
    7.  

    is this the right way to do it?

    Thank you.
     
  30. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Components like P3dHitCollisions have the ClearHitCache method, which you can call after changing the paint components. If you're using a custom hit component with the P3dHitCache then you can call the Clear method on it to do the same thing.
     
    Hazneliel likes this.
  31. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Hello
    It is possible to have decals that gradually fade at different speeds?
     
  32. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    If you use the LivePainting system then you can manually fade the opacity of each decal exactly as you want. If you have too many decals and need higher performance, then you would need to implement a custom version of P3dGraduallyFade that fades using a custom shader. For example, you could paint two textures: TextureA = RGBA+A, TextureB = FadeSpeed. This fading shader would then decrease TextureA.a based on the TextureB.a.
     
  33. altepTest

    altepTest

    Joined:
    Jul 5, 2012
    Posts:
    1,117
    Hi, this feature is included in the last version? If yes, can you point me out where to find it?

    EDIT: Found it! Great will play with it :)
     
    Last edited: Jun 10, 2020
    Darkcoder likes this.
  34. holdingjason

    holdingjason

    Joined:
    Nov 14, 2012
    Posts:
    135
    Looking at picking this up for a few reasons. Obviously to allow in game painting on decorative items, clothing etc to allow deeper customization. But had a few questions.

    1) Deferred rendering supported?
    2) I think URP is also supported?
    3) Would this be an appropriate solution for painting footprints ie decals. Right now using a outdated solution that has some big problems. Needs to be very performant since a lot of footprints might be spawned as character run around.

    Thanks.
     
  35. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    1) Yes.
    2) Yes.
    3) It depends. If your play area isn't too large and you need lots of footprints and possibly other marks on the floor then sure. If your play area is very large then you will quickly use up a lot of texture memory, so you will need some kind of system to activate and deactivate paintable areas to keep memory at a consistent usage level. Also, keep in mind terrains can't be painted, only meshes + skinned meshes.
     
  36. killer1171090

    killer1171090

    Joined:
    Feb 23, 2013
    Posts:
    145
    Is it possible to Save/Load the painting to a String format?
     
  37. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    You can convert a P3dPaintableTexture to/from byte[] using the GetPngData and LoadFromData methods.

    You can convert byte[] to/from string using the System.Convert.ToBase64String and FromBase64String methods.
     
    killer1171090 likes this.
  38. DFros

    DFros

    Joined:
    Nov 2, 2014
    Posts:
    1
    Hello Darkcoder,

    I am working on a big project for VR on the Oculus Quest but I come against an issue.
    I'm trying to make it work with the standard Quest controllers but it doesn't seem to recognise the buttons and triggers and I can't find where you call in the controllers to fix it or change it to the standard Oculus API output.

    Can you point me in the right direction or help me out with this please?
     
  39. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    The P3dVrManager component's inspector has the "Map Controllers" button, which maps them like this:

    Code (CSharp):
    1. MapController(axes, "VR Left Trigger", 8);
    2. MapController(axes, "VR Right Trigger", 9);
    3. MapController(axes, "VR Left Grip", 10);
    4. MapController(axes, "VR Right Grip",11);
    If these axes don't work for the quest then you can modify them in the input settings in your project settings, just look for the 4 entries named there.
     
  40. killer1171090

    killer1171090

    Joined:
    Feb 23, 2013
    Posts:
    145
    In the docs it says that Components are required and Meshes needs to be set to Paintable?
    What would be the bare minimum required to get the painting system working on a procedural mesh so everything setup entirely in runtime?
     
  41. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    The attached file will be included as an example in the next version of Paint in 3D. This shows you how to create and make a mesh paintable entirely from C# code. Keep in mind this code won't work with the current version because the current P3dPaintable component will activate immediately, but in the next version it's modified to activate in Start. If you wish to make this code work with the current version you need to manually call .Activate() on the P3dMaterialCloner and P3dPaintableTexture components. The new version will be out later this month.
     

    Attached Files:

    killer1171090 likes this.
  42. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    I'm using a flood fill script in C# on the CPU not like the included global flood fill in P3D (Side note: I know local flood fill is possible despite the parallelism on GPUs using column scanlines; might be a pain to implement in Unity but would be super helpful)

    Anyways at the moment I'm trying a bunch of really hacky approaches to use "c# brushes" and "shader brushes" at the same time. The common problem is they all need to have a render texture applied to the paintable texture before the paintable texture overrides the material (I start with a procedural unwrap of the mesh in texture space) and the output of the flood fill operation needs to be applied to the paintable render texture whenever that tool is used.

    What would solve these problems (which I will do on my own, but it might be helpful to add this for everyone)

    1) Add a post initialization Unity event to the paintable texture class that gets invoked after a material instance is created.
    2) Helper functions to read/convert Texture2D to the current paintable texture.
     
  43. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    1) In the next version there will be a OnActivated event added to P3dPaintable.

    2) On P3dPaintableTexture there is the .GetReadableCopy() method, and you can update from a Texture using the .Replace or .Clear methods.

    An actual floodfill example would be nice though, I plan to add it eventually.
     
    ParadoxSolutions likes this.
  44. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    @Darkcoder

    Calling .Replace() on a PaintableTexture does not seem to automatically reflect changes to the Paintable's OtherRenderers property.

    Are the other renderers just having their materials copied from the paintable's renderer?

    Edit: I added a loop to copy the mat to the other renderers and got the desired result, I'm not sure how often Replace is called internally but it would be nice for this to be built in if it is not to expensive.

    Also I have not tried yet but does the Replace() function work with undo/redo or would I have to register the change myself?
     
    Last edited: Jun 22, 2020
  45. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    When your P3dPaintable and P3dMaterialCloner components activate, the specified material and matching OtherRenderers materials will be replaced with the cloned version. Since they will all now have the same clone, clearing or replacing a texture on one will change it on all other clones. If you don't see this then you must have some other code that is causing the materials to change and no longer match. It's not possible to automatically keep doing this replacement because if you change the material then P3dMaterialCloner doesn't know which material you want to have cloned/replaced since their references no longer match. Perhaps I could change the implementation to track which slots in which materials were changed, or allow you to manually specify which slots in which materials.

    To support undo/redo you must call the P3dPaintableTexture's StoreState or P3dStateManager.StoreAllStates method before your modifications. This should then work with all texture modifications.
     
  46. shayk2012

    shayk2012

    Joined:
    Oct 13, 2017
    Posts:
    11
    Hi Carlos,
    Thank you for this great asset!

    I need a floodfill color capability in the p3d system:
    (floodfill - fill a continuous area of similar color pixels with new color)
    a. should integrate with the UndoSystem (Full/Local)
    b. should work also with paintables that use both the first and the secondary uv (like your "Automatic secondary" example)
    c. preview would be a bonus :)

    my questions:
    1. will you consider adding this feature into the asset (in the near future:)?
    2. if this feature is not in your roadmap, could you guide me on how to do it myself?
    (I succeeded doing it partially with: reading the renderTexture, implemnting the floodFill algorithm, writing the texture back. it works, but it doesn't integrate with the local undo system, and doesn't work on secondary uv (because it doesn't recognize the first texture))

    greetings,
    shayk
     
    Last edited: Jun 24, 2020
  47. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I plan to implement this in a future version, and I've just written a test that works without preview.

    The biggest challenge with floodfill is that it can't be run on the GPU like the other painting modes, and it can't be done in one pass so it can't be integrated like the other painting modes. It's easy enough to do it on the CPU, but it's not very high performance.
     
  48. shayk2012

    shayk2012

    Joined:
    Oct 13, 2017
    Posts:
    11
    I'm happy that you plan to implement it! thanks a lot.
    yes, I understand the challenge. (I hope that you find a way to optimize it. But even if it still takes noticeable time , I think it's legit , as long as you give give some gui feedback that something is working, and maybe give some settings (e.g. maxtime/maxcycles) to quit if the action dosen't finish).
    I wish you fruitful work and success solving it!
    best wishes
     
    Darkcoder likes this.
  49. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    If you scroll up a bit I talk about how I'm implementing local flood fill
    (CPU version from the wiki: http://wiki.unity3d.com/index.php?title=TextureFloodFill)

    pretty much just have a brush object like you see in the demo scenes that when enabled lets me click a pixel that is sampled from the paintable texture using hit.texcoord. Then create a texture2D version, apply flood fill at that position then read the pixels to the paintable texture's active texture then call Replace().

    It works, but it is slow at about a 2 second delay for 2k textures.

    I would post my code but it is pretty integrated with other stuff. Would be nice to have a GPU local floodfill to just Blit (although I dont think you can pass Blit a texcoord). Unfortunately I can't find a GPU flood fill implementation in HLSL/GLSL anywhere other than in papers.
     
  50. Darkcoder

    Darkcoder

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

    Version 1.8.9 of Paint in 3D is now out!
    • Added Procedural Setup demo scene.
    • Added Reveal Graffiti demo scene.
    • Added Reveal Graffiti / Counter demo scene.
    • Added P3dPaintable.OnActivated event.
    • Added Triangles draw mode to P3dHitScreen.
    • Added Triangle painting tool to in-editor painting.
    • Added material builder tool to in-editor P3dMaterial inspector.
    • Added icon builder tool to in-editor P3dMaterial inspector.
    • Added seam fixer option to the ModelImporter inspector.
    • Added multi mesh support to seam fixer.
    • Added MaskTexture setting to P3d___Counter components.
    • Added channel information to P3dGroupData instances.
    • Added OnCompleted event to all P3d___Counter components.
    • Fixed seam fixer bug with higher poly meshes.
    • Fixed console errors that can appear when finishing in-editor painting.
    • Fixed normal painting on platforms that don't support DXT5nm textures.
    • Fixed in-editor camera to not longer snap with double left click.
    • Fixed P3D Overlay shader in SRP.
    • Fixed P3D Overlay/Alpha opacity in SRP.
    • Improved Seam Fixer performance.
    • Simplified P3dPaintable inspector.
    • Changed default P3dPaintable.Activation to Start.
    • Renamed P3dHitScreen.Fill to Draw.
    • Renamed P3d___Counter.Mesh setting to MaskMesh.
    • Replaced IHitRaycast interface with IHitCoord.
    • Removed P3dPaintSphere.Paint setting.
    • Removed P3dPaintDecal.Paint setting.


    New graffiti painting example, that shows you how to reveal a pre-designed texture, as well as count the % of it that has been revealed.



    New triangle painting mode that works in-editor and in-game.

    And much more!

    Enjoy :)