# Screen to World coordinates

**URL:** https://discourse.libcinder.org/t/screen-to-world-coordinates/1014
**Category:** Using Cinder
**Created:** [January 6, 2018, 5:14pm UTC](https://discourse.libcinder.org/t/screen-to-world-coordinates/1014 "2018-01-06T17:14:37Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![SuperRockG](https://avatars.discourse-cdn.com/v4/letter/s/fbc32d/32.png) [@SuperRockG](https://discourse.libcinder.org/u/SuperRockG)
#### Post date: [January 6, 2018, 5:14pm UTC](https://discourse.libcinder.org/t/screen-to-world-coordinates/1014/1 "2018-01-06T17:14:37Z")

</div>

Hi,

I am using an ortho camera and trying to convert from screen to world coordinates using this calculation. But it does not seem to work.

Can anyone explain why?

Previously i was, getting the ratio of screen pos to screen size, multiplying that ratio by the ortho camera frustum size, then adding that to the left and top of the frustum.

I thought i would change to the way below so it would work for all camera types, not just ortho.

```
	ci::mat4 matProjection = m_pCameraOrtho->getProjectionMatrix() * m_pCameraOrtho->getViewMatrix();
	ci::mat4 matInverse = ci::inverse(matProjection);

	float x = vPos.x;
	float y = vPos.y;

	float in[4];
	float winZ = 1.0;

	// convert to NDC normalized device coordinates
	in[0] = (2.0f * ((float)(x - 0) / (ci::app::getWindowWidth() - 0))) - 1.0f,
	in[1] = 1.0f - (2.0f * ((float)(y - 0) / (ci::app::getWindowHeight() - 0)));
	in[2] = 2.0 * winZ - 1.0;
	in[3] = 1.0;

	ci::vec4 vIn = ci::vec4(in[0], in[1], in[2], in[3]);

	// convert to world coordiantes
	ci::vec4 _vPos = vIn * matInverse;

	_vPos.w = 1.0 / _vPos.w;

	// scale up to pixel coordinates
	_vPos.x *= _vPos.w;
	_vPos.y *= _vPos.w;
	_vPos.z *= _vPos.w;

	return ci::vec2(_vPos);
```

---

<div class="post-metadata">

### Author: ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)
#### Post date: [January 7, 2018, 10:58pm UTC](https://discourse.libcinder.org/t/screen-to-world-coordinates/1014/2 "2018-01-07T22:58:42Z")

</div>

Hi,

to convert from window coordinates (I’ll use the mouse here) to world coordinates, you can simply use the `glm::unProject()` function:

```auto
ivec2 mouse = ...; // obtain mouse coordinates in the mouseMove() function.

mat4 projection = cam.getProjectionMatrix() * cam.getViewMatrix();

int w = getWindowWidth();
int h = getWindowHeight();
vec4 viewport = vec4( 0, h, w, -h ); // vertical flip is required

vec3 worldCoordinate = 
    glm::unProject( vec3( mouse, 0 ), mat4(), projection, viewport );

```

When drawing your content, you should store the model matrix. This way, you can later also retrieve local coordinates:

```auto
mat4 model = glm::rotate( glm::radians( 30.0f ), vec3( 0, 0, 1 ) );

gl::pushModelMatrix();
gl::setModelMatrix( model );
gl::drawStrokedRect( Rectf( 0, 0, 100, 100 ) );
gl::popModelMatrix();

vec3 localCoordinate = 
    glm::unProject( vec3( mouse, 0 ), model, projection, viewport );

if( Rectf( 0, 0, 100, 100 ).contains( vec2( localCoordinate ) ) )
    CI_LOG_I( "Rectangle touched!" );

```

-Paul

P.S.: if you’re going to use `glm::unProject` a lot, it will be faster to call it once per frame to obtain a `worldCoordinate` (use `mat4()` for the second parameter), then for each object on screen multiply it by its inverse model matrix to obtain the local coordinate:  
`vec4 localCoordinate = glm::inverse( model ) * vec4( worldCoordinate, 1 )`.

(Post taken from the [old forums](https://forum.libcinder.org/topic/converting-touch-points-to-world-coordinates-using-an-orthogonal-camera)).

---

<div class="post-metadata">

### Author: ![SuperRockG](https://avatars.discourse-cdn.com/v4/letter/s/fbc32d/32.png) [@SuperRockG](https://discourse.libcinder.org/u/SuperRockG)
#### Post date: [January 12, 2018, 1:48pm UTC](https://discourse.libcinder.org/t/screen-to-world-coordinates/1014/3 "2018-01-12T13:48:08Z")

</div>

Once again, Paul thank you 🙂 Will be book marking this as its something i always keep coming back to.
