How to, in shader, get the pixel's 3d coordinate? (local and global)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Mr Henri

So, I’m creating a special shader to render some objects using raymarching!

I succeded to render everything normally on a cube (MeshInstance),
however, the camera inside the shader used a different transform than the one in the actual scene.

In order to fully render, let’s say, a sphere inside the cube I’d need to have the camera position (which I have) and the fragment’s position in the world (similarly to how SCREEN_UV gives a vec2 for the fragment’s position on screen, I want a vec3 for the fragment’s position in the world):

Also, if possible as well, the fragment’s position related to the mesh itself (e.g., how UV is relative to the node and SCREEN_UV is relative to the screen).

Thank you in advance <3!

:bust_in_silhouette: Reply From: wombatstampede

Ok VERTEX will give you (by default) the local coordinates inside the vertex shader.
These coordinates will be relative to the mesh.

And VERTEX will give you the camera-relative coordinates inside the fragment shader.

You should be able to get world coordinates inside the fragment shader by applying the CAMERA_MATRIX to the VERTEX.

vec3 wrld_vertex = CAMERA_MATRIX * vec4(VERTEX, 1.0)

You can pass the (local) VERTEX from the vertex shader to the fragment shader by using a varying variable. Such variables will be interpolated between the corners of a face to match the pixel. Probably, there’s also a way to calculate the local VERTEX inside the fragment shader but I don’t see a convenient way (like i.e. an INV_MODELVIEW_MATRIX)

beautiful! what I was looking for (:

harmony | 2022-06-17 18:45

In Godot 4 it was renamed to VIEW_MATRIX

titus | 2023-06-20 04:51

:bust_in_silhouette: Reply From: tshrpl
// from camera space to world space
vec3 VERTEX_WORLD = CAMERA_MATRIX * vec4(VERTEX, 1.0);

// from world space to object space
vec3 VERTEX_LOCAL = inverse(WORLD_MATRIX) * vec4(VERTEX_LOCAL, 1.0);

edit:
combine them for efficiency

// pixel's position in object space
VERTEX = inverse(WORLD_MATRIX) * CAMERA_MATRIX * vec4(VERTEX, 1.0);

This works great, thanks. Used in a Dissolve shader in Object Space: https://twitter.com/AlfredBaudisch/status/1555081237009731584

alfredbaudisch | 2022-08-04 08:57