游戏世界三维坐标转换为屏幕坐标原理分析:三角函数转换与矩阵变换
在3D游戏中获得游戏人物敌人坐标xyz后,并不能直接绘制到屏幕上,需要进行一系列的转换算法,目前主流的算法包括三角函数转换与矩阵变换,三角函数转换方法过时且繁琐,这里不推荐使用,本文主讲矩阵变换原理:
一、游戏中多种坐标矩阵的转换关系
游戏中用CE可以找到敌人的world space坐标,也就是XYZ的游戏世界空间坐标, 通过矩阵变换得到Clip Space坐标(剪切坐标),通过透视分割算法得到NDC坐标,最后将NDC坐标视窗映射矩阵即可获得屏幕坐标。
二、D3D和opengl中矩阵存储形式
Direct3D 采用行主序(Row major)存储
“Effect matrix parameters and HLSL matrix variables can define whether the value is a row-major or column-major matrix; however, the DirectX APIs always treat D3DMATRIX and D3DXMATRIX as row-major.”
OpenGL 采用列主序(Colume major)存储
“The m parameter points to a 4x4 matrix of single- or double-precision floating-point values stored in column-major order. That is, the matrix is stored as follows”
存储顺序说明了线性代数中的矩阵如何在线性的内存数组中存储,d3d 将每一行在数组中按行存储,而opengl将每一列存储到数组的每一行中:
因此,对于线程代数中的同一个矩阵,则在d3d和OpenGL中有不同的表示形式:
线代矩阵:a11,a12,a13,a14 d3d保存: a11,a12,a13,a14 OpenGL保存: a11,a21,a31,a41a21,a22,a23,a24 a21,a22,a23,a24 a12,a22,a32,a42a31,a32,a33,a34 a31,a32,a33,a34 a13,a23,a33,a43a41,a42,a43,a44 a41,a42,a43,a44 a14,a24,a34,a44
三、算法实现流程(以D3D为例)
1.假设敌人的世界坐标为X, Y, Z,W;其中W为其次项,一般设置为1(D3D规范如此,这个不必计较)
2.计算剪切坐标:
剪切坐标X = a11*X + a12*Y + a13*Z + a14
剪切坐标Y = a21*X + a22*Y + a23*Z + a24
剪切坐标Z = a31*X + a32*Y + a33*Z + a34
剪切坐标W = a41*X + a42*Y + a43*Z + a44
(此处注意设置筛选条件,仅剪切坐标w>0的才可以继续以下操作,小于0的可以忽略,因为不在你的视角内,PS:不信的同学可以最后试一下加与不加的区别)
3.计算NDC坐标:(透视分割算法:用剪切坐标XYZ除以W即可)
NDC坐标X = 剪切坐标X / 剪切坐标W
NDC坐标Y = 剪切坐标Y / 剪切坐标W
NDC坐标Z = 剪切坐标Z / 剪切坐标W
4.NDC坐标转屏幕坐标:
转换公式如下:
屏幕坐标.x = 窗口宽度 ÷ 2 × NDC坐标.x + NDC坐标.x + 窗口宽度 ÷ 2
屏幕坐标.y = -(窗口高度 ÷ 2 × NDC坐标.y) + NDC坐标.y + 窗口高度 ÷ 2
至此,已经描述完世界坐标转换屏幕坐标的算法了
如果对NDC转屏幕坐标感兴趣的小伙伴可以继续往下看:
四、NDC转屏幕公式解析
如图所示,我们通过视口变换矩阵ViewPort与NDC坐标进行矩阵乘,即可得到以上公式,但是对于屏幕坐标Y的公式不可由该矩阵乘推得,注意公式前面的符号:屏幕坐标.y = -(窗口高度 ÷ 2 × NDC坐标.y) + NDC坐标.y + 窗口高度 ÷ 2,
按照矩阵乘推理,应该没有负号,但是此处有,原因如下:
先普及下正常的屏幕坐标系和屏幕视口坐标系的区别:
由此可以知道,在与VIewPort做矩阵乘运算中,Y应该为与原来相反,所以在
[x,
y;
z,
1]竖矩阵中将y加上符号,再做矩阵乘,即可得到以上正确的算法公式,自己动手算一遍就会懂了。
参考文献:
https://www.bilibili.com/video/BV1UK4y1D781/?spm_id_from=trigger_reload
https://www.cnblogs.com/icmzn/p/13531265.html
https://space.bilibili.com/442168898/channel/detail?cid=123750
https://www.bilibili.com/video/av286268338/
游戏世界三维坐标转换为屏幕坐标原理分析:三角函数转换与矩阵变换相关推荐
- 三维坐标转换为二维坐标
三维坐标转换为二维坐标 最近做项目用到三维坐标转换为二维平面坐标的转换公式.看了网上的很多资料,都不太适用自己的项目.最后决定自己来推导. 具体问题描述 如下图所示,将二维平面上的三维坐标系O-X'Y ...
- 经纬度坐标转换为屏幕坐标
经纬度坐标转换成屏幕坐标 地理坐标定义规则:X轴(代表经度)向右递增,Y轴(纬度)向上递增,就好比小学学过的平面坐标.向左.向下的规则.屏幕坐标定义规则:X轴向右递增,Y轴向下递增. 可以看出,地理坐 ...
- java地理坐标转屏幕_(转)经纬度坐标转换为屏幕坐标
经纬度坐标转换成屏幕坐标 地理坐标定义规则:X轴(代表经度)向右递增,Y轴(纬度)向上递增,就好比小学学过的平面坐标.向左.向下的规则.屏幕坐标定义规则:X轴向右递增,Y轴向下递增. 可以看出,地理坐 ...
- 三维视觉 | 01 摄像机原理及坐标系转换
最早接触视觉三维是本科毕设的时候,当时做的是目标检测与三维定位.所以一直想有机会也分享一下视觉三维重建的知识,最近有空,索性就将一些零碎的知识整理分享出来,有问题欢迎大家评论区留言! 文章目录 一.摄 ...
- 目前已知摄像头的三维坐标和三维朝向,已知摄像头画面宽高,某一物体在该画面中的位置坐标,以及该物体中心距离摄像头的距离,求该物体在现实世界中的坐标,用c++实现,使用小孔成像原理,直接上代码...
求解这个问题的过程可以分为以下步骤: 将摄像机坐标系下的物体坐标转换为图像坐标系下的坐标,图像坐标系下的坐标是以图像左上角为原点,x轴向右,y轴向下的二维平面坐标. 将图像坐标系下的坐标转换为归一化平 ...
- 【我的世界原理分析】1.光照原理
[我的世界原理分析]1.光照原理 前言 1.平滑光照 2.环境光 3.光照算法 前言 最近在研究类我的世界这样的游戏,方便以后开发以及提供给更多人一个思路.大家多多评论留言我会不断更新更多相关内容. ...
- 三维坐标 偏转_三维坐标变换原理-平移, 旋转, 缩放
给定一个二维点(x, y),那么形如(kx, ky, k)的所有三元组就都是等价的,它们就是这个点的齐次坐标(homogeneous).齐次坐标就是将一个原本是n维的向量用一个n+1维向量来表示,是指 ...
- OpenGL 获取当前屏幕坐标对应的三维坐标
转自原文 OpenGL 获取当前屏幕坐标对应的三维坐标,使用很简单glu库中的一个函数 #include <GL/glut.h> #include <stdlib.h> #in ...
- 游戏光枪坐标定位原理及算法
http://b2b.hc360.com/supplyself/347075653.html 品牌: CRZMAN 型号: WII 适用送礼场合: 广告促销,商务馈赠,节日,乔迁,生日,展销会,开业典 ...
最新文章
- POJ 2976 Dropping tests【二分 最大化平均值】
- java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory
- C++学习笔记——虚函数
- mysql三高讲解(二):2.1 索引组织表
- Spark Streaming实例
- C语言常用库函数(含详细用法)
- FORTRAN文件读写操作 from《FORTRAN95 程序设计》
- 鞋店商城小程序开发价值
- 使用Visual Paradigm画ER图/Visual ER图
- 毕业论文尾注和参考文献
- centos系统添加桌面图标
- SpringBoot将图片/文件传至前端
- 【C语言】函数详解(入门到进阶)
- 《U-Net: Convolutional Networks for Biomedical Image Segmentation》学习笔记
- 【读书推荐】中国是部金融史
- Java实现 LeetCode 476 数字的补数
- 电脑连接蓝牙耳机声音总是断断续续:
- javac -d . hello.java中的 -d .是什么作用?
- ShareSDK移动APP社会化分享组件
- 【安信可A9G专题⑤】A9G模组AT指令MQTT接入阿里云实现APP控制