Way to get Vertex World Position in Shader

I am trying to get the world position of vertices in order to generate ground fog. However, I have tried multiple ways to calculate the position of the vertices by reconstruction with no luck, either from depth or by matrix projections both in the vertex and fragment shaders, such as described here.

When the vertex positions are fed into gl_FragColor, the resulting image should appear to be splitting the world into four quadrants, which do not shift depending on camera rotation or position, such as in this image:
Screenshot_2025-02-28_20-47-35

Here is the normal render for comparison:
Screenshot_2025-02-28_20-47-58

Does anyone have any advice or any code? Thanks.

See this example, it converts position to world space in the vertex shader like this

vec4 pos = matrix_model * vec4(aPosition, 1.0);

There’s also a different way to do ground fog PlayCanvas Examples

I was looking at that example and have no idea how to port it to my own project to use with my assets, since it seems to be very tailored to that specific environment.

I guess I did not specify that I am attempting to do this in a post processing shader, so my aPosition is only 2d instead of 3d.

Ah that makes a big difference. You need to enable on the camera to render depth texture. And then in your shader, you’d need to reproject the depth back into world space. Not super trivial.

Assuing you’re using engine v2, similar shader code is in this file: engine/src/extras/render-passes/render-pass-taa.js at main · playcanvas/engine · GitHub

this bit reads the depth from the depth buffer:

 // current depth is in linear space, convert it to non-linear space
float linearDepth = getLinearScreenDepth(uv0);
float depth = delinearizeDepth(linearDepth);

and then this bit converts it to world position:

// Transform NDC to world space of the current frame
vec4 worldPosition = matrix_viewProjectionInverse * ndc;
worldPosition /= worldPosition.w;

I am using engine v1, but I was doing something similar. I believe it is an issue with retrieving the view matrix of the camera, the transforms don’t seem to line up with the actual movement of the camera. I am using the first person character controller and am using a script attached to the camera in the character controller template. I am retrieving the view matrix like this:

 this.effect.viewMatrix = this.entity.camera.viewMatrix.clone();

It seems as if the view matrix isn’t really aligning with the position of the camera when I move.

I’d capture a frame using Spector JS and compare the view matrix between one of the meshes during the rendering with the one you use.

I compared them and they are slightly different! I will investigate further!

I used Spector JS and was able to find a built in view projection matrix and used that instead of the ones passed in by the javascript portion of the script and got my effect to work :smile:

1 Like