Search Unity

Question URP Cross section with plane/cube shader

Discussion in 'Shader Graph' started by viktorkadza, May 16, 2020.

  1. viktorkadza

    viktorkadza

    Joined:
    Sep 4, 2018
    Posts:
    46
    Hi,
    I am need a shader doing something like this in URP:
    upload_2020-5-16_14-1-24.png

    Doing it with plane,or a kind of box volume isn't crucial.
    I can make a cutout with AlphaClipThreshold, but still need to cap the hole somehow.
    upload_2020-5-16_13-53-28.png

    Maybe there is a way to get the intersection of a plane and a solid. Or an intersection between a thin,plane like solid and a normal solid .


    upload_2020-5-16_13-59-18.png

    Best Regards.
    Viktor
     

    Attached Files:

  2. crawlygs

    crawlygs

    Joined:
    Jan 16, 2013
    Posts:
    3
    I need this too.
     
  3. rorybowcott

    rorybowcott

    Joined:
    Jun 22, 2017
    Posts:
    8
    Did you ever get around to finding a solution to this?
     
  4. Olmi

    Olmi

    Joined:
    Nov 29, 2012
    Posts:
    1,553
    Hi,

    If you don't need the cut surface textured, you could "fake" this effect by calculating distance to a plane. If your texel is above the plane, clip it out using alpha clip. Then use Is Front Face to detect if the texel is in a backface and set the backface color to solid by using emission. This way it looks as if it's cut as you don't see the shading on the interior faces. If this is what you need, you could adapt Ronja's tutorial to Shader Graph, the whole process is explained there very clearly.

    See link: https://www.ronja-tutorials.com/2018/08/06/plane-clipping.html

    For a textured surface you will need more advanced setup, you probably would have to use a mesh cutting system and construct the cut surface polygons yourself.
     
  5. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    973
    In URP:
    - in case of coded shaders you can use the method from here:
    https://github.com/Dandarawy/Unity3DCrossSectionShader/wiki
    - just get the stencil code from the shaders there and add it to your URP shaders.

    Shader graphs do not support stencils, so:
    - in case of shader graph shaders - write a simplest possible URP "ghosting" shader writing to the stencil buffer only - and put it onto a top of the shader graphs shaders using the RenderObjects feature. Then use a simple unlit color texture shader written with code, with added stencils - as above - for the textured cutting planes.

    You should be able to get this effect; this is done in URP.
    combined.png
     
    Last edited: Feb 16, 2021
    mirobeka and newguy123 like this.
  6. mirobeka

    mirobeka

    Joined:
    Jun 14, 2020
    Posts:
    3
    Hey man, I'm trying to do this for days now! I'm complete noob noob when it comes to shaders, my brain hurts, but I'm starting to understand it. However, not so much yet, that I could translate your answer into steps to produce this effect. I get it, but it's like one "ahaaa" away!

    Could you elaborate on "write a simplest possible URP 'ghosting' shader"? What do you mean by ghosting?

    And what's the "RenderObjects" feature? I can't find any info about this.

    Could you dumb it down for us, please? :)

    PS: too late I've discovered that URP is not compatible with surface shaders. Already upgraded the whole project just to discover that this won't work...
     
  7. Tabularas

    Tabularas

    Joined:
    Jul 7, 2020
    Posts:
    4
    @tomekkie2
    I was looking through your mentioned posts but I still can't figure out a solution to achieve this directly in Shader graph.

     
  8. mirobeka

    mirobeka

    Joined:
    Jun 14, 2020
    Posts:
    3
    @Tabularas it can't be done only with shader graph. However, you can "view generated shader". Basically shader code that's compatible with new URP. From what I've learned, this code is much more complex and low level than other shader code (that we can find all around the internet).

    So in order to use stencil buffer, we should generate code from graph and insert the stencil snippet somewhere. But I'm lost at this point.

    Check out this video, it's better explained there:
     
  9. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    973
    "Ghosting" - I mean an "invisible" shader, using Colormask 0, writing to stencil buffer only.
    The "RenderObjects" feature let's you to render the filtered objects more times.
    Shader graph do not support the stencil buffer, so you have to get your material rendered for a second time using a stencil write shader and you can use "RenderObjects" for that.
    The "RenderObjects" have also their stencil options, but these lack front/back face distinction, while you need only the back faces to get written, so you have to use a shader.
     
  10. fra3point

    fra3point

    Joined:
    Aug 20, 2012
    Posts:
    269
    Hello!

    I'm using this solution for URP: https://github.com/Dandarawy/UnityCrossSectionShaderGraph

    It works quite well in general but there's a case that makes this system fail.

    Look at this image:
    upload_2023-5-21_17-59-41.png

    The metallic ring has a cut section shader with the following properties:

    Code (CSharp):
    1. Cull Off
    2. Blend One Zero
    3. ZTest LEqual
    4. ZWrite On
    5. AlphaToMask On
    6.  
    7. Stencil {
    8.      Ref 255
    9.      CompBack Always
    10.      PassBack Replace
    11.  
    12.      CompFront Always
    13.      PassFront Zero
    14. }
    and it is cut by a red plane, which has a very simple lit shader (made with shadergraph) with these edited properties which make the plane visible only where it fills the holes:

    Code (CSharp):
    1. Cull Back
    2. Blend One Zero
    3. ZTest LEqual
    4. ZWrite On
    5.  
    6. Stencil{
    7.      Ref 255
    8.      Comp LEqual
    9.      Pass keep
    10.      Fail keep
    11. }
    The problem is that the cutting plane reveals some inner faces even if their depth is greater than the plane itself:

    upload_2023-5-21_18-6-22.png


    The wanted behoviour is something like this:

    upload_2023-5-21_18-9-51.png

    Is this possible to achieve?
    Thanks in advance to anyone that could help me.


    Francesco
     
  11. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    973
    I think these are redundant front faces inside the ring.
    Check this ring for errors.
    Generally all the cases of not closed, intersecting or erroneous meshes make this system fail.
     
    fra3point likes this.
  12. fra3point

    fra3point

    Joined:
    Aug 20, 2012
    Posts:
    269
    Thanks for the reply!

    I actually made those redundant front faces intentionally, just to show the problem.
    I am working with complex meshes (3M triangles) created from CAD files and it is not possible to remove all the internal faces easely. Are there any other solutions that can show the cutting plane considering its depth?
     
  13. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    973
    3d printable files can not have any errors like that.
    I guess you could process your CAD files in some way to make them 3d printable.
     
  14. fra3point

    fra3point

    Joined:
    Aug 20, 2012
    Posts:
    269
    It's not really possible for me to make those CADs printable (or without front inner faces) as you suggested because of the complexity of the models. There's another problem, too...

    Just to add a bit of context, I'm working on a machine inspection system, and all the single parts of the model (houndreds) must be seen together and individually with a kind of "isolate object" view. A lot of these objects are adjacent, so their surfaces touch each other.

    Look at this simplified example:

    in2.gif

    The two cubes are separated objects, but they are adjacent. When I use the cutting plane, the adjacent faces act as the internal front faces of my previous post's ring. This does not happen if the cubes are detatched. I cannot just delete the touching faces because I have to show those objects individually when my "isolate object" mode is active.

    I was wondering why this happens (I'm not an expert with stencil shaders) and if there are other shader-based solutions to avoid this limitation.

    Thanks for your help, it's much appreciated!


    Francesco
     
    Last edited: May 22, 2023
  15. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    973
    Means possibly the separate meshes are 3d printable.
    But their adjacency makes the problem.
    Maybe you could use the offset directive in the cross section shader.
    https://docs.unity3d.com/Manual/SL-Offset.html
    But I am not sure if you could apply it separately to front and back faces.
    If not you could split it into separate passes for front and back.
    I mean you could remove a bit of depth from backfaces, moving it a bit towards the camera.
    That should fix the most of the problem, but some artifacts would remain on the edges.

    I am sellig a dedicated cross-section asset on the AssetStore, and I have added a special feature moving back the backface vertices along the face normals on the shader vertex stage. It fixes the most of the problem, but artifacts remain.
    You can see it on my demo here:
    https://virtualplayground.d2.pl/crossSection_urp/
    There will be a dropdown selector on the bottom left and you can swich to the retract_backfaces_urp scene.
    Inside the scene - on the bottom- right - you can find the slider with offset amount.
    Using offset it should work roughly the same.
     
    Last edited: May 22, 2023
  16. fra3point

    fra3point

    Joined:
    Aug 20, 2012
    Posts:
    269
    The example solves the problem perfectly. I'll definetly buy your system from the Asset Store. Thank you!


    Francesco