2017-01-20 95 views
1

我正在尝试实现顶点着色器代码以实现给定顶点网格上的“广告牌”行为。我想要的是正常定义网格(如3D对象),然后让它始终面向相机。我也需要它始终具有相同的尺寸(屏幕式)。这两个“效果”应该发生:如何转换顶点着色器中的顶点以获得3D广告牌

Billboard in which the size is preserved despite the camera being far awayBillboard in which the rotation is fixed despite rotating the camera

在我的情况下,唯一的区别是,而不是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)); 

但我得到的是一个形状的大小更接近时更大相机,否则更小。我忘了什么吗?

是否可以在顶点着色器中做到这一点?

+0

我会做的是通过'(view * center).z'缩放模型矩阵,因此屏幕上的大小总是相同的。对于实际的方向矩阵,它应该是视图矩阵的转置(所以它们都抵消)。 – pleluron

回答

2
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深度)和你没有保持跟踪屏幕的宽高比(如链接的教程一样)。它依赖于投影矩阵。

+1

谢谢你解决了这个问题。但是,我想知道这个操作的基本数学是什么。为什么到摄像机的距离(我认为'dist'变量代表的距离)必须乘以每个顶点的___x___和___y___坐标? –

+2

透视使物体在一定距离处看起来更小,所以你只需要将它们放大,相对于那个距离。也可以是'vec4(position.xyz * dist,0)',如你所说你有一个3D对象来渲染。 – pleluron