Search Unity

Resolved Shader Graph Projection Problem

Discussion in 'High Definition Render Pipeline' started by John_Leorid, Jul 20, 2021.

  1. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    650
    upload_2021-7-20_9-0-25.png

    As you can see in the picture I want to make my own kind of decal shader.
    Why? It's for an editor tool we are using, our Sector System which loads and unloads stuff and we need to see the areas where things are loaded.

    Could just use Decal Projector? Maybe, but I don't want to create a bunch ob GameObjects just for drawing, when a cool method like Graphic.DrawMesh exists, which just draws stuff without creating dummy objects. The only thing I'd need to get working is this shader graph.

    And really, it can't be that hard? ehem ..
    upload_2021-7-20_9-3-19.png

    Ok, Zoom View of the important stuff here:
    (full Graph is attached)
    upload_2021-7-20_9-4-24.png
    So what I am trying to do is basically explained in this cool video at 3:45.
    I want to get the world point (based on depth) behind (or in front) of any point of my object.
    Basically raycasting throught my object to see if the resulting point is inside or not.

    I'm getting the view diretion in world space, so the vector from my the pixel on my object to the camera.
    Then invert it, so I get the direction from camera to ObjectPixel.
    Multiply it by the scene depth to get the vector that has the resulting depth (raycast hit).
    But this is just the vector from 0,0,0 - to get the actual hit point, I have to add the camera position.
    Then I transfrom the hitPoint to object space, to check if it is inside my cube.
    Now we are at the lower line.
    Default Cube (scaled up), so the cube has a size of 1,1,1, half extends of 0.5,0.5,0.5.
    If any point is outside, any length must be > 0.5.
    So to compare it, I take the local vector to the hitpoint and take the absolute value.
    Substract the absolute value from 0.5,0.5,0.5.
    Then take the sign, if any value is less than 0, the point is outside of my cube.
    So all I have to do now, is clamping the signed values of each axis so they are either 1 or 0 instead of 1 and -1.
    Then multiply all axis with each other - if any of them is 0 (outside), the result is 0. If all of them are 1 (inside), the result is 1.
    That's it. I just use a comparison after that to draw the rest of the cube too.

    And it is basically working, but the edges are wrong (first picture). I think this has to do with perspective projection, because when I set my FOV to 4 in the editor, the issue is gone.
    Also it only happens on the edges of the camera, in the center it is at the correct position.
    When looking at the cube from the inside, it works 100% (idk why).

    Any ideas how to fix this?

    PS: Sorry for the extremly messy shader, I was testing a lot of things.
     

    Attached Files:

    Last edited: Jul 20, 2021
  2. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    650
    Got it working. I've found some cool guys github where he provides a free URP Decal shader. Just copy and pasted his way to do the "GPU raycast" and now everything is working.

    Screenshot of the calculation ... using the dot product, dividing, I have absolutely no idea what's happening here but it seems to be right way to do it.
    upload_2021-7-21_2-40-36.png