Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Is there a way to get an object's screen position in the shader graph?

Discussion in 'Graphics Experimental Previews' started by hatless, Jul 21, 2019.

  1. hatless

    hatless

    Joined:
    Dec 15, 2010
    Posts:
    48
    That's the position of the object itself, not any particular vertex or fragment. It seems like it should be easy, but unity doesn't seem to be making it easy.
     
  2. hatless

    hatless

    Joined:
    Dec 15, 2010
    Posts:
    48
    Further thoughts: The obvious (intended? probably?) method would be to pass a zero vector to a transform node that transforms object to view space. But that doesn't take into account screen depth, so ok, I just need to get the depth value of the object and divide. But the shader graph is hermetically designed so that the only way to get the depth would be... with a transform node? Which is the source of the problem??

    Bump, because I don't think unity is meant to be a Zachtronics-like lateral thinking challenge, but I've been death marching for five hours on a problem that should take five seconds and feel a bit burned out.
     
  3. hatless

    hatless

    Joined:
    Dec 15, 2010
    Posts:
    48
    Returning to the puzzle: Tried every plausible combination of matrix multiplications. Then any implausible combination that 'looked like it might do something.' No dice. The solution might be hidden somewhere in this huge possibility space but I'll never find it by chance.

    Sudden insight: Flatten mesh to screen-facing plane using vertex shader, then use uvs as proxy for position. It works! Until I try it with gpu instancing. Then it breaks!

    Guys, playing Unity: the Puzzling is no longer fun. Could someone please spoiler me the solution?
     
  4. Maarti

    Maarti

    Joined:
    Sep 3, 2016
    Posts:
    5
  5. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
  6. hatless

    hatless

    Joined:
    Dec 15, 2010
    Posts:
    48
    I guess I'd better restate the question again. The challenge of the stage in Unity: the Puzzling I am stuck on is to calculate, in the shader graph, with hdrp, the screen position and screen depth of the object being rendered. Not a pixel or vertex of the object but the the thing itself.

    In the base game this would be very easy: stating the problem solves the problem. But the Shader Graph + HDRP expansion packs have raised the difficulty level enormously and I'm not sure these stages were playtested at all.

    So could someone please spoil me on the no doubt lucid and elegant solution?
     
  7. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    upload_2019-10-7_19-32-22.png
    You didn't find the node by typing object ? if not please report a bug. You can't have the object's pivot position without calculating one yourself because it's not a vertex or a pixel, and won't be transformed to screen space.

    So like I said pass it in, or further transform it after using Object node. Good luck!
     
  8. hatless

    hatless

    Joined:
    Dec 15, 2010
    Posts:
    48
    Thanks for the well-wishes, but if you know a way it can be done, could you say it rather than gesturing vaguely towards it? It's enough to make me suspect you've not even tried.

    (To be wholly clear: the problem is "to calculate, in the shader graph, with hdrp, the screen position and screen depth of the object being rendered.")
     
  9. Ehredt

    Ehredt

    Joined:
    Jun 20, 2018
    Posts:
    79
    My guess is that there's no node to calculate screen space object position in shader graph, so you'd probably have to calculate the screen space position of an object in a script outside shader graph and then, to have it show up in the shader, create a property with an exposed reference in the shader graph and have the script update that during gameplay. Apologies if this is super obvious and you've already tried it -- I'm not a shader programmer so references in shader graph weren't intuitive to me at first. I don't have time to test it myself, but I can't imagine a reason it wouldn't work, which of course are the last words anyone says right before something breaks in their game engine.

    The code to change the property would look something like "yourMaterial.SetVector("_ScreenPosition", objectScreenSpacePosition); and I guess you would want to be using a Vector2 instead of a Vector1 like I did in the screenshot.

    Let me know if this doesn't work for some reason -- I don't have time to test it thoroughly but I can imagine someone else having this same question so it'd be good if we could come up with a solution here.

    upload_2019-10-10_16-39-57.png
     
  10. fsstudiodev

    fsstudiodev

    Joined:
    Aug 21, 2020
    Posts:
    3
    This is not something that should be done in a shader. Just calculate it in CPU side and upload position as a uniform.
    I guess there's a way to get the Camera matrix, just multiply your object's world position by the camera matrix to get the position in camera space. And then upload it by using myMaterial.SetVector("_ObjectPosition", objectPosition).
    You'll need to create a property and expose it as _ObjectPosition.
     
    Pheonix14 likes this.
  11. azmi_unity

    azmi_unity

    Joined:
    Dec 13, 2020
    Posts:
    62
    Try this.

    upload_2021-5-20_23-13-20.png
     
    EtudE71, susiehwangart and MaxMiZhou like this.