Author Topic: Render panel over 3d object?  (Read 4630 times)

numpy

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 7
    • View Profile
Render panel over 3d object?
« on: January 25, 2015, 10:47:00 PM »
I'm using a Scroll View which consists of a Grid. Each grid item has a 3d mesh as one of its children. The mesh is rendering fine and moving properly when the Scroll View is scrolled. However, the 3d mesh stays rendered on top of panels which have a higher depth than it.

Here's a gif illustrating what I mean (the 3d mesh is the computer):


What do I need to configure so that the 3d object is clipped by the other NGUI elements like everything else is?

numpy

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: Render panel over 3d object?
« Reply #1 on: January 26, 2015, 12:47:10 AM »
I managed to get this working with the shader and class here: http://www.tasharen.com/forum/index.php?topic=10223.msg48057#msg48057

I had quite a bit of trouble figuring out how to do this, but as far as I can tell there are two approaches:

- Use Unity's RenderTexture. You can setup a hidden camera and have it render to a UITexture. This requires Unity Pro though. I found a hack (https://www.reddit.com/r/Unity3D/comments/2hljz5/) which lets you do something similar in Unity Free, but it is not nearly as optimized and may not be well-suited for this problem.
- Use a clipping shader (which is what I ended up doing).

I set my 3D object's material to use this UI/ClippedUnlitModel shader. Then I attached the ClippedModel class to the object. I made sure the closest UIPanel (which was the Scroll View) to the object had its Clipping property set to "Soft Clip". Then I put my 3D object on another layer and setup another camera to render only that layer.

Here is how I did it in more detail: http://spaceandtim.es/posts/clipping-3d-objects-in-ngui

pretender

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 155
    • View Profile
Re: Render panel over 3d object?
« Reply #2 on: January 26, 2015, 03:42:30 AM »
Hey, thanks man for this neat explanation! Finally somebody to sort it out!
I managed to get it working, except the part with separate camera. I am not sure how do you mean that you "position camera appropriately"? Does it need to match UI camera? and is this possible with perspective camera?

Thanks again!

numpy

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: Render panel over 3d object?
« Reply #3 on: January 26, 2015, 10:21:41 AM »
For positioning the camera, I just mean positioning it so that the 3d object is in view. You may need to fiddle with the Z position to get it to show up properly. I haven't tried it with a perspective camera but I can't see why it wouldn't work.

r.pedra

  • Full Member
  • ***
  • Thank You
  • -Given: 7
  • -Receive: 20
  • Posts: 131
    • View Profile
Re: Render panel over 3d object?
« Reply #4 on: January 27, 2015, 06:43:05 AM »
You could have modified the RenderQueue of the 3D Object with a script to put in between your widget and the yellow rectangle.

For example if your panel have a starting renderqueue of 3000 (you can see it by clicking on the drawcall button on the panel), if your widget have a depth of 1 and the yellow rectangle a depth of 3, if you specify the RenderQueue of the 3D Object to 3002, it should be behind the yellow rectangle. We used it very often in our project to use Particles between widgets layers.

numpy

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: Render panel over 3d object?
« Reply #5 on: January 30, 2015, 11:20:42 AM »
Thank you r.pedra - I just tried the approach you suggested, and after some fiddling with it, it works wonderfully. I started running into a few issues with the shader approach (in particular, I was using alpha overlays and the models would always render on top), but using render queues resolved everything.

I just used the following script (taken from http://www.tasharen.com/forum/index.php?topic=776.msg34546#msg34546), attached them to my 3D models (instead of the ClippedModel.cs script) and set their shaders back to Self-Illumin/Diffuse and put them back on the PlayArea layer. Then I made it so that I set the UIPanels that should be under the 3D objects to have their "Render Q" property be "Start At 3000" and the UIPanels that should above to have their "Render Q" property be "Start At 5000". Then, using the script below, I set my 3D objects' Render Queues to be 4000 (you will probably have to tweak the values for your own particular use case).

  1. using UnityEngine;
  2.  
  3. public class SetRenderQueue : MonoBehaviour
  4. {
  5.     public int renderQueue = 3000;
  6.  
  7.     Material mMat;
  8.  
  9.     void Start ()
  10.     {
  11.         Renderer ren = renderer;
  12.  
  13.         if (ren == null)
  14.         {
  15.             ParticleSystem sys = GetComponent<ParticleSystem>();
  16.             if (sys != null) ren = sys.renderer;
  17.         }
  18.  
  19.         if (ren != null)
  20.         {
  21.             mMat = new Material(ren.sharedMaterial);
  22.             mMat.renderQueue = renderQueue;
  23.             ren.material = mMat;
  24.         }
  25.     }
  26.  
  27.     void OnDestroy () { if (mMat != null) Destroy(mMat); }
  28. }
  29.