Jump to content
  • Advertisement
leonard2012

3D Why the transform between normalized device and viewport coordinates is different between OpenGL and Direct3D?

Recommended Posts

According to https://en.wikibooks.org/wiki/GLSL_Programming/Vertex_Transformations and https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glViewport.xml, the relation between normalized device coordinates (NDC) and viewport coordinates in OpenGL is

y_vp = (y_ndc + 1) * height / 2

For Direct3D however, it is said in section 16.1 of "Introduction to 3D Game Programming with DirectX 11" by F. D. Luna (https://www.amazon.com/Introduction-3D-Game-Programming-DirectX/dp/1936420228) that the relation is

y_vp = (1 - y_ndc) * height / 2

 

I could not figure out the reason of this difference. Could someone kindly give me some explanation?

Share this post


Link to post
Share on other sites
Advertisement
On 11/02/2018 at 1:30 AM, leonard2012 said:

I could not figure out the reason of this difference. Could someone kindly give me some explanation?

There's endless different mathematical conventions for different things, most of which are equally valid and arbitrary choices. Historically, D3D and GL have disagreed with which way is up (do coordinates start at the top of the screen and increase downward, or start at the bottom and increase upwards?), and back in the early versions whether you should write vectors across the page or down the page... Most of the time you should be able to use whatever conventions you like at your application-level, and then do a bit of mathematical fiddling to translate that into D3D/GL's conventions. e.g. You could choose to have viewpoints be defined from the top corner or bottom corner, have Y be up or Z be up, use right-handed or left-handed coordinates, have NDC Z=1 be the near plane or far plane, use row-vectos or column-vectors, store 2D arrays in row-major or column-major order, etc.... 

Their NDC definitions also vary in Z: D3D uses a 0 to 1 range and GL uses a -1 to 1 range (by default - GL4 allows changing it). This is one case where there is an objective reason for the choice though.  GL's convention here has a nice symmetry to it, but D3Ds offers precision benefits due to how floating point numbers work, allowing much better z-buffer precision. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By AzeAngelicOne
      Real talk, This game, this game right here:

      It sucks. Immensely. It's good playing with friends, but it's AWFUL playing alone.
      But what if it didn't?
      Anybody know this game?

      A strong community behind it, and patches every month, just to show that the devs are doing everything in their power to make sure that the game is still supported, and improved to the point where everyone is happy. Well, most people.
      What if someone made a Shonen Jump crossover game in the style of DBFZ/UMvC3? What would you do?
    • By Mailbox
      Hello,
      I'm in the midst of developing a simple 3d physics engine, but have been stuck on a problem for quite a while now. I would really appreciate it if someone could have a look at it, because I'm at a loss.
      The issue I'm having concerns the collision response code, which seems to fail spectacularly in some cases, generating wrong impulse magnitudes. Specifically, something with the angular part of it is wrong, since it works as expected when only dealing with the linear part.
      I'm still not sure if I calculate the inertia tensor in world coordinates the right way, so that could be one possible culprit (though I've tried a few different ways). Impulses seem to be applied correctly to the bodies, so I think the error lies in the calculation of the impulse magnitude denominator.
      I've checked it many times with the way the Bullet physics engine does it, with the formulas available at Wikipedia, and some other sources, to no avail.
      The bodies simply keep bouncing off eachother (even though there is supposed to be no restitution) or spinning wildly on collisions.
      Here is the code that deals with the collision response:
      Vector3 originA = contactOrigin - bodyA.Position; Vector3 originB = contactOrigin - bodyB.Position; Vector3 velocityA = bodyA.Velocity + Vector3::Cross(bodyA.AngularVelocity, originA); Vector3 velocityB = bodyB.Velocity + Vector3::Cross(bodyB.AngularVelocity, originB); Vector3 velocity = velocityA - velocityB; Matrix3x3 inverseWorldInertiaTensorA = Matrix3x3::Scale(bodyA.InverseInertia) * Matrix3x3::Rotate(bodyA.Orientation); Matrix3x3 inverseWorldInertiaTensorB = Matrix3x3::Scale(bodyB.InverseInertia) * Matrix3x3::Rotate(bodyB.Orientation); float normalVelocity = Vector3::Dot(velocity, contactNormal); if (normalVelocity > 0.f) { float impulseDenominator = bodyA.InverseMass + bodyB.InverseMass + Vector3::Dot(Vector3::Cross(inverseWorldInertiaTensorA * Vector3::Cross(originA, contactNormal), originA), contactNormal) + Vector3::Dot(Vector3::Cross(inverseWorldInertiaTensorB * Vector3::Cross(originB, contactNormal), originB), contactNormal); float j = -normalVelocity / impulseDenominator; bodyA.Velocity += j * bodyA.InverseMass * contactNormal; bodyB.Velocity -= j * bodyB.InverseMass * contactNormal; bodyA.AngularVelocity += j * (inverseWorldInertiaTensorA * Vector3::Cross(originA, contactNormal)); bodyB.AngularVelocity -= j * (inverseWorldInertiaTensorB * Vector3::Cross(originB, contactNormal)); } Thanks in advance!
    • By Luca Falco
      https://www.youtube.com/watch?v=UMoc52DEoC8     ABOUT THE GAME: Room54 is a first-person Horror/adventure  Videogame for pc,mac and linux users. the game is currently under development by a very small team, we put so much effort in this project and we are keep doing our best for that we are going to launch a kickstarter campaing in order to reach our ideal budget to complete the project, we hope the GameDev community can help us a lot                      STORY:   Daniel is a family father like many other, one day he decide with your wife and his daughter  to spend her winter holidays at their mountain house that they have recently buy in  mountain ,a  wonderful place surrounded by the nature of the woods,  Completely far away from the caotic city life. During their holidays Daniel and his family will understand that they are not welcome there and they will discover an  hided and disturbing part of the valley that they have never seen before                       GAMEPLAY:   You will play as Daniel, a father that will try to save his family, your gameplay will be focused on discovering secrets places around valley,investigating and trying to survive, you will find object that will help you solve enigma and to stay alive. The immersive audio and  environment will make you feel constantly follow by an high anxiety dose  during the game.                         SOCIAL PAGES:     Follow us to get the latest development news and insights     IndieDB:     http://www.indiedb.com/games/room54   Twitter:       https://twitter.com/Room54Thegame   facebook:   https://www.facebook.com/Room54/
    • By Gnollrunner
      Hi again,  After some looking around I have decided to base my game directly on Direct X rather than using an existing game engine.  Because of the nature of the stuff I'm doing it just didn't seem to fit very well and I kept running into road blocks.  At this point I have a big blob of code for doing fractal world generation and some collision code,  and I'm trying to put it into some form that resembles a game engine.  Since I've never used one before It's a bit alien to me ..... so can someone direct me to a book, website, article, whatever... that covers this?  I'm mainly looking for stuff that covers C++ library design. I'm not adverse to using 3rd party tools for stuff I can used them for.
    • By mmmax3d
      Hi everyone,
      I would need some assistance from anyone who has a similar experience
      or a nice idea!
      I have created a skybox (as cube) and now I need to add a floor/ground.
      The skybox is created from cubemap and initially it was infinite.
      Now it is finite with a specific size. The floor is a quad in the middle
      of the skybox, like a horizon.
      I have two problems:
      When moving the skybox upwards or downwards, I need to
      sample from points even above the horizon while sampling
      from the botton at the same time.  I am trying to create a seamless blending of the texture
      at the points of the horizon, when the quad is connected
      to the skybox. However, I get skew effects. Does anybody has done sth similar?
      Is there any good practice?
      Thanks everyone!
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!