Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 如何在顶点着色器中变换顶点以获得3D广告牌_Opengl_3d_Shader_Vertex Shader_Geometry Shader - Fatal编程技术网

Opengl 如何在顶点着色器中变换顶点以获得3D广告牌

Opengl 如何在顶点着色器中变换顶点以获得3D广告牌,opengl,3d,shader,vertex-shader,geometry-shader,Opengl,3d,Shader,Vertex Shader,Geometry Shader,我正在尝试实现顶点着色器代码,以实现给定顶点网格上的“公告牌”行为。我想要的是正常定义网格(如3D对象),然后使其始终面向摄影机。我还需要它总是有相同的大小(屏幕明智)。这两个“效应”应该发生: 在我的例子中唯一的区别是,我想要一个3D对象,而不是一个二维条 为了做到这一点,我试图遵循中的备选方案3(图像的拍摄位置相同),但我无法理解他们所做的许多假设(可能是因为我缺乏图形和OpenGL方面的经验) 我的着色器将公共变换堆栈应用于顶点,即: gl_Position = project * vi

我正在尝试实现顶点着色器代码,以实现给定顶点网格上的“公告牌”行为。我想要的是正常定义网格(如3D对象),然后使其始终面向摄影机。我还需要它总是有相同的大小(屏幕明智)。这两个“效应”应该发生:

在我的例子中唯一的区别是,我想要一个3D对象,而不是一个二维条

为了做到这一点,我试图遵循中的备选方案3(图像的拍摄位置相同),但我无法理解他们所做的许多假设(可能是因为我缺乏图形和OpenGL方面的经验)

我的着色器将公共变换堆栈应用于顶点,即:

gl_Position = project * view * model * position;
其中,
position
是具有世界空间中顶点位置的输入属性。我希望能够应用模型变换(例如平移、缩放和旋转)来修改对象相对于摄影机的方向。我理解教程中解释的概念,但我似乎无法理解如何将它们应用到我的案例中

我尝试了以下内容(摘自本教程,与本教程类似):

但我得到的是一个形状,当离相机越近时,它的尺寸越大,否则就越小。我忘了什么吗

是否可以在顶点着色器中执行此操作

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
depth),您不必跟踪屏幕的纵横比(正如链接教程所做的那样)。但这取决于投影矩阵。

我要做的是按
(视图*中心)z缩放模型矩阵,以便屏幕上的大小始终相同。对于实际的方向矩阵,它应该是视图矩阵的转置(因此它们都被抵消)。谢谢,这解决了问题。然而,我想知道,这个操作背后的数学原理是什么。为什么到摄影机的距离(我认为
dist
变量表示的距离)必须乘以每个顶点的x和y坐标?透视使对象在一定距离内看起来更小,因此您只需相对于该距离放大它们。也可以是
vec4(position.xyz*dist,0)
,正如您所说,您有一个3D对象要渲染。
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));