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

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.

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.

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?

Use the Screen Position Node ?
https://docs.unity3d.com/Packages/com.unity.shadergraph@6.9/manual/Screen-Position-Node.html

1 Like

Failing that just pass it in from script…

(also 3D position of the object if needed https://docs.unity3d.com/Packages/com.unity.shadergraph@6.9/manual/Object-Node.html)

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?

5039699--494228--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!

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.”)

1 Like

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.

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.

1 Like

Try this.

4 Likes