如何转换顶点着色器中的顶点以获得3D广告牌
我正在尝试实现顶点着色器代码以实现给定顶点网格上的“广告牌”行为。我想要的是正常定义网格(如3D对象),然后让它始终面向相机。我也需要它始终具有相同的尺寸(屏幕式)。这两个“效果”应该发生:如何转换顶点着色器中的顶点以获得3D广告牌
在我的情况下,唯一的区别是,而不是2-d吧,我想有一个3D物体。
要做到这一点,我试图按照this tutorial中的替代方案3(图片取自同一位置),但我无法弄清楚他们提出的很多假设(可能是由于我缺乏在图形和OpenGL方面的经验)。
我着色器应用常见的转换堆栈的顶点,即:
gl_Position = project * view * model * position;
哪里position
是在世界空间顶点位置输入属性。我希望能够应用模型转换(例如平移,缩放和旋转)来修改对象相对于相机的方向。我理解本教程中解释的概念,但我似乎无法理解将其应用于我的案例。
我已经试过是以下(从这个answer提取,类似的教程):
uniform vec4 billbrd_pos;
...
gl_Position = project * (view * model * billbrd_pos + vec4(position.xy, 0, 0));
但我得到的是一个形状的大小更接近时更大相机,否则更小。我忘了什么吗?
是否可以在顶点着色器中做到这一点?
uniform vec4 billbrd_pos;
...
vec4 view_pos = view * model * billbrd_pos;
float dist = -view_pos.z;
gl_Position = project * (view_pos + vec4(position.xy*dist,0,0));
这样的片段深处仍然是正确的(在billbrd_pos
深度)和你没有保持跟踪屏幕的宽高比(如链接的教程一样)。它依赖于投影矩阵。
谢谢你解决了这个问题。但是,我想知道这个操作的基本数学是什么。为什么到摄像机的距离(我认为'dist'变量代表的距离)必须乘以每个顶点的___x___和___y___坐标? –
透视使物体在一定距离处看起来更小,所以你只需要将它们放大,相对于那个距离。也可以是'vec4(position.xyz * dist,0)',如你所说你有一个3D对象来渲染。 – pleluron
我会做的是通过'(view * center).z'缩放模型矩阵,因此屏幕上的大小总是相同的。对于实际的方向矩阵,它应该是视图矩阵的转置(所以它们都抵消)。 – pleluron