在我的iPhone应用程序中,我需要将3D场景投影到屏幕的2D坐标中进行一些计算.我的对象经历了各种旋转,平移和缩放.所以我想我首先需要将顶点与ModelView矩阵相乘,然后我需要将它与正交投影矩阵相乘.
首先是在正确的轨道上?
我有模型视图矩阵,但需要投影矩阵.ES 2.0中是否有glOrtho()等价物?
我使用两个投影矩阵P1和P2(例如我使用恐龙数据集),我需要计算基本矩阵F.所以我使用两个Matlab函数:
这些函数应该做同样的事情,但我有一个不同的F值!怎么可能?哪个是正确的功能?
如果在两个不同的图像中两个点X1和X2"相同",则X2 ^ T*F*X1 = 0 ...因此我通过使用SURF从两个旋转图像(5度)找到两个对应点,但是X2 ^ T*这两个版本的F*X1永远不会等于零.有任何想法吗?
相反,如果我使用此函数从匹配点计算F:
我有X2 ^ T*F*X1 = 0 ....显然F不同于两个FI与其他两个功能...
matlab computer-vision perspectivecamera projective-geometry projection-matrix
我一直在尝试按照本教程的指示实现屏幕空间环境光遮挡.我一直在解决我的实施问题,因为我遇到过它们,但这一次让我感到难过.
我对该方法的理解如下.环境遮挡因子由从与给定片段的法线对齐的半球内取得的样本确定.为了确定样本是否有助于环境遮挡因子,我必须根据视图空间深度纹理(包含在此帖子图像的左下角)检查视图空间中的样本深度.所以我知道从深度纹理中取出哪些坐标,我必须将样本的坐标从视图空间转换为规范化设备坐标(在[-1,1]范围内),然后转换到范围[0 ,1],因此深度纹理有效地"映射"到视口.
下面的图像是我的场景中的环境遮挡.我知道环境遮挡本身有一个相当明显的问题(我假设半球的方向不正确),我会及时处理,但是目前我的好奇心是"闭塞"的外观是什么',表明我从视空间样本坐标移动到纹理坐标的操作是不正确的.
由于我缺少一个稳定的着色器调试器,我可以做的调试仅限于我可以渲染到屏幕上的内容.使用以下代码创建下一个图像,其中ndcs是给定样本的规范化设备坐标:
if (ndcs.x > 1.0f || ndcs.y > 1.0f || ndcs.x < -1.0f || ndcs.y < -1.0f)
{
gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
else
{
gl_FragColor = vec4(vec3(1.0f), 1.0f);
}
Run Code Online (Sandbox Code Playgroud)
我希望图像完全是白色的(或者更确切地说,我正在使用这个着色器的位),但是它似乎表明我正在创建的NDC在[-1,1]范围之外,我相信一定是不正确的.它也不是屏幕的一致区域,如下图所示,相机非常接近表面:
我以前从未使用过这个程序来获取NDC,所以我确信我的逻辑在某处肯定是错的.我已经下载了教程提供的演示代码,但我无法看到代码的不同之处.我也在网上搜索过(包括在这个网站上)我似乎无法找到任何与我自己症状相同的人.
这是我的着色器的相关代码:
Vert Shader:
v_eye_space_position = u_mvpMatrix * a_position;
v_world_space_normal = normalize(u_rotationMatrix * a_normal);
v_eye_space_normal = normalize(u_mvpMatrix * a_normal);
gl_Position = v_eye_space_position;
Run Code Online (Sandbox Code Playgroud)
Frag Shader:
// --- SSAO Testing ---
// Convert from the noise texture back to [-1,1] range …
Run Code Online (Sandbox Code Playgroud) 想象一下,在一个球体中包含一组混合的3D物体,您的目标是创建整个场景的圆柱形等面积投影.使用OpenGL,你可能想从在后处理着色器旋转的摄像机绕中心轴线,然后校正径向失真缝合在一起的多个渲染目标纹理(4是精确的),因为上投影的平面上,而不是一个圆筒.理想情况下,你能够通过球的整个体积扫相机的平截头体,没有任何重叠,并且使得每个渲染填充矩形纹理的整个像素的空间(如圆柱形突起做).
因此,为了清楚起见,这里是球形场景(其中包含对象)的可视化,以及围绕Y轴跨越PI/2的相机平截头体.
请注意,"远"平面缩小为一条直线,该直线与球体的Y轴共线.在平截头体的外表面上形成"X"的白色相交线表示相机的原点,或者在眼睛空间中的(0,0,0).该外表面也是"近"平面,距离相机0 Z单位.
这个想法是,球体的中心轴项目光线向外,使得所有的光线行进平行于Y平面(即,具有正常的平面(0,1,0)),并且每个射线从球体发出的原点相交的球体的表面在垂直角度.
天真地,我认为OpenGL投影矩阵可以做到这一点 - 据我所知,我在这里的预测是线性的,因此可能吗?但是,我似乎无法正确解决方程式:
让我们s
成为球体的半径.
因此,在眼睛空间,从相机的起源:在OpenGL投影矩阵中:
- 近平面的左右边缘分别位于X轴
-s
和s
X轴的单位- 近平面的顶部和底部边缘分别位于Y轴
s
和-s
Y轴的单位- 远平面的左右边缘共同位于
-s
沿Z轴的单位(请记住,在眼睛空间中,Z值在相机前面是负的)
-w_c < x_c < w_c
x_n = x_c / w_c
由于左右平截头体平面汇聚在相机前面,我解决了一个方程式,将我的输入映射到它们的预期输出,并得出结论:这意味着
x_n = x_e / (z_e + s)
x_c = x_e
和w_c = z_e + s
.这在我的投影矩阵上填充了两行:
---------- 这就是我被卡住的地方 ----------
很明显,y_n
它不依赖于x_e
或根本不存在z_e
,它的等式应该是:这类似于正交投影.然而,这引入了与
y_n = y_e / s
w_c
我已经在 …
我正在尝试在背景图像(正投影)上渲染一些带有Frustum投影的网格.无论我做什么,背景图像都会保持在场景之上(隐藏网格物体).
我尝试过一点测试 - 当我用相同的投影矩阵渲染它们时,它们的顺序是正确的 - 背景图像在网格后面.
这些是投影矩阵和Depth-Buffer init:
glEnable(GL_DEPTH_TEST);
glClearDepthf( 1.0f );
glDepthFunc( GL_LEQUAL );
glDepthMask (GL_TRUE);
EGLConfig eglconfig;
EGLint const attrib_list[] = {
EGL_DEPTH_SIZE, 16,
EGL_NONE
};
EGLint numreturned;
CHECK(eglChooseConfig(esContext.eglDisplay, attrib_list, &eglconfig, 1, &numreturned) != EGL_FALSE);
float fieldOfView = 60.0;
float znear = 0.1f;
float zfar = 100000;
float size = (float)(znear * tanf((fieldOfView * M_PI /180.0f) / 2.0f));
m_orthoProjMatrix.loadOrtho(0,
screenWidth,
0,
screenHeight,
znear,
zfar);
m_frustProjMatrix.loadFrustum(-size,
size,
-size / (screenWidth / screenHeight),
size / (screenWidth / screenHeight),
znear,
zfar); …
Run Code Online (Sandbox Code Playgroud) opengl-es frustum orthographic projection-matrix opengl-es-2.0
我想将我的视觉里程计结果与 KITTI 数据集提供的地面实况进行比较。对于groundthruth 中的每一帧,我都有一个投影矩阵。例如:
1.000000e+00 9.043683e-12 2.326809e-11 1.110223e-16 9.043683e-12 1.000000e+00 2.392370e-10 2.220446e-16 2.326810e-11 2.392370e-10 9.999999e-01 -2.220446e-16
Run Code Online (Sandbox Code Playgroud)
这里是自述文件提供的说明:
第 i 行通过 3x4 变换矩阵表示左相机坐标系的第 i 个姿势(即 z 指向前方)。矩阵按行对齐顺序存储(第一个条目对应于第一行),并在第 i 个坐标系中取一个点并将其投影到第一个(=第 0 个)坐标系中。因此,平移部分(第 4 列的 3x1 向量)对应于第 i 帧中左相机坐标系相对于第一个(=第 0)帧的姿态
但我不知道如何为我生成相同类型的数据。在我的情况下,我对每一帧都有什么:
有了这些数据,我如何与真实情况进行比较?所以我需要从上面的数据中找到投影矩阵,但不知道如何去做。
在大图中,我想获得一个投影矩阵或知道如何分解由地面实况提供的投影矩阵,以便将转换与我的数据进行比较。
有人能帮我吗 ?
谢谢
我需要使用渲染的深度图从屏幕空间位置计算3D坐标。不幸的是,使用常规光线追踪对我来说不是一种选择,因为我要处理的单个几何图形包含大约5M张面。
所以我想我将执行以下操作:
这种工作,但是以某种方式定位点总是在物体的后面,因此我的深度计算可能有问题。
渲染深度图非常简单:
const depthTarget = new THREE.WebGLRenderTarget(w, h);
const depthMaterial = new THREE.MeshDepthMaterial({
depthPacking: THREE.RGBADepthPacking
});
// in renderloop
renderer.setClearColor(0xffffff, 1);
renderer.clear();
scene.overrideMaterial = depthMaterial;
renderer.render(scene, camera, depthTarget);
Run Code Online (Sandbox Code Playgroud)
使用以下命令在鼠标位置查找存储的颜色值:
renderer.readRenderTargetPixels(
depthTarget, x, h - y, 1, 1, rgbaBuffer
);
Run Code Online (Sandbox Code Playgroud)
并使用(从packing.glsl中的GLSL版本改编)转换回float:
const v4 = new THREE.Vector4()
const unpackDownscale = 255 / 256;
const unpackFactors = new THREE.Vector4(
unpackDownscale / (256 * 256 * 256),
unpackDownscale / (256 * 256),
unpackDownscale / 256,
unpackDownscale
); …
Run Code Online (Sandbox Code Playgroud) 我使用相机参数calibrateCamera()
,现在我有cameraMatrix,distCoeffs,rotationMatrix,transformMatrix.
使用这些矩阵,我可以构建投影矩阵并将空间中的3D对象点转换为2D图像点.
有点像这样:
But what I want is the reverse of this projection. I want to convert these 2D points back into 3D space. I know I'll lost some information, but all of my original points were in a same plan.
Please help me to build a similar matrix by using camera parameters for this convertion.
opengl ×3
c++ ×2
opengl-es ×2
camera ×1
dataset ×1
depth-buffer ×1
frustum ×1
glsl ×1
glu ×1
matlab ×1
matrix ×1
opencv ×1
orthographic ×1
projection ×1
raycasting ×1
ros ×1
ssao ×1
three.js ×1
webgl ×1