在屏幕坐标中平移对象
Translate an object in screen coordinates
我在 OpenGL (WebGL) 中有一个对象,我对它的外观很满意,并且想将它向左移动一点。但是,当我这样做时,它的视角会发生变化。我想保持原样,只是在不同的地方渲染它。
我认为我使用的是相当标准的设置,带有投影和模型视图矩阵。我尝试以各种方式改变两者,但我只能让我的对象在 3D space 中移动,而不是在平面屏幕或眼睛坐标中移动。任何想法如何做到这一点(例如不渲染到纹理)?
部分代码摘录。这些函数做了显而易见的事情,它们取自 Mozilla WebGL 教程。我认为确切的定义并不重要。
// set perspective matrix
var perspectiveMatrix = makePerspective(45, 640.0/480.0, 0.1, 100.0);
loadIdentity();
// set modelview matrix
mvTranslate([0, 0, -12]);
mvRotate(rotationAngle, [0, 1, 0]);
// and then I just draw an object...
在顶点着色器中:
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
老实说,我觉得具体的代码对于这道题来说并不是那么重要。请不要挂断电话。我可以使用 Three.js,或 DirectX,或手写的光线追踪器。我将重新表述问题:在标准形式中,屏幕坐标是通过矩阵乘法从模型坐标计算得出的:
u = Perspective * ModelView * x
我想在屏幕上移动 u
。我可以手动完成:
u.x += deltaX
u.y += deltaY
但是有没有办法利用透视矩阵来达到同样的效果呢?是否有 "standard" 方法在视图 space 中引入转换? OpenGL 中有方便的功能吗?
好的,我想我已经弄明白了。要进行翻译,您需要乘以翻译矩阵(这里的语法来自 Mozilla WebGL 教程,它结合使用 sylvester.js 和它自己的函数,但实际上只是将其视为伪代码)。
以下将一个单位向左翻译,一个向侧面翻译。
var shift = Matrix.Translation($V([-1, -1, 0]));
如果你的对象在屏幕中间 (0, 0),你的坐标从左下角 (-1, -1) 到右上角 (1, 1),这会把你的左下角的对象。
现在的关键是记住矩阵乘法通常是不可交换的。所以你不能做perspective x something
,它必须是something x perspective
。这样,当您作用于模型向量时,首先应用透视,然后应用您的转变:
var shiftedPerspectiveMatrix = shift.x(perspectiveMatrix)
作为奖励,以下是如何在像素坐标中执行此操作:
// for referece:
var perspectiveMatrix = makePerspective(45, 640.0/480.0, 0.1, 100.0);
var trans = Matrix.Translation($V([-1, -1, 0]));
var scale = Matrix.Diagonal([320, 240, 1, 1]);
// move 100 pixels to the left
var viewShift = Matrix.Translation($V([-100, 0, 0]));
let transI = trans.inv();
let scaleI = scale.inv();
var newPerspectiveMatrix = transI.x(scaleI).x(viewShift).x(scale).x(trans).x(perspectiveMatrix);
要记住的是,当M是一个矩阵时,M−1 M 是一个空操作。应用M后,你生活在一个不同的坐标系中。因此,如果要应用的变换 A 是在该不同的坐标系中定义的,则可以执行 x' = M−1 A M x.
抱歉,如果我弄乱了订单。好久没学解析几何和线性代数了
现在上面的代码所做的是,它将坐标更改为人类可理解的系统(屏幕像素,尽管原点位于中心),应用我想要进行的移动,然后转换回 OpenGL -可理解的系统。注意应用是从右到左的,我撤消操作的顺序是相反的
我在 OpenGL (WebGL) 中有一个对象,我对它的外观很满意,并且想将它向左移动一点。但是,当我这样做时,它的视角会发生变化。我想保持原样,只是在不同的地方渲染它。
我认为我使用的是相当标准的设置,带有投影和模型视图矩阵。我尝试以各种方式改变两者,但我只能让我的对象在 3D space 中移动,而不是在平面屏幕或眼睛坐标中移动。任何想法如何做到这一点(例如不渲染到纹理)?
部分代码摘录。这些函数做了显而易见的事情,它们取自 Mozilla WebGL 教程。我认为确切的定义并不重要。
// set perspective matrix
var perspectiveMatrix = makePerspective(45, 640.0/480.0, 0.1, 100.0);
loadIdentity();
// set modelview matrix
mvTranslate([0, 0, -12]);
mvRotate(rotationAngle, [0, 1, 0]);
// and then I just draw an object...
在顶点着色器中:
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
老实说,我觉得具体的代码对于这道题来说并不是那么重要。请不要挂断电话。我可以使用 Three.js,或 DirectX,或手写的光线追踪器。我将重新表述问题:在标准形式中,屏幕坐标是通过矩阵乘法从模型坐标计算得出的:
u = Perspective * ModelView * x
我想在屏幕上移动 u
。我可以手动完成:
u.x += deltaX
u.y += deltaY
但是有没有办法利用透视矩阵来达到同样的效果呢?是否有 "standard" 方法在视图 space 中引入转换? OpenGL 中有方便的功能吗?
好的,我想我已经弄明白了。要进行翻译,您需要乘以翻译矩阵(这里的语法来自 Mozilla WebGL 教程,它结合使用 sylvester.js 和它自己的函数,但实际上只是将其视为伪代码)。
以下将一个单位向左翻译,一个向侧面翻译。
var shift = Matrix.Translation($V([-1, -1, 0]));
如果你的对象在屏幕中间 (0, 0),你的坐标从左下角 (-1, -1) 到右上角 (1, 1),这会把你的左下角的对象。
现在的关键是记住矩阵乘法通常是不可交换的。所以你不能做perspective x something
,它必须是something x perspective
。这样,当您作用于模型向量时,首先应用透视,然后应用您的转变:
var shiftedPerspectiveMatrix = shift.x(perspectiveMatrix)
作为奖励,以下是如何在像素坐标中执行此操作:
// for referece:
var perspectiveMatrix = makePerspective(45, 640.0/480.0, 0.1, 100.0);
var trans = Matrix.Translation($V([-1, -1, 0]));
var scale = Matrix.Diagonal([320, 240, 1, 1]);
// move 100 pixels to the left
var viewShift = Matrix.Translation($V([-100, 0, 0]));
let transI = trans.inv();
let scaleI = scale.inv();
var newPerspectiveMatrix = transI.x(scaleI).x(viewShift).x(scale).x(trans).x(perspectiveMatrix);
要记住的是,当M是一个矩阵时,M−1 M 是一个空操作。应用M后,你生活在一个不同的坐标系中。因此,如果要应用的变换 A 是在该不同的坐标系中定义的,则可以执行 x' = M−1 A M x.
抱歉,如果我弄乱了订单。好久没学解析几何和线性代数了
现在上面的代码所做的是,它将坐标更改为人类可理解的系统(屏幕像素,尽管原点位于中心),应用我想要进行的移动,然后转换回 OpenGL -可理解的系统。注意应用是从右到左的,我撤消操作的顺序是相反的