Search Unity

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

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

  1. PiAnkh

    PiAnkh

    Joined:
    Apr 20, 2013
    Posts:
    126
    I must say that this asset looks like it could be amazing but I am struggling with it. The documentation is lacking and often out of date. For example the names of the P3D components are different. I want to use it in editor rather than in-game but almost all the examples are for in-game.
    For example, how do I change the blend mode in editor? The documentation refers to brush settings, but I have no brush settings at all in the paint tab (I assume this is where they should be).
    I am tying to love this asset but so far it is very frustrating.
    Thanks for any help
     
  2. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Yeah I need to update the documentation, I rewrote the in-editor painting features a while back and some of the features have different names now.

    The 'brushes' are now called materials (P3dMaterial). You can find them in the PaintIn3D/InEditor/Materials folder. For example, you can duplicate the "White (Albedo)" one, and change the P3dPaintDecal component's BlendMode (or other settings) from AlphaBlend to Additive or whatever you like. This will now appear in the Paint tab's Material picker. I've been meaning to release some brush/material packs that contain lots of different things, but almost all users of this asset only use the in-editor stuff, so I've been focusing on that.

    Let me know what else you find so I can improve these features more!
     
  3. PiAnkh

    PiAnkh

    Joined:
    Apr 20, 2013
    Posts:
    126
    Wow. I would never have figured that out.
    You write that almost all users only use the "in-editor stuff". I assume you mean most use only the in-game stuff as that is where you have the majority of examples.
    It seems to me that the way it is implemented in-editor, in particular as materials, greatly limit its use in-editor.
    The brush settings such as opacity, texture rotation etc cannot be varied on the fly. Also no settings for brush jitter etc.
    My use case is exclusively in-editor where I need more functionality and control over the brushes. This might not be the right asset for me.
     
  4. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Oops, yes I meant the in-game features are more popular.

    To adjust the rotation/scattering/etc you need to modify the P3dPaintDecal settings for the current P3dMaterial. I plan to add some kind of 'Override Angle' etc settings to make this easier, because some materials paint a large amount of textures (e.g. PBR materials), so it's not practical to manually adjust them.

    If you'd like a refund then feel free to email or private message me your invoice/order number at any time.
     
  5. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    305
    Hello

    How can I use P3dHitNearby to paint a Decal? I have tried combining them but the Decal is not painting properly. Is there an example scene?

    Thank you.
     
  6. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    The "Live Painting" examples show you how to combine P3dHitNearby with P3dPaintDecal. Perhaps your transform is facing the wrong direction? The Z+ direction is where the decal will apply. You can increase the P3dPaintDecal.NormalFront setting to 2 to remove the slope based culling.
     
    Hazneliel likes this.
  7. haxiomic_unity

    haxiomic_unity

    Joined:
    Oct 29, 2020
    Posts:
    2
    Hey, loving this tool! Amazing work @Darkcoder

    Quick question about linear/gamma blending – is there a built in way to blend colors in linear space? Currently by default colors are blended in gamma space which produces results that don't quite look right – from the WebGL demo, if you mix green and red you get incorrect darkening (explained in more detail here: https://ninedegreesbelow.com/photography/linear-gamma-blur-normal-blend.html)
    Screenshot 2020-11-01 at 22.15.08.png

    Our project uses the gamma color space because we support WebGL 1.0, to resolve this issue we tweaked the Blend shader to perform the decode and encode before and after – did we miss a built in way to resolve this? If not maybe it could be handled automatically by checking the sRGB flag on the texture to determine if decoding is required for linear-space blending

    Code (hlsl):
    1.  
    2. const float gamma = 2.2;
    3. return pow(DoBlend(pow(current, gamma), pow(color, gamma), strength, coord, rot, channels), 1.0/gamma);
    4.  
    Screenshot 2020-11-01 at 22.25.33.png
     
  8. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Last time I tried to support gamma and linear separately it resulted in many headaches, so I made everything work in gamma. The modifications you made look good. There's indeed no way to toggle this in the current version. I'll look into this again for a future version, perhaps a setting to do what you've done is the best idea, or perform all calculations in linear instead of gamma, I'll have to experiment with it.
     
  9. haxiomic_unity

    haxiomic_unity

    Joined:
    Oct 29, 2020
    Posts:
    2
    Gotcha – we'll stick with the modification, thanks for the quick response!
     
    Darkcoder likes this.
  10. Rickmc3280

    Rickmc3280

    Joined:
    Jun 28, 2014
    Posts:
    189
    I think all of your assets are great. I often stumble upon CW when searching for stuff.

    I do think however that more video tutorials would be cool that keep in mind how to use each individual script/component. That is how my mind works unfortunately.
     
  11. songjiekun

    songjiekun

    Joined:
    Jan 21, 2017
    Posts:
    29
    @Darkcoder
    hello,
    I am using your "P3D solid " shader. it is working great and now it supports "emission texture", so it is better.
    however i am doing some fadein and fadeout effect. so i should use "P3D alpha " shader right? but "P3D alpha " shader does not have emission texture.
     
  12. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I plan to make some around the end of the year. I much prefer making tutorial demo scenes though, since they auto update with any changes I make to the components, and you can easily modify them.


    I sent you a private message with a build that should fix this.
     
  13. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
    Can you elaborate a bit more how this asset works?

    Let me explain / share my issue. First thing I tried was Polybrush, but it seems to paint in blobs, so I can't just paint where the rock intersects the terrain, I have to paint a larger 'chunk', mainly because it needs to paint on a vertex:
    upload_2020-11-6_1-31-24.png

    But your asset looks like it can paint more freely. Is this true? I'm using terrain streaming, chunking, etc. so I don't think it should be as impactful on performance compared to just rendering things the 'standard Unity way'.
     
  14. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Paint in 3D is a texture painting asset. Therefore, to blend the rock with the terrain like this you would need to paint the terrain color/texture to the base of your rocks. Since each rock is presumably uniquely rotated and scaled and on top of arbitrary terrain, this means you will have to manually paint every single rock. This will mean they cannot be batched, your texture memory would increase a lot, it would be difficult to modify the rocks as you would have to repaint them with every modification, and you would waste a lot of time doing this. Many of these issues could be offset using a custom shader where you instead paint a splat map that blends between the rock and terrain textures, but at that point you may as well just use a dedicated terrain solution that supports object blending.
     
    Exeneva likes this.
  15. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
    Correct, that's how I got in this situation in the first place - CTS 2019 does not have a mesh blending feature, and I need it.

    I tried your asset following the online docs for Editor mode, but in Play mode I don't see any sort of painting capabilities. I must be missing something basic. Can you point out a setting or something I haven't set?

    upload_2020-11-6_19-22-2.png
     
  16. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I recommend you copy+paste your terrain and rocks to a new scene to make this easier.

    Did you configure your rock for painting?

    upload_2020-11-7_10-40-6.png

    upload_2020-11-7_10-40-14.png

    If these presets don't appear then your rock is using a shader/material that isn't supported by default. In this scenario you must manually configure it like so:

    upload_2020-11-7_10-42-6.png

    You can then follow the other steps to export the texture as an asset, then you can begin painting normally and Export All once finished.
     
  17. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
    Am I missing something about the override camera?
    upload_2020-11-6_23-9-34.png

    Unity latest 2020.1, URP 8.2.0, I can't move the camera in the game scene using the controls mentioned in the doc.

    Actually, if you could just make a short video tutorial on how to set up this asset, that would be most helpful. Most other assets have a video tut of some kind.
     
    Last edited: Nov 9, 2020
  18. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Based on your previous screenshot it looks like you already have some kind of camera controls in your scene, so they may be overwriting the paint camera controls. If you put your objects in a new scene without any camera components then it should work fine.

    Here's a video showing how to paint a rock to blend in with the ground:



    Once you've created your texture like this, you can make a new material and replace its texture with this painted version. I'll look into making this process automatic with some kind of tool to pull the meshes out of the main scene to make a paint scene, but for now it must be manually done.

    I'll send you an updated build with this grass material and extra settings. This new build makes creating new in-editor painting materials easier to create:

    1. Duplicate one of the existing materials & rename it (PaintIn3D/InEditor/Materials/Full).
    2. Double click it to open its prefab.
    3. Drag and drop your textures into the texture slots, or click X on the missing ones if you don't have/need them.
    4. Click the "Build Material" button, and you can now use it.
    To make an icon for it you can open the "Icon Builder (Material)" scene (PaintIn3D/InEditor/Examples), paint the sphere with your new material, and while inside the material prefab click the "Build Icon" button. I'll update the documentation for this for the final release.

    Let me know if you encounter any issues.
     
  19. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
    upload_2020-11-9_10-8-55.png

    The current version on the store is not working for me in a new scene, unfortunately. I will try the build you sent via private message and let you know.
     
  20. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
    I should have clarified: The video I'm hoping for is actually more for the initial setup.

    I'm not creating models in a modeling program, putting them into Unity, and then trying to decide what shader to use. Instead, I have an existing scene of models that I am converting into paintable and trying to paint.

    upload_2020-11-9_21-16-40.png

    Per your suggestion, I copied the terrain and rocks over to a new scene. But when I switch from URP/Lit to your Paint in 3D shader, my object seems to disappear.
     
  21. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    You don't have to change the shader. If you do, then it looks like maybe your albedo has transparency, which is used by the P3D Solid shader to have cutout transparency. I'll send you an updated build that has presets for URP and HDRP shaders.
     
  22. Darkcoder

    Darkcoder

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

    Version 1.9.9 of Paint in 3D is now out!
    • Added Wheel Dirt demo scene.
    • Fixed P3dHitScreen values persisting through disable/enable.
    • In-Editor: Simplified P3dMaterial builder tools.
    • In-Editor: Added Override Angle setting to Paint tab.
    • In-Editor: Added Override Normal setting to Paint tab.
    • In-Editor: Added Override Modifiers setting to Paint tab.
    • In-Editor: Added Override Tiling setting to Paint tab.
    • In-Editor: Added Override State Limit setting to Scene tab.
    • In-Editor: Moved camera options to Camera tab.
    • In-Editor: Added Show Pivot camera option.

    dust.gif

    Lots of improvements to the in-editor painting features, and a nice new demo scene for car wheel dirt.

    Enjoy :)
     
    keeponshading likes this.
  23. newlife

    newlife

    Joined:
    Jan 20, 2010
    Posts:
    1,080
    Cool! it means that its possible to "transfer" the dirt on the car body?
     
  24. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
  25. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    @Darkcoder I'm using HitScreen and "Points in 3D filled" I would like to create an effect where the player has a limit on the area they can fill for example: Limit to 5 points (with a max distance between points) so the player would click 5 times then the area would be filled in.

    Is there a good way to pass points or hits to "points in 3D filled" then call fill() without a continuous brush stroke? This would be the best solution.

    If not can I track hit points using hit cache, my gameplay code requires that I have some points in the same shape that was drawn for another effect. The outliers from a list of hit positions would work but I'm not sure how to get this from the hit cache.

    If I have to use a continuous brush stroke I also need a way to limit the area by pixels or distance between points.


    Edit: I got around my problem using hit nearby, but I'll leave this question up for someone else to find.
     
    Last edited: Nov 10, 2020
  26. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Yes, you just need to change the particle and paint color based on the current surface you're driving on.


    Does it work if you change the P3dPaintableTexture component's Slot setting to _BaseMap instead of _MainTex, and then run the scene? I forgot that URP/HDRP seems to have a mystery _MainTex slot that doesn't do anything.



    I have plans to add new paint tools to allow scenarios like this. For example, click two points to draw a line, multiple points to draw an edge or filled polygon, etc. This is trivial to do when painting a flat surface like a whiteboard, but it's very challenging when painting a complex mesh, because the surface triangles likely don't exactly lie on the same plane as each line. One solution is to just fill each line or triangle with a series of dots like P3dHitScreen currently does, but this fails when the camera is far from the surface or when painting steep triangles. The better solution is implementing some kind of depth aware projection mapping. This is a little tricky though, and would require a new component, so I haven't had time to implement it yet. Since the next version is 2.0.0, maybe that's a good time to add it :D
     
  27. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    Darkcoder likes this.
  28. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
  29. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
    That makes it unpaintable and it replaces the albedo texture I put on the object with the paintable texture.
    upload_2020-11-11_4-34-42.png

    Can you make a video showing the initial setup of how this asset should work for existing assets in a URP project?
     
  30. Ideas966

    Ideas966

    Joined:
    Jan 21, 2013
    Posts:
    6
    Hello, I'm really enjoying this package so far. However I am trying to create a painting scene for touch-screens where the brush is slightly offset above the touch position (giving location to brush based on raycasthit with an added Y offset to the screen position of the touch). Working off the basic set-up scene I am unable to recreate this offset with the paint object, can you give me a tip on how to do this? Adjusting the offset and touch-offset values on the hitscreen component doesn't create the effect I want (especially strange to me that they are float values and not vectors?). Trying to call HandleHitRaycast directly from another script is also proving to be quite complicated because I am not confident in how to fill out all of those variables.

    In case it's not clear I want to vertically offset where the paint is made based on a touch/mouseclick screen position. So for example if I have a (0, 10) offset and I make a touch at (0, 50) on the screen I want the paint to be drawn at (0, 60). Thanks for any help!
     
    Last edited: Nov 11, 2020
  31. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I just tested out the latest version of Paint in 3D in a new URP project, and it looks like I did correctly configure the URP Lit shader's albedo texture name. Therefore, the video I posted above should work exactly the same when painting any existing URP assets.

    upload_2020-11-12_9-58-25.png

    This is a basic sphere with a material using the default URP/Lit shader, and a brick texture. If I follow the steps in the video (except clicking the StateLimit/Apply button, because that's now unnecessary), I get this result, which can then be exported to png like so:

    upload_2020-11-12_10-0-9.png


    This is what the TouchOffset value is for. The reason why it's a single value is because I didn't imagine anyone would want to horizontally offset the paint, so this is just the vertical value. The code for this looks correct:

    Code (csharp):
    1.  
    2.                 if (touchOffset != 0.0f && P3dInputManager.TouchCount > 0)
    3.                 {
    4.                     screenPosition.y += touchOffset * P3dInputManager.ScaleFactor;
    5.                 }
    As you can see, on touch devices it moves the finger up based on this value, and scales it based on ScaleFactor. This factor is based on a DPI of 200, so TouchOffset=10 will be 10 pixels on a 200DPI device. It looks like I should actually be diving this factor instead of multiplying it, but it should still work.
     
  32. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
  33. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I sent you a new build with updated presets. It looks like I had multiple entries for the URP shaders.

    Also, can you try copy+pasting one rock into a new scene and then trying to follow the paint setup steps as seen in the previous video? This will make it clear that you're not painting the wrong rock or something like this. Also, does this rock have a MeshCollider?
     
  34. Ideas966

    Ideas966

    Joined:
    Jan 21, 2013
    Posts:
    6
    Thanks for your reply to my earlier question, but now I have a new problem. I exported my game to my Iphone SE (original model from a few years ago) last night and the paintable texture I use turns completely black and constantly resets as I try to paint. It works completely fine on the editor, and my teammates who use an Iphone XS Max and Iphone XR played the build on their phone and it looked fine (no black texture).

    Further info on my implementation: using paintable textures on a transparent model to reveal the texture as paint is applied.

    Any idea what's going on and how to fix it?
     

    Attached Files:

  35. unity_bcbhh

    unity_bcbhh

    Joined:
    Feb 18, 2019
    Posts:
    5
    First of all, this is a really nice asset!
    I'm somewhat new to Unity and have a challenge with the VR Pen example.
    Everything works fine, when you press the pen in a right angle to the board.
    When doing it with an angle of say 45 degrees, the pen slides somewhat over the board when you hit it and with that you draw a unwanted segment of the line. I assume this has something with the collider stuff.
    Any hint how to avoid that is appreciated :)
     
  36. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
    Imported the new package, but still the same issue even in a new scene:

    https://gyazo.com/7b8271e57d5e622176f5a1ec36b9f824
     
  37. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Not sure. Which rendering pipeline are you using? Also, which shader is this object using? Does anything change if you change the P3dPaintableTexture settings, like turning mip maps off?


    Can you record a video of this issue? The pen is designed to allow some back movement (similar to car suspension or something), because if it's fixed it's very hard to draw on flat surfaces since there's no haptic feedback when you go through the surface.


    Did you do the "Make Paintable" etc steps after upgrading? Your view shows the P3dPaintableTexture targeting the _MainTex, but this shouldn't be possible with the last build. You can select the "PaintIn3D/Shared/Groups/Albedo (RGB) Alpha (A)" asset, and read the ShaderData list. Near the bottom this should contain "_BaseMap@Universal Render Pipeline/Lit", where "Universal Render Pipeline/Lit" should be the same shader as you're trying to make paintable. There should be no entry called "_MainTex@Universal Render Pipeline/Lit", (though in a previous version there was).
     
  38. unity_bcbhh

    unity_bcbhh

    Joined:
    Feb 18, 2019
    Posts:
    5
    Can you record a video of this issue? The pen is designed to allow some back movement (similar to car suspension or something), because if it's fixed it's very hard to draw on flat surfaces since there's no haptic feedback when you go through the surface.

    VR Pen Issue - here is a short video (little bit shaky due to recording)
     
  39. Eckhart3D

    Eckhart3D

    Joined:
    Feb 28, 2020
    Posts:
    3
    Hi,
    I bought "Paint in 3d" without being able to use it to this point. This is not a complaint, I bought it before I knew it's not HDRP compatible. I, as I said, use HDRP and I am aware that the new version is HDRP compatible but when I try it it won't work. I get everything very dark and gets progressively darker to the point of not being able to see what is going on. It probably is something I do but I have a question that I hope someone here can answer so I know should I spend my time on this system.
    My project is HDRP with graphics on 11(on scale from 1 to 10) so I think it won't be too damaging in the performance department for my project is aimed at highend PC's.
    What I want to do with "Paint in 3d" is get my character dirty on collision with certain bits of the ground and then get clean in rain or water. Is that possible with this asset in HDRP and would it brake the highend PC's performance?
     
  40. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I don't see what the issue is here. It just looks like your pen is shaking too much, and when at this angle the pen has less range, and this causes the paint tip to go in/out of range very quickly, causing it to draw dots. Inside the pen GameObject (e.g. "Marker (Red)"), you can see the "Variable Distance/Point A/B" GameObjects. You can increase the separation of these, like make PointA's position.z -0.15 or something.


    Paint in 3D should fully support all render pipelines. The issue with HDRP is that it requires custom exposure settings, otherwise everything goes dark. I can't add them to the scenes though, because this component doesn't exist in the other pipelines, so you must manually add them. It looks like I forgot to mention this in the documentation, so for now you can read THIS from my other asset, which details the required steps. I'll update the documentation and look into a way to automatically do this, sorry for the issues!
     
  41. unity_bcbhh

    unity_bcbhh

    Joined:
    Feb 18, 2019
    Posts:
    5
    The issue is that when pushing the controller in a right angle direction to the board and the pen is not pointing in a right angle but is rotated this unwanted gliding over the board is causing a unwanted line (in the video the line down at 0:15) . The dots are caused by unity recorder. When not recording the line will be drawn smooth.
     
  42. Rickmc3280

    Rickmc3280

    Joined:
    Jun 28, 2014
    Posts:
    189
    Just reading these reviews and having switched between multiple projects myself for different reasons.

    Would it be possible to create P3D in 3 primary folders?

    1)Standard
    2)URP
    3)HDRP

    Each including its own materials/setup?

    I know it in theory would be difficult to initially setup, but not necessarily to maintain. You could segment the scripts to a 4th folder (the scripts that store the backbone of p3d functionality) and add a scripts folder in each Standard/URP/HDRP folder that relies on them and additionally URP/HDRP Shaders.

    I personally dont get why Unity makes it so complicated. I think all built in materials should be universal (as they adapt to the renderpipeline in place) (if ActiveRenderPipeline == URP... etc etc )and disable features not related to them. For instance... Color and metallic is independent of render pipeline. Albedo is independent... how they are processed however are different. they could make it to where you can plugin shaders for URP/HDRP/Standard so so if you dont have a shader plugged in and not defaulting to standard shader == disabled.

    I did have issues before when switching to URP, but your advice helped me. Just wondering if a well thought out alternative would fix the problem. Maybe you could include such asset in P3D and sell it on the Asset Store for extra $$$ xD :)

    Can be simple...


    Attach This in scene as a manager.
    Code (CSharp):
    1.  
    2.  
    3. using System;
    4. using System.Collections;
    5. using System.Collections.Generic;
    6. using UnityEngine;
    7.  
    8. namespace RenderPipelineManager
    9. {
    10.     [System.Serializable]
    11.     public class RenderPipelineManager : MonoBehaviour
    12.     {
    13.         public static RenderPipelineManager main = null;
    14.         [Header("Select Which Render Pipeline(s) To Use")]
    15.         public AllowedRenderPipelines allowableRenderPipelines;
    16.  
    17.         [Header("Select Which Render Pipeline Will be Active")]
    18.  
    19.         public ActiveRenderPipeline activeRenderPipeline;
    20.         public bool UNIVERSAL_SHADER_AND_MATERIAL_REQUIRED;
    21.  
    22.         [Header("Default Materials")]
    23.         public Material Default_Standard_Mat;
    24.         public Material Default_URP_Mat;
    25.         public Material Default_HDRP_Mat;
    26.         public Material Default_Custom_Mat;
    27.  
    28.         [Header("Default Shaders")]
    29.         public Shader Default_Standard_Shader;
    30.         public Shader Default_URP_Shader;
    31.         public Shader Default_HDRP_Shader;
    32.         public Shader Default_Custom_Shader;
    33.  
    34.         [HideInInspector]
    35.         public bool canUseHDRP;
    36.         [HideInInspector]
    37.         public bool canUseURP;
    38.         [HideInInspector]
    39.         public bool canUseStandard;
    40.         [HideInInspector]
    41.         public bool canUseCustom;
    42.         [HideInInspector]
    43.         public bool changeRenderPipeline;
    44.  
    45.         void Awake()
    46.         {
    47.             if (main == null)
    48.                 main = this;
    49.             else if (main != this)
    50.                 Destroy(gameObject.GetComponent<RenderPipelineManager>());
    51.         }
    52.         private void Start()
    53.         {
    54.             if (allowableRenderPipelines == AllowedRenderPipelines.Standard_ONLY)
    55.             {
    56.                 canUseHDRP = false;
    57.                 canUseURP = false;
    58.                 canUseStandard = true;
    59.                 canUseCustom = false;
    60.                 return;
    61.             }
    62.             if (allowableRenderPipelines == AllowedRenderPipelines.URP_ONLY)
    63.             {
    64.                 canUseHDRP = false;
    65.                 canUseURP = true;
    66.                 canUseStandard = false;
    67.                 canUseCustom = false;
    68.                 return;
    69.             }
    70.             if (allowableRenderPipelines == AllowedRenderPipelines.HDRP_ONLY)
    71.             {
    72.                 canUseHDRP = true;
    73.                 canUseURP = false;
    74.                 canUseStandard = false;
    75.                 canUseCustom = false;
    76.                 return;
    77.             }
    78.             if (allowableRenderPipelines == AllowedRenderPipelines.Standard_And_URP)
    79.             {
    80.                 canUseHDRP = false;
    81.                 canUseURP = true;
    82.                 canUseStandard = true;
    83.                 canUseCustom = false;
    84.                 return;
    85.             }
    86.             if (allowableRenderPipelines == AllowedRenderPipelines.Standard_And_URP_And_HDRP)
    87.             {
    88.                 canUseHDRP = true;
    89.                 canUseURP = true;
    90.                 canUseStandard = true;
    91.                 canUseCustom = false;
    92.                 return;
    93.             }
    94.             if (allowableRenderPipelines == AllowedRenderPipelines.URP_AND_HDRP)
    95.             {
    96.                 canUseHDRP = true;
    97.                 canUseURP = true;
    98.                 canUseStandard = false;
    99.                 canUseCustom = false;
    100.                 return;
    101.             }
    102.             if (allowableRenderPipelines == AllowedRenderPipelines.Standard_AND_HDRP)
    103.             {
    104.                 canUseHDRP = true;
    105.                 canUseURP = false;
    106.                 canUseStandard = true;
    107.                 canUseCustom = false;
    108.                 return;
    109.             }
    110.             else
    111.             {
    112.                 allowableRenderPipelines = AllowedRenderPipelines.Standard_ONLY;
    113.                 canUseHDRP = false;
    114.                 canUseURP = false;
    115.                 canUseStandard = true;
    116.                 canUseCustom = false;
    117.             }
    118.         }
    119.  
    120.         public void UpdateActivePipelineTo(ActiveRenderPipeline changeTo)
    121.         {
    122.             ActiveRenderPipeline previous = activeRenderPipeline;
    123.  
    124.             if (changeTo == activeRenderPipeline)
    125.             {
    126.                 changeRenderPipeline = false;
    127.                 return;
    128.             }
    129.             if (changeTo == ActiveRenderPipeline.Custom && canUseCustom == true)
    130.             {
    131.                 changeRenderPipeline = true;
    132.                 activeRenderPipeline = ActiveRenderPipeline.Custom;
    133.                 return;
    134.             }
    135.             if (changeTo == ActiveRenderPipeline.HDRP && canUseHDRP == true)
    136.             {
    137.                 changeRenderPipeline = true;
    138.                 activeRenderPipeline = ActiveRenderPipeline.HDRP;
    139.                 return;
    140.             }
    141.             if (changeTo == ActiveRenderPipeline.URP && canUseURP == true)
    142.             {
    143.                 changeRenderPipeline = true;
    144.                 activeRenderPipeline = ActiveRenderPipeline.URP;
    145.                 return;
    146.             }
    147.             else
    148.             {
    149.                 changeRenderPipeline = true;
    150.                 activeRenderPipeline = ActiveRenderPipeline.Standard;
    151.             }
    152.         }
    153.  
    154.         public void UpdateAssetsInScene()
    155.         {
    156.             UniversalRender[] AllUniversalRender = FindObjectsOfType(typeof(UniversalRender)) as UniversalRender[];
    157.             if (activeRenderPipeline == ActiveRenderPipeline.Standard)
    158.             {
    159.                 foreach (UniversalRender UR in AllUniversalRender)
    160.                 {
    161.                     UR.Make_Material_Standard();
    162.                     UR.Make_Shader_Standard();
    163.                 }
    164.                 return;
    165.             }
    166.             if (activeRenderPipeline == ActiveRenderPipeline.URP)
    167.             {
    168.                 foreach (UniversalRender UR in AllUniversalRender)
    169.                 {
    170.                     UR.Make_Material_URP();
    171.                     UR.Make_Shader_URP();
    172.                 }
    173.                 return;
    174.             }
    175.             if (activeRenderPipeline == ActiveRenderPipeline.HDRP)
    176.             {
    177.                 foreach (UniversalRender UR in AllUniversalRender)
    178.                 {
    179.                     UR.Make_Material_HDRP();
    180.                     UR.Make_Shader_HDRP();
    181.                 }
    182.                 return;
    183.             }
    184.             if (activeRenderPipeline == ActiveRenderPipeline.Custom)
    185.             {
    186.                 foreach (UniversalRender UR in AllUniversalRender)
    187.                 {
    188.                     UR.Make_Material_Custom();
    189.                     UR.Make_Shader_Custom();
    190.                 }
    191.                 return;
    192.             }
    193.  
    194.             //UniversalShader[] AllShaders = FindObjectsOfType(typeof(UniversalShader)) as UniversalShader[];
    195.             //UniversalMaterial[] AllMaterials = FindObjectsOfType(typeof(UniversalMaterial)) as UniversalMaterial[];
    196.             //foreach (UniversalShader shade in AllShaders)
    197.             //{
    198.             //    UpdateShader(shade);
    199.             //}
    200.             //foreach (UniversalMaterial mat in AllMaterials)
    201.             //{
    202.             //    UpdateMaterial(mat);
    203.             //}
    204.             if (UNIVERSAL_SHADER_AND_MATERIAL_REQUIRED == false)
    205.             {
    206.                 UpdateMesh();
    207.             }
    208.         }
    209.  
    210.         public void UpdateMesh()
    211.         {
    212.         }
    213.  
    214.      
    215.      
    216.     }
    217.  
    218.     [System.Serializable]
    219.     public enum AllowedRenderPipelines
    220.     {
    221.         Standard_ONLY = 1,
    222.         URP_ONLY = 2,
    223.         HDRP_ONLY = 3,
    224.  
    225.         Standard_And_URP = 4,
    226.         Standard_And_URP_And_HDRP = 5,
    227.         URP_AND_HDRP = 6,
    228.         Standard_AND_HDRP = 7,
    229.  
    230.     }
    231.     [System.Serializable]
    232.     public enum ActiveRenderPipeline
    233.     {
    234.         Standard = 1,
    235.         URP = 2,
    236.         HDRP = 3,
    237.         Custom = 4
    238.     }
    239.  
    240. }
    241.  
    242.  
    243.  

    ** Attach this to game objects that have materials and shaders (should probably add something like requires material/ or whatever).

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. namespace RenderPipelineManager
    7. {
    8.     public class UniversalRender : MonoBehaviour
    9.     {
    10.         public bool wasInitiated = false;
    11.  
    12.         public Material Active_Material;
    13.         public Material standard_Material;
    14.         public Material uRP_Material;
    15.         public Material hDRP_Material;
    16.         public Material custom_Material;
    17.  
    18.         public Shader Active_Shader;
    19.         public Shader standard_Shader;
    20.         public Shader uRP_Shader;
    21.         public Shader hDRP_Shader;
    22.         public Shader custom_Shader;
    23.  
    24.         public UniversalRender()
    25.         {
    26.         }
    27.         private void Start()
    28.         {
    29.             if (RenderPipelineManager.main != null)
    30.             {
    31.                 Initiate();
    32.             }
    33.         }
    34.  
    35.         public void Initiate()
    36.         {
    37.             if (ShaderIsNull(standard_Shader) == true && RenderPipelineManager.main.canUseStandard == true) standard_Shader = RenderPipelineManager.main.Default_Standard_Shader;
    38.             if (ShaderIsNull(uRP_Shader) == true && RenderPipelineManager.main.canUseURP == true) uRP_Shader = RenderPipelineManager.main.Default_Standard_Shader;
    39.             if (ShaderIsNull(hDRP_Shader) == true && RenderPipelineManager.main.canUseHDRP == true) hDRP_Shader = RenderPipelineManager.main.Default_Standard_Shader;
    40.             if (ShaderIsNull(custom_Shader) == true && RenderPipelineManager.main.canUseCustom == true) custom_Shader = RenderPipelineManager.main.Default_Standard_Shader;
    41.  
    42.             if (MaterialIsNull(standard_Material) && RenderPipelineManager.main.canUseStandard == true) standard_Material = RenderPipelineManager.main.Default_Standard_Mat;
    43.             if (MaterialIsNull(uRP_Material) && RenderPipelineManager.main.canUseURP == true) uRP_Material = RenderPipelineManager.main.Default_Standard_Mat;
    44.             if (MaterialIsNull(hDRP_Material) && RenderPipelineManager.main.canUseHDRP == true) hDRP_Material = RenderPipelineManager.main.Default_Standard_Mat;
    45.             if (MaterialIsNull(custom_Material) && RenderPipelineManager.main.canUseCustom == true) custom_Material = RenderPipelineManager.main.Default_Standard_Mat;
    46.             wasInitiated = true;
    47.         }
    48.  
    49.         public void Make_Shader_Standard()
    50.         {
    51.             if (wasInitiated == false) Initiate();
    52.             Active_Shader = standard_Shader;
    53.             gameObject.GetComponent<MeshRenderer>().material.shader = Active_Shader;
    54.         }
    55.         public void Make_Shader_URP()
    56.         {
    57.             if (wasInitiated == false) Initiate();
    58.             Active_Shader = uRP_Shader;
    59.             gameObject.GetComponent<MeshRenderer>().material.shader = Active_Shader;
    60.         }
    61.         public void Make_Shader_HDRP()
    62.         {
    63.             if (wasInitiated == false) Initiate();
    64.             Active_Shader = hDRP_Shader;
    65.             gameObject.GetComponent<MeshRenderer>().material.shader = Active_Shader;
    66.         }
    67.         public void Make_Shader_Custom()
    68.         {
    69.             if (wasInitiated == false) Initiate();
    70.             Active_Shader = custom_Shader;
    71.             gameObject.GetComponent<MeshRenderer>().material.shader = Active_Shader;
    72.         }
    73.  
    74.         public void Make_Material_Standard()
    75.         {
    76.             if (wasInitiated == false) Initiate();
    77.             Active_Material = standard_Material;
    78.             gameObject.GetComponent<MeshRenderer>().material = Active_Material;
    79.         }
    80.         public void Make_Material_URP()
    81.         {
    82.             if (wasInitiated == false) Initiate();
    83.             Active_Material = uRP_Material;
    84.             gameObject.GetComponent<MeshRenderer>().material = Active_Material;
    85.         }
    86.         public void Make_Material_HDRP()
    87.         {
    88.             if (wasInitiated == false) Initiate();
    89.             Active_Material = hDRP_Material;
    90.             gameObject.GetComponent<MeshRenderer>().material = Active_Material;
    91.         }
    92.         public void Make_Material_Custom()
    93.         {
    94.             if (wasInitiated == false) Initiate();
    95.             Active_Material = custom_Material;
    96.             gameObject.GetComponent<MeshRenderer>().material = Active_Material;
    97.         }
    98.  
    99.         public bool ShaderIsNull(Shader input)
    100.         {
    101.             return (input);
    102.         }
    103.         public bool MaterialIsNull(Material input)
    104.         {
    105.             return (input);
    106.         }
    107.  
    108.     }
    109. }
    110.  
    111.  
    112.  
    Edited code on my end, im forgetting something to show the public enums. Will have to update when fix. But that is how I envision it working to be able to swap between render pipelines /materials. I know your edit mode one works similarly. But could add this in all scenes to handle discrepancies Or something of the likes. Could attach the 2nd set of code to an object and give it a material /shader for each render mode and push updates as needed (edit/play mode).

    Would have to add a disable function somewhere in the mix to blank out the scene and disable objects to swap out. Could further edit for editing in edit mode. Just threw it together real quick.

    Edit to add:

    Or you could attach this type of system to all objects and tie it into yours. Use the system to setup the p3d materials and shaders and when user is comfortable with setup they can remove all extra associations by removing these components. The manager removes all of the UniversalRender scripts and then the editor removes the manager script from the scene.
     
    Last edited: Nov 15, 2020
  43. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
    I followed the steps but still the same thing - the camera moves, but there is no paint capability. I looked at the asset you mentioned, but it doesn't have the Universal Render Pipeline/Lit option you mention.
    upload_2020-11-14_20-0-31.png

    I'm running the latest version you sent me, by the way.
     
  44. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    I'm still not understanding the issue. The Paint Tip for each pen is set up to 'ConnectHits', which will draw lines between the previous and current hit point. You can disable this if you wish.


    I don't really want to have to think about render pipelines, as it's too much of a headache for asset developers. I'm happy with my current solution, because I only have to make a Shader Graph version of each lit shader, and as long as the shader properties are the same then it will automatically work with my conversion tool. The only thing left is making the HDRP exposure settings auto generate, but this can easily enough be done using a prefab with this setup. Some developers make separate folders and packages or even assets to support this, but that isn't really worth my time.


    This list has about 100 entries, you can copy+paste it into notepad to see everything. the URP/Lit entry should be near the bottom.
     
  45. Exeneva

    Exeneva

    Joined:
    Dec 7, 2013
    Posts:
    432
  46. WJLIDDY

    WJLIDDY

    Joined:
    Aug 31, 2017
    Posts:
    6
    Hey Darkcoder, I have been using paint in 3d for the better part of a year now and it's been performing wonderfully. Great job.

    In the version I used initially (1.7.9) There appeared to be some bugs with UndoAll() so i upgraded to the latest version (1.9.9) and I'm getting this error when I try to compile. Any ideas? upload_2020-11-16_21-58-21.png
     
  47. unity_bcbhh

    unity_bcbhh

    Joined:
    Feb 18, 2019
    Posts:
    5
    The problem is, that the pen moves downwards unintentionally although pushed straight towards the board, but just rotated/angled as shown.
    Maybe I should draw a sketch with forces and angles visible?

    Just try it as shown to reproduce the issue.
     
    Last edited: Nov 17, 2020
  48. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Your setup looks correct now. Strange that painting doesn't work. Can you send me a private message with package of this exact scene + mesh + material, so I can test it myself?


    It depends what your custom 'SetupDrawPrefabs' script is trying to do. You can look at the code for P3dPaintableTexture.Undo/Redo to see what is being done now. What was called State and StateType is now UndoRedo and UndoRedoType.

    Oh I see. Well, that's how the pen is designed to work, like the car suspension analogy I made earlier. The pen works similar to a laser beam that fires from behind the VR controller hand (e.g. 10cm back), and to the hand, and it will paint the first surface it hits along this line. Therefore if you hold the controller at 45 degrees and push it in, this 45 degree line will penetrate at a different point starting at the tip and ending at the back position. This will appear as though the paint/hit point is moving down, but that's not really what's happening.

    To make it not 'move down', this system would have to be replaced with one that instead detects when the virtual line is going through the wall/board, and then raycast back using the hit normal to try and find the surface directly under the tip. In this whiteboard scenario such a system would work well, but if you need to paint more complex surfaces I imagine there would be issues. Can't you just tilt the pen 45 degrees to minimize the issue?
     
  49. WJLIDDY

    WJLIDDY

    Joined:
    Aug 31, 2017
    Posts:
    6
    > What was called State and StateType is now UndoRedo and UndoRedoType.
    Thank you very much! That fixed it.

    I think I found another error when upgrading from 1.7.9 to 1.9.9, my p3d clone mirror doesn't work anymore. I've attached a video showing what happens with "flip" being toggled. This worked fine before I upgraded.
     
  50. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    Does the "21 Mirror" demo scene work for you? If so, let me know what modifications to this are required to replicate what's seen in your scene.