Render GUI elements with projection matrix

Started by
11 comments, last by NightCreature83 8 years, 4 months ago

I want to know how to render 3D objects at the same position on the screen with projection matrix.

I suppose I must use View matrix which has view direction strictly along Z axis, but what else?

I am asking because I want to draw GUI in 2D coordinates like usual UI 0,0 - is the upper left corner.

I know that OrthoOffCenterLH matrix can project 3d 0.0.0 to 2d 0.0 with left upper corner, but with ortho matrix there is no visible depth.

Thats why I want to use projection matrix.

I suppose that in this case I must manually calculate position of each element to move it from center in 3D to upper left corner in 2D.

Am I right?

Advertisement

I know that OrthoOffCenterLH matrix can project 3d 0.0.0 to 2d 0.0 with left upper corner, but with ortho matrix there is no visible depth.

Thats why I want to use projection matrix.

What do you mean by "visible depth"? Do you want to have z-ordering (with a zbuffer), or do you want an actually 2.5D UI where you can have elements further behind appear smaller than in front? Also do you want to actually render real 3D objects, or where you referring to 2D textured sprites?

If you do not want an UI that uses such "real 3D" behaviour and just use sprites, you actually don't need any matrix at all, you can just perform the projection manually (eigther in shader or on the CPU):


        float2 projectPoint(float2 vPoint)
        {
            float2 vProjected;
            vProjected.x = vPoint.x * (1.0f / (vResolution.x * 0.5f)) - 1.0f;
            vProjected.y = vPoint.y * (1.0f / (vResolution.y * 0.5f)) + 1.0f;
            return vProjected;
        }

vPoint is a point in range of upper left (0.0/0.0) to lower right(vResolution.x/vResolution.y), so you basically multiply by the reciproc half screen/viewport size and add some offset to bring it in the screen coordinate range.

In any other case, you'd need someone else to answer your question.

By visible depth I mean z-ordering with z-buffer. I want a real 3D UI behaviour.

How I need to render it in that case taking into account that I want to convert 3D Zero(0,0,0) in the middle of coordinates to the 2D Zero (0,0) at the left top corner?

If you want to preserve depth you still can use ortho matrix. If you turn off depth wright, the triangles will be drawn in the order you submitted them.

I mean that I want to draw controls using true depth feeling, which could be made only with projection matrix. With ortho I need to scale objects manually if I want make them smaller when they are far from the camera.


How I need to render it in that case taking into account that I want to convert 3D Zero(0,0,0) in the middle of coordinates to the 2D Zero (0,0) at the left top corner?

you don't - you make it a real 3d gui.

the menus are drawn just like a player weapon in 1pv, always in front of the camera.

mouse clicks are raycasts into the scene that intersect the menu options.

done deal - get a beer.(assuming you're of age <g>)

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

I think that you mean "perspective projection matrix", not "projection matrix" (orthographic is still a type of projection).

If you have a 2D point and you want to know where that would be in 3D, you can "unproject" the 2D point to get the original world-space or view-space coordinate that would result in a given 2D position once projected. DirectXMath even has a helper function for doing it. Basically it converts from window coordinates to normalized device coordinates, transforms by the inverse of the combined world * view * projection matrix, and performs the perspective divide-by-w. If you want the coordinates in world space, pass an identity matrix as the "World" parameter. If you want the coordinates in view space, pass an identity matrix for the both the "World" and the "View" parameters.

I mean that I want to draw controls using true depth feeling, which could be made only with projection matrix. With ortho I need to scale objects manually if I want make them smaller when they are far from the camera.

You will want to just do normal 3D rendering and use a camera to view the menu through. Use this camera idea to frame the UI too it makes it a lot easier to deal with.

In a 3D ui you dont have to care about the 0,0,0 mapping on to the 0,0 corner, this is what the frameing with a camera is for.

If you look at the DiRT and GRID games they all have a 3D ui, and for ease of development we never supported mouse input all input is either keyboard arrows and enter or controller. Doing the unprojection is not that hard but the system we had to create these UIs made that a lot harder, the update side of the UI had no idea of where the rendering of the UI was happening in space. Which allowed for a lot of flexibility in setting up scenes and implementing the behaviour of the screens at the cost of not having mouse input though.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

I also did a full 3d menu and tried to do a full 3d ui.

It does make things very easy but there is a hidden setup cost; you must implement all your 3d gui components for your ui, e.g. I have a label, slider and checkbox.

Once you have these elements you could have a fully mouse navigable ui, your other choice is to do it how nightcreature said and just highlight the current selection which is more console friendly...

Thanks to all for your answers.

What do you think about using PerspectiveOffCenterLH matrix for this?

Seems it project DirectX units directly to pixels and position correspondingly. Using this matrix 0.0 will be at the top left corner of the window without any additional manipulations.

This topic is closed to new replies.

Advertisement