Get 2D Sprite position based on visible position on screen after shader (like get_global_mouse_pos)?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By SpaceDoubt
:warning: Old Version Published before Godot 3 was released.

Short version: Can I get a sprite’s position on the screen in the same way that I can get the mouse position? Particularly a sprite on a ViewportSprite with a shader on it? (If the sprite appears in the top left, it returns 0,0, etc…)

Seems like I’m probably missing something simple, but…

Long version:
I’ve got a mode 7 shader going on a ViewportSprite which lets me make 2d maps appear all nice and fake 3D (like mario kart!). What I want is to be able to place little markers on my 2D maps and use their positions to create sprites in the fake 3D space that aren’t affected by the actual shader (but still use the position from it).

In order to have objects show up in “3D” positions, I could do way more math than my head wants to understand (I’m trying!), but if I could just figure out how to get the sprite to return it’s visible position on the screen the same way the mouse does, I could let the math that’s already there handle it… (This would also make the scaling way easy)

It’s also kinda tricky, cause the shader only shows a portion of the actual viewport. That’s why I need to read all the sprite coordinates based on what you see after the shader, as opposed to just what the viewport returns.

I’ve only been using Godot a couple weeks, but I am loving it.
I am having a hard time understanding how to use matrices and transforms and the like. If that’s useful here, I’d love some help understanding that stuff, as well.


:bust_in_silhouette: Reply From: Zylann

Shaders are output only and executed on the graphics card, so there is no easy way of getting the output of it back in GDScript, and in the format you expect.

What you can do is to either use actual 3D, or compute your own projection in GDScript to get the “fake 3D” position of the sprites on your viewport.
I did a quick search and the confusing part is, I can’t find standalone projection matrix functions in GDScript. Probably because it was never needed, 3D is there already. Functions like unproject_position are actually on Camera (3D), but for this a camera has to exist. You can also use Matrix3 and Transform for math (but you’ll have to setup projection values yourself).

There are other ways involving geometry shaders so you could send marker positions as an array to a uniform and generate sprite geometry on the GPU, but these are not supported in Godot 2.x and it would still stay on the graphics card.

Another hacky way would be to use points (GL_POINTS in OpenGL), which you can send as a list of vertices. They will be rendered as quads on the graphics card, and can be textured with a custom shader.

Awesome response, thank you!

I had a feeling it wasn’t going to be quite that simple.

Thanks for the quick, detailed response.

Math time!

SpaceDoubt | 2017-02-19 04:00