# Can I get world-space z-near-plane vertices from projection matrix + z-near distance?

Game Development Asked by kaoD on November 26, 2020

I’m trying to port ShaderToy VR shaders to WebXR (the new browser API for AR/VR devices).

ShaderToy VR shaders expect two extra parameters: ray origin (view translation) and ray direction (unit vector from ray origin to each pixel). I could easily calculate this ray direction if I had fovX + fovY + distance to projection plane.

The problem: WebXR does not expose FOVs and instead just provides us with a projection matrix (apparently some devices might need more complex projection matrices with shear, roll, etc.) WebXR also exposes zNear and zFar, but that’s all the frustum info available if I’m not mistaken.

Is there any way to obtain the zNear plane corners in world-space with this information?

Thanks @DMGregory for the pointer in the comments.

I'm constructing a fullscreen quad at (x, y, -1, 1) in NDC. Notice z = -1 is the near plane in NDC (left-handed unlike normal coordinate systems in OpenGL-land).

attribute vec2 aVertexPosition;

uniform mat4 uInvViewMatrix;
uniform mat4 uInvProjMatrix;

varying vec3 vZNearPos;
varying vec3 vRayOrig;

void main() {
// Vertices in the near plane in NDC
gl_Position = vec4(aVertexPosition.xy, -1.0, 1.0);

// Vertices in the near plane in world-space
vec4 vZNearPosW = uInvViewMatrix * uInvProjMatrix * gl_Position;
vZNearPos = vZNearPosW.xyz / vZNearPosW.w;

// Ray origin in world-space
// This could be a uniform but I was lazy :P
vec4 rayOrigW = uInvViewMatrix * vec4(0, 0, 0, 1);
vRayOrig = rayOrigW.xyz / rayOrigW.w;
}


The uniforms in JS:

• uInvViewMatrix is view.transform.matrix, NOT view.transform.inverse.matrix which you'd normally use (see https://developer.mozilla.org/en-US/docs/Web/API/XRView/transform). I.e. this is the inverse of the view matrix.
• uInvProjMatrix is the inverse of WebXR's view.projectionMatrix.

varying vec3 vZNearPos;
varying vec3 vRayOrig;

void main() {
// I'm not sure if this can be safely interpolated per-vertex
// so I kept in the fragment shader just in case
vec3 rayDir = normalize(vZNearPos - vRayOrig);

}


Correct answer by kaoD on November 26, 2020

## Related Questions

### How can I make particles move like a square in Unity?

1  Asked on December 21, 2021 by magikarpsama

### Unity3D URP – How do I approach creating Fog of War for 3D top-down stealth game?

1  Asked on December 21, 2021 by zekko

### How can I make the text flash?

1  Asked on December 20, 2021

### Transform.Rotate is jumping around

1  Asked on December 18, 2021

### World space coords for 2d images

1  Asked on December 15, 2021 by user3134909

### How do I safely change properties on my skybox?

1  Asked on December 15, 2021

### Why does masked animation look so strange?

1  Asked on December 15, 2021

### Save-security with MD5 hash

3  Asked on December 13, 2021 by abdulla

### Rigidbody player controller on moving platforms

1  Asked on December 13, 2021 by gorgo-3

### Can I bring features of an Android game into another Android game?

1  Asked on December 13, 2021 by thinkgood

### Polygon filling algorithm

0  Asked on December 13, 2021

### How to programmatically overlay a shader on a terrain by mask (Unity)?

0  Asked on December 13, 2021

### Leaderboard not working in Unity

1  Asked on December 11, 2021 by single-arrow-games

### What is “Avatar” in the “Animation Controller” used for?

0  Asked on December 11, 2021

### 2D Grid-based Pathfinding with Elevation

1  Asked on December 11, 2021 by oyed

### Mirror/Unet, RegisterSpawnHandler throws invalid asset Id error because assetId is 0 for dynamically loaded assetbundles

1  Asked on December 8, 2021

### Placing Zones in Cities Skylines

1  Asked on December 8, 2021 by fence_rider

### What causes skating feet in Unity (but not in mixamo or Autodesk FBX review)?

1  Asked on December 8, 2021

### Frame-rate drops when drawing 2D map tiles

1  Asked on December 6, 2021 by theco

### Default Game Window Size To Take While Making Games

2  Asked on December 6, 2021