Search Unity

UI and masking 3d meshes in a scrollrect

Discussion in 'UGUI & TextMesh Pro' started by saarwii, Oct 1, 2015.

  1. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    So I am basically trying to do this http://answers.unity3d.com/questions/998203/mask-3d-objects-inside-ui-scrollrect.html....i have scrollrect with buttons and each button has a different 3d object on it to represent what the button do. But so far I have not been successful in masking out the 3d objects. I have messed around with render texture, but i have not found a good solution. I dont want to set up a stage where i film the 3d object in the right size and to project them on to the buttons with a render texture. Is there away to mask out the object with a shader? The objects i am using aare just using the standard shader, can i modify it to support stenciling ( dont have a full grasp on what stenciling is or does, I have just come across the term alot in my googling on the subject)
     
    bakhshmk likes this.
  2. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    Hi.

    You need to do a tiny big of scripting for this to work. Basically create a UI element that uses this mesh.

    Something like this:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4.  
    5. [RequireComponent(typeof(CanvasRenderer))]
    6. [ExecuteInEditMode]
    7. public class SetMeshMaterials : MonoBehaviour
    8. {
    9.     public Mesh TheMesh;
    10.     public List<Material> Materials;
    11.  
    12.     void ResetData ()
    13.     {
    14.         var cr = GetComponent<CanvasRenderer>();
    15.         cr.SetMesh (TheMesh);
    16.         cr.materialCount = Materials.Count;
    17.  
    18.         for (int i = 0; i < Materials.Count; i++)
    19.             cr.SetMaterial (Materials[i], i);
    20.     }
    21.  
    22.     void OnEnable()
    23.     {
    24.         ResetData();
    25.     }
    26.  
    27.     void OnValidate()
    28.     {
    29.         ResetData();
    30.     }
    31. }
    32.  
    33.  
    This will not work for screen space overlay canvas with the standard shader as no lighting happens. You need either a screen space overlay or world canvas.
     
    bakhshmk likes this.
  3. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    Thx for the answer, but i cant get it to work. TheMesh and Materials are never asigned with the objects mesh or materials. Do i have to add som code that refers to the current object?

    something like

    Code (CSharp):
    1. Void Start(){
    2. TheMesh = this.GetComponent<Meshfilter>().mesh;
    3. }
     
  4. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    But i could not get that to work either so i guess i am doing something wrong
     
  5. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    So i created a empty game object, added yout script and then draged the mesh from assets folder and the materials from them on to i, but it still dont mask them. So i i am pretty lost here now :)
     
  6. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    Ohhh yeah a shader modification is also needed... On phone right now will get back to you :)
     
  7. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    I think I just had a lightbulb moment on what that actually means @Tim C with the update to use meshes with the new UI.
    Basically, any mesh would be hostable on a UI canvas, by either reading it's mesh data, or manipulating with with techniques such as the above. Interesting....
    Looking forward to your shader update.
     
  8. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    Im so freaking excited now! I havet been messing around with the standard shader, trying to add stenceling to it...but shaders is not my strong suite
     
  9. saarwii

    saarwii

    Joined:
    Mar 7, 2014
    Posts:
    24
    Any news on this issue?
     
  10. townbully

    townbully

    Joined:
    May 24, 2014
    Posts:
    2
    Did this ever get worked out? I've tried using the scripts in this thread along with using a UI shader, but no luck. Masking is ignored for a cube, for example, placed in the content area of a scrollrect.
     
  11. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Yo @Tim C any thoughts on the shader?
    Just put a proposal in the UI Extensions project for this. Might whip up the basic control quickly myself using the above example, if you could provide your shader godness :D
     
  12. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Just realised as @Tim C has moved off the project, he might not be the right person to ask.
    @phil-Unity any chance you can fill in the gap here as it seems a very useful approach?
     
  13. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Unfortunately at this time i'm not 100% sure let me talk with Tim and figure something out as i dont know what he had in mind for this.
     
    SimonDarksideJ likes this.
  14. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Thanks @phil-Unity Eagerly waiting a response on this as it would be very useful.
     
  15. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Quick poke for the new year @phil-Unity any further thoughts on advancing this?
    Tried a few combinations to manipulate / display the mesh but it does seem some shader magic is required.
     
  16. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Need to get a hold of Tim which didnt happen yet i'll poke him now but hes away till the 11th.
     
    SimonDarksideJ likes this.
  17. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    No worries, thanks for the update Phil
     
  18. townbully

    townbully

    Joined:
    May 24, 2014
    Posts:
    2
  19. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Happy new year team, any update on this request @phil-Unity ?
    Hoping we can get through this quickly now in the new year as this would be an awesome boost to the UI system if we can get it working with the mesh data.

    Did you manage to get hold of @Tim C 's brain and dissect his ideas ? :D
     
  20. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
  21. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Hey so i got a shader from Tim thought not sure its been fully tested but i'm sure you guys will tell us if anything is wrong.
     

    Attached Files:

    Noisecrime and eses like this.
  22. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    WhoooHooo @phil-Unity I'll give that a whirl. Thanks.
    Will run this through the UI Extensions controls I had lined up for this and let you know. Thanks for chasing this down.
     
  23. seansteezy

    seansteezy

    Joined:
    Nov 28, 2013
    Posts:
    122
    Anyone get this working with that shader? I think I am close... got the shader, applying to all mesh & shaders, still not masking tho.
     
  24. seansteezy

    seansteezy

    Joined:
    Nov 28, 2013
    Posts:
    122
    Correction - it's working but in reverse... showing up outside the mask and not within it.... any thoughts?
     
  25. horkyze

    horkyze

    Joined:
    Sep 21, 2012
    Posts:
    4
    @seansteezy Hi, how did you got it working (even in reverse)? Im stuck, canvas images just occlude the mesh
     
  26. seansteezy

    seansteezy

    Joined:
    Nov 28, 2013
    Posts:
    122
    It seems to show up way below the rendering canvas, but I have my main cam, and UI is set to screen space camera, with the plane at 5. For each object in my menu (scroll rect -> grid layout -> menu item prefab -> ui -> 3d object), they have a modified mesh script attached (from the above) that will find one of the meshes in the child menu object and change its shader to the one provided above. While it doesn't look particularly good, it does show up outside the clipping mask, but doesn't show up within it, when that shader is applied to the game objects.
     
  27. horkyze

    horkyze

    Joined:
    Sep 21, 2012
    Posts:
    4
    Yup same here, but can you please test to remove all clipping masks? I dont have any and still the images in canvas are occluding that mesh. So then the problem would be not clipping but mesh drawn too early? (Btw: when you set ZWrite On in shader the mesh will pop above, but still no clipping works)
     
  28. seansteezy

    seansteezy

    Joined:
    Nov 28, 2013
    Posts:
    122
    That may be a z value or layer/cam clipping issue. I had probs with my camera near clipping plane, it was clipping my models, even though it was at 10 and the ui was at 0.
     
  29. horkyze

    horkyze

    Joined:
    Sep 21, 2012
    Posts:
    4
    Code (CSharp):
    1. Stencil
    2. {
    3.     Ref 1
    4.     Comp LEqual
    5.     Pass Keep
    6.     ReadMask [_StencilReadMask]
    7.     WriteMask [_StencilWriteMask]
    8. }

    This stencil settings solved the inversion problem for me :). Hope it will help you too

    Edit: Oh and i forgot you haveto set SubShader tags as
    Code (CSharp):
    1. Tags { "RenderType"="UI""Queue"="Transparent" }
     
    Last edited: Sep 26, 2016
  30. Allen0012

    Allen0012

    Joined:
    Sep 5, 2009
    Posts:
    93
    How lucky am I? Finding this one day after it got figured out after almost a year.
    Great job everyone, this should be part of next Unity update.



    I attached everything you need to get this working. Remember to set the Canvas Render Mode to "Screen Space - Camera".
     

    Attached Files:

  31. cstlmode

    cstlmode

    Joined:
    Dec 2, 2014
    Posts:
    88
    i can"t get this to work , sorry guys i'm an artist trying to learn programming , and i need to get this to work for my project ,
    what i have is skinnedmesh , a character with some IDLE animation and turning around in a loop
    i have done a small modification to the c# code in order to adapt it to the skinned mesh ,i have multiple materials on the character, i attache the UI3DMesh script to the Mask , when i try to change the size of the materials array, unity crashs ,

    PS :i have applied the shader provided to all the sub materials of the skinned mesh

    please help know if i'm doing this the right way
    thanx

    my modified script
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. [RequireComponent(typeof(CanvasRenderer))]
    4. [ExecuteInEditMode]
    5. public class UI3DMesh : MonoBehaviour
    6. {
    7.     public  Mesh TheMesh;
    8.     public SkinnedMeshRenderer Frank;
    9.     public List<Material> Materials;
    10.     void ResetData ()
    11.     {
    12.         var cr = GetComponent<CanvasRenderer>();
    13.         TheMesh= Frank.sharedMesh;
    14.         cr.SetMesh (TheMesh);
    15.         cr.materialCount = Materials.Count;
    16.         for (int i = 0; i < Materials.Count; i++)
    17.             cr.SetMaterial (Materials[i], i);
    18.     }
    19.     void OnEnable()
    20.     {
    21.         ResetData();
    22.     }
    23.     void OnValidate()
    24.     {
    25.         ResetData();
    26.     }
    27. }
     
    Last edited: Dec 24, 2016
  32. TechDevTom

    TechDevTom

    Joined:
    Oct 21, 2011
    Posts:
    33
    Thanks for all the info that you've posted here guys! It's super helpful. I've modified the script slightly so that you don't need to constantly assign the script that was put up on here by Allen0012. All you need to do now is use the shader and material provided in Allen0012's zip file and place my modified script on a GameObject.

    In the inspector you'll be able to see a list of MeshFilters on the script. Fill that up with all of the GameObjects/Meshes you want to hide in a Mask in Unity's UI and make sure that all of the GameObjects with the MeshFilters on have CanvasRenderer components too and are parented within a UI Canvas.

    Here's the script:


    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. using System.Collections.Generic;
    4. using System.Reflection;
    5. using System.Linq;
    6.  
    7.  
    8. // 3D Masking Original Script from:  https://forum.unity3d.com/threads/ui-and-masking-3d-meshes-in-a-scrollrect.358475/
    9. [ExecuteInEditMode]
    10. public class UI3DMesh : MonoBehaviour
    11. {
    12.     public List <MeshFilter>    meshFilters = new List <MeshFilter> ();
    13.  
    14.     void ResetData ()
    15.     {
    16.         meshFilters.ForEach (delegate (MeshFilter meshFilter)
    17.         {
    18.             var cr = meshFilter.transform.GetComponent <CanvasRenderer> ();
    19.             cr.SetMesh (meshFilter.sharedMesh);
    20.  
    21.             List <Material> materials = meshFilter.transform.GetComponent <Renderer> ().sharedMaterials.ToList ();
    22.  
    23.             for (int i = 0; i < materials.Count; i++)
    24.             {
    25.                 cr.materialCount = materials.Count;
    26.                 cr.SetMaterial  (materials[i], i);
    27.             }
    28.         });
    29.     }
    30.  
    31.     void OnEnable()
    32.     {
    33.         ResetData();
    34.     }
    35.  
    36.     void OnValidate()
    37.     {
    38.         ResetData();
    39.     }
    40. }
     
  33. zero_null

    zero_null

    Joined:
    Mar 11, 2014
    Posts:
    159
    Guys is it still been worked on ???
     
  34. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    @TSLoire do you have an example scene with your approach. Doesn't seem to work or I'm not configuring it correctly

    *Edit, ok, got a mesh renderering but with no materials and looks more like a shadow that a mesh.

    *Edit 2, scratch that. You have to play with the new "Shader Channels" option on the canvas for it to recognise it properly. Scaling is awful though, as meshes in the canvas are scaled right down.

    *Edit 3. Completely scratch that. Seems the UI Canvas system does indeed support 3D objects natively now and the script wasn't actually doing anything.
     
    Last edited: Jul 11, 2017
  35. TechDevTom

    TechDevTom

    Joined:
    Oct 21, 2011
    Posts:
    33
    Hey Simon, did you get it fixed then? What version of Unity are you using? I think in the end I used a different approach, but it seemed to be working fine for me. If you still need a scene I can probably get you one at some point today. Is this kind of thing actually native to Unity?

    Edit 1: It doesn't seem to work for me now. I'm not sure why... If you want I can take a look into it. I haven't worked on the project I was using it in for a while now, so it might take a bit of head scratching. I think I might have ended up just using the DepthMask shader to hide certain 3D elements when they went past a certain boundary and changed the RenderQueue value on meshes.
     
    Last edited: Jul 20, 2017
  36. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    If you note from my last comment @TSLoire , 3D mesh rendering is not natively supported by the UI system (provided you enable a Light and use either SS-Camera or worldspace canvas.
    Although, you may note the scale is really small on a worldspace canvas :S
     
  37. Magic73

    Magic73

    Joined:
    Jun 23, 2015
    Posts:
    132
    I'm also interested!
     
  38. Vixxd

    Vixxd

    Joined:
    Jul 25, 2016
    Posts:
    11
    HI @Allen0012, I can't get the sample you provided to work - do you happen to have the scene/project still? Trying to get this to work is the bane of my existence.
     
  39. mcaisw

    mcaisw

    Joined:
    Aug 15, 2017
    Posts:
    7
    follow this question
     
  40. CrazyApplesStudio

    CrazyApplesStudio

    Joined:
    Jan 18, 2018
    Posts:
    25
    I need this to work and it doesn't, i have a ScrollView on a SS Camera Canvas and the mask masks all the 2D elements but not my 3D objects.
     
    LeekAndRibs likes this.
  41. MODev

    MODev

    Joined:
    Jul 30, 2013
    Posts:
    229
    Guys wouldn't be easier for you to just use tool like this? https://www.assetstore.unity3d.com/en/#!/content/109573
    As I understood you are looking for GUI clipping solution for 3D objects, best with some UI depth support. If you don't want to buy something like this you can make custom shader which records to depth/culling mask elements in gui (it's easy because screen space position will be screen space position of your 3D object) and in another 3D mesh use shader which maps in world space the culling mask.You can look at guide below to see how it behaves (tool has just more options but basic version would look like as I described).

     
  42. shan1991

    shan1991

    Joined:
    Sep 30, 2016
    Posts:
    1
    Hey Guys, I am the same issue but I add the Shader which is provided above. Masking is done but I face the issue is that this does not load the texture that's why my model show white color as shown in below image.
    Thanks
     

    Attached Files:

  43. Deleted User

    Deleted User

    Guest

    Could you upgrade this shader to work in LWSP :D ?
     
  44. Sparkline

    Sparkline

    Joined:
    Feb 8, 2013
    Posts:
    121
    Just tried this solution in Unity 2018.2.11 and it is not working( 3D mesh just becomes invisible. Can someone help?
     
  45. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    We're trying to do the same but anything listed here isn't working at all. When the Stencil Read Mask is 255 the mesh is invisible, any value below that it is visible.
    But the 3D mesh won't get masked by the UI mask or rect 2d mask.

    Using Unity 2018.4.x LTS currently, any solutions?
     
    anattress likes this.
  46. mige5

    mige5

    Joined:
    Oct 20, 2017
    Posts:
    16
    Got this working, but the shader has different lighting as unlit/texture shader. - so any1 able to tell me how can I change the lighting in this shader to same as unlit/texture?
     
  47. SpruceMooseGames

    SpruceMooseGames

    Joined:
    Feb 12, 2020
    Posts:
    1
    I may have found a quick solution to this by setting the 3D objects shader as the
    TextMeshPro/Sprite
     
  48. mertzorlular95

    mertzorlular95

    Joined:
    Sep 11, 2019
    Posts:
    3
    I know it's a bit late but, I managed to get it work but as you can see in the image, masked object is not like the original one. Shadows are not working. Can anyone identify the probem?

    My shader code is here;
    Code (CSharp):
    1. Shader "Custom/NewSurfaceShader" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    5.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    6.         _Metallic ("Metallic", Range(0,1)) = 0.0
    7.  
    8.  
    9.         _StencilComp("Stencil Comparison", Float) = 8
    10.         _Stencil("Stencil ID", Float) = 0
    11.         _StencilOp("Stencil Operation", Float) = 0
    12.         _StencilWriteMask("Stencil Write Mask", Float) = 255
    13.         _StencilReadMask("Stencil Read Mask", Float) = 255
    14.  
    15.         _ColorMask("Color Mask", Float) = 15
    16.  
    17.         [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip("Use Alpha Clip", Float) = 0
    18.     }
    19.  
    20.     SubShader
    21.     {
    22.         Tags { "RenderType"="Opaque""Queue"="Transparent"}
    23.         LOD 200
    24.         ZWrite On
    25.         ZTest[unity_GUIZTestMode]
    26.         Blend SrcAlpha OneMinusSrcAlpha
    27.         ColorMask[_ColorMask]
    28.  
    29.        
    30.         Stencil
    31.         {
    32.             Ref 1
    33.             Comp LEqual
    34.             Pass Keep
    35.             ReadMask [_StencilReadMask]
    36.             WriteMask [_StencilWriteMask]
    37.         }
    38.  
    39.         CGPROGRAM
    40.         // Physically based Standard lighting model, and enable shadows on all light types
    41.         #pragma surface surf Standard vertex:vert fullforwardshadows
    42.         // Use shader model 3.0 target, to get nicer looking lighting
    43.         #pragma target 3.0
    44.  
    45.         #include "UnityUI.cginc"
    46.            
    47.         struct Input
    48.         {
    49.             float2 uv_MainTex;
    50.             float4 worldPosition;
    51.         };
    52.  
    53.         void vert(inout appdata_full v, out Input o)
    54.         {
    55.             UNITY_INITIALIZE_OUTPUT(Input, o);
    56.             o.worldPosition = v.vertex;
    57.         }
    58.        
    59.  
    60.         sampler2D _MainTex;
    61.         half _Glossiness;
    62.         half _Metallic;
    63.         fixed4 _Color;
    64.         // float4 _ClipRect;
    65.  
    66.         void surf (Input IN, inout SurfaceOutputStandard o) {
    67.             // Albedo comes from a texture tinted by color
    68.             // fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    69.             fixed4 c = _Color;
    70.             o.Albedo = c.rgb;
    71.             // Metallic and smoothness come from slider variables
    72.             o.Metallic = _Metallic;
    73.             o.Smoothness = _Glossiness;
    74.             o.Alpha = c.a;
    75.             // o.Alpha *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
    76.            
    77.             #ifdef UNITY_UI_ALPHACLIP
    78.             clip(o.Alpha - 0.001);
    79.             #endif
    80.         }
    81.         ENDCG
    82.     }
    83.     FallBack "Diffuse"
    84. }
     

    Attached Files:

    • test.png
      test.png
      File size:
      44.7 KB
      Views:
      635
  49. stevencr4z

    stevencr4z

    Joined:
    Jul 2, 2020
    Posts:
    5
    I've tried every solution here trying to get this to work with URP. Will Unity ever make this a default feature? I don't even know any good workarounds for this.
     
    berkeicel, Lynxed and HEATH3N like this.
  50. Lynxed

    Lynxed

    Joined:
    Dec 9, 2012
    Posts:
    121
    This is preposterous. 5 years of this thread and no stable solution exists. I've tried everything here (except using TMPro - i need custom shader).