<p>Scale the object proportional to its depth (z in camera space) and it will retain the same size on screen regardless of its position in world space.</p>

<p>Additionally, you might also wish to scale the object proportional to the field of view so that it retains the same screen size regardless of the camera zoom. (Specifically, scale it by tan(fov/2)).</p>

<p>Finally, you might also wish to scale it inversely proportional to the pixel size of the window if you want the widget to retain a constant size in pixels regardless of how large the window is. Otherwise it will be constant as a fraction of the window size.</p>

<p>I wouldn't recommend trying to do this in post-projective space (by manipulating w, etc) because it will scale the object's distance from the camera at the same time as scaling its size. Effectively you're scaling it in camera space. What you really want to do is scale it in its own local space before applying world-view-projection transformations.</p>

CC BY-SA 4.0
2020-06-01T03:07:05.247Z
I am confused.
"Scale the object proportional to its depth (z in camera space) and it will retain the same size on screen regardless of its position in world space"

Assume `pos` is the world space position, `vpos` the view space position and `spos` the screen projected position.

I tried  `gl_Position *= spos.z`; `vpos *= vpos.z`; and `gl_Position *= 1.f / gl_Position.z`
None are giving me a constant size image. Some just make everything disappear    :p
Makogan
CC BY-SA 4.0
2020-06-01T03:42:26.643Z
Scale the object in local space, by the camera z of its world position.
Nathan Reed
CC BY-SA 4.0
2020-05-31T19:21:00.670Z
2020-05-31T19:29:53.813Z
2020-05-31T19:29:53.813Z
Nathan Reed
<p>If you open the modern Blender UI and select for example scaling, and then you use the scroll wheel to "zoom" (move the camera along the radial axis). You will notice that the size of the 3D
widget remains constant in screen space (it becomes bigger or smaller in regards to all the other objects).</p>

<p>I am wondering how this can be achieved. I assume there is an obvious matrix cancellation you can do, e.g setting the w component to 1 after projecting. But I am not sure.</p>

<p>As you can see the widget's size in screen space is identical:
<a href="https://i.sstatic.net/oZxDj.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/oZxDj.png" alt="enter image description here"></a>
<a href="https://i.sstatic.net/8VnC7.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/8VnC7.png" alt="enter image description here"></a></p>

CC BY-SA 4.0
2020-05-31T09:00:51.500Z
doesn't the widget simply live in screen space? i.e after projection of all the other things we simply add the widget into screenspace?
AverageGatsby
CC BY-SA 4.0
2020-05-31T09:31:01.760Z
Think @AverageGatsby is right. After rendering the scene, you can just add one additional render pass to draw the UI without any 3d transformations.
wychmaster
CC BY-SA 4.0
2020-05-31T18:27:44.297Z
Those widgets are 3D, i.e they are placed in the world and live in world space. They however remain constant size in screen dimensions.
Makogan
CC BY-SA 4.0
2020-05-31T21:40:09.520Z
I wasn't sure which parts you meant. Thought you are talking about the widgets on the side and referred to them as 3d widgets because they are drawn in the render window. ;)
wychmaster
<transformations><camera><linear-algebra><gui><ui>
How to keep an object constant in screen space?
Makogan
# How to keep an object constant in screen space?

(Asked by: username_0 on 2020-05-31)

If you open the modern Blender UI and select for example scaling, and then you use the scroll wheel to "zoom" (move the camera along the radial axis). You will notice that the size of the 3D
widget remains constant in screen space (it becomes bigger or smaller in regards to all the other objects).

I am wondering how this can be achieved. I assume there is an obvious matrix cancellation you can do, e.g setting the w component to 1 after projecting. But I am not sure.

As you can see the widget's size in screen space is identical:
[![enter image description here](https://i.sstatic.net/oZxDj.png)](https://i.sstatic.net/oZxDj.png)
[![enter image description here](https://i.sstatic.net/8VnC7.png)](https://i.sstatic.net/8VnC7.png)

**Tags:** transformations, camera, linear-algebra, gui, ui

> **Comments:**
> **username_1**: doesn't the widget simply live in screen space? i.e after projection of all the other things we simply add the widget into screenspace?  
> **username_2**: Think @username_1 is right. After rendering the scene, you can just add one additional render pass to draw the UI without any 3d transformations.  
> **username_0**: Those widgets are 3D, i.e they are placed in the world and live in world space. They however remain constant size in screen dimensions.  
> **username_2**: I wasn't sure which parts you meant. Thought you are talking about the widgets on the side and referred to them as 3d widgets because they are drawn in the render window. ;)  

---

## 1 answers

### Answer by username_3 on 2020-05-31. Score: 5

Scale the object proportional to its depth (z in camera space) and it will retain the same size on screen regardless of its position in world space.

Additionally, you might also wish to scale the object proportional to the field of view so that it retains the same screen size regardless of the camera zoom. (Specifically, scale it by tan(fov/2)).

Finally, you might also wish to scale it inversely proportional to the pixel size of the window if you want the widget to retain a constant size in pixels regardless of how large the window is. Otherwise it will be constant as a fraction of the window size.

I wouldn't recommend trying to do this in post-projective space (by manipulating w, etc) because it will scale the object's distance from the camera at the same time as scaling its size. Effectively you're scaling it in camera space. What you really want to do is scale it in its own local space before applying world-view-projection transformations.

> **Comments:**
> **username_0**: I am confused. "Scale the object proportional to its depth (z in camera space) and it will retain the same size on screen regardless of its position in world space"  Assume `pos` is the world space position, `vpos` the view space position and `spos` the screen projected position.  I tried  `gl_Position *= spos.z`; `vpos *= vpos.z`; and `gl_Position *= 1.f / gl_Position.z` None are giving me a constant size image. Some just make everything disappear    :p  
> **username_3**: Scale the object in local space, by the camera z of its world position.  

---

