Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SceneKit - get position in screen coordinate

Tags:

glsl

scenekit

How can I get the coordinate of a point in the screen referential from the geometry shader entry point? SceneKit exposes a bunch of matrix transformations and their inverses (https://developer.apple.com/reference/scenekit/scnshadable > Using Inputs Provided by SceneKit) but I could not figure out how to use them...

for instance, in the geometry entry point that's executed in the vertex shader, I've tried:

varying vec2 screen_coords;

#pragma body
screen_coords = (u_inverseModelViewProjectionTransform * _geometry.position).xy

but that doesn't seem to work :(

To clarify, I'd like screen_coords to be in [0, 1] * [0, 1] if the point is in the screen depending on it's exact position, and something else if not.

like image 494
Guig Avatar asked Sep 13 '16 21:09

Guig


2 Answers

It took me a while, but here it is:

vec4 screenPos = u_modelViewProjectionTransform * _geometry.position;
screen_coords = (screenPos.xy / screenPos.w + 1.0) * 0.5;

Explanation: screenPos roughly corresponds to the coordinate in screen space. screenPos.xy / screenPos.w rescale those coordinate. Then weirdly this gives input [-1, 1] * [-1, 1] so I finally added an offset and scale to get the result in [0, 1] * [0, 1]

like image 162
Guig Avatar answered Oct 16 '22 18:10

Guig


For anyone that stumbles on this in the future, in metal I think you can get the screen coords in the surface shader just by grabbing

in.fragmentPosition.xy * scn_frame.inverseResolution.xy

See here for more info

like image 25
aferriss Avatar answered Oct 16 '22 18:10

aferriss