如何使广告牌球形 [英] How to make a billboard spherical

查看:241
本文介绍了如何使广告牌球形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此之后turorial 这里

Following this turorial here

我已经成功地创造出一个圆柱形的广告牌(它利用几何着色器这需要点并产生四边形)。问题是,当我移动相机,使它比广告牌高(使用gluLookat)广告牌不旋转,真正面对镜头(好像它是一个圆柱形的广告牌)。

I have managed to create a cylindrical billboard (it utilizes a geometry shader which takes points and produces quads). The problem is that when i move the camera so that it's higher than the billboard (using gluLookat) the billboard does not rotate to truly face the camera (as if it was a cylindrical billboard).

我如何让它成球形?

如果有兴趣的人,这里略作修改几何着色器code:

if anyone interested, here is slightly modified geometry shader code:

#version 330
//based on a great tutorial at http://ogldev.atspace.co.uk/www/tutorial27/tutorial27.html

layout (points) in;
layout (triangle_strip) out;
layout (max_vertices = 4) out;

uniform mat4 mvp;
uniform vec3 cameraPos;

out vec2 texCoord;

void main(){
    vec3 pos = gl_in[0].gl_Position.xyz;
    pos /= gl_in[0].gl_Position.w; //normalized device coordinates
    vec3 toCamera = normalize(cameraPos - pos);
    vec3 up = vec3(0,1,0);
    vec3 right = normalize(cross(up, toCamera)); //right-handed coordinate system
    //vec3 right = cross(toCamera, up); //left-handed coordinate system

    pos -= (right*0.5);
    gl_Position = mvp*vec4(pos,1.0);
    texCoord = vec2(0,0);
    EmitVertex();

    pos.y += 1.0;   
    gl_Position = mvp*vec4(pos,1.0);
    texCoord = vec2(0,1);
    EmitVertex();

    pos.y -= 1.0;   
    pos += right;
    gl_Position = mvp*vec4(pos,1.0);
    texCoord = vec2(1,0);
    EmitVertex();

    pos.y += 1.0;       
    gl_Position = mvp*vec4(pos,1.0);
    texCoord = vec2(1,1);
    EmitVertex();
}

编辑: 正如我以前说过,我曾尝试3,3-子矩阵设置为身份的方法。我可能解释的行为不对,但这种GIF应该做的更好:

As I said before, I have tried the approach of setting the 3,3-submatrix to identity. I might have explained the behaviour wrong, but this gif should do it better:

在上面的图片,旋转相机使用的身份子矩阵方法的广告牌(红色)。 的广告牌,但是,不应该移动通过表面(白色),它应该保持它的正确位置,并始终在表面上,这不会发生的一侧

In the picture above, the camera is rotated with the billboard (red) using identity submatrix approach. The billboard, however, should not move through the surface (white), it should maintain it's position correctly and always be on one side of the surface, which does not happen.

推荐答案

在万一有人想知道我是如何解决这一点。
我有一个基于我对Quonux的回答解决方案,它唯一的问题是,广告牌将旋转速度非常快,当相机正上方时(最高矢量几乎平行到摄像机外表向量)。这种奇怪的行为是使用一个跨产品找到右键载体的结果:当相机悬停在广告牌的上面,跨产品改变它的标志,等等请问右键矢量的方向。这解释了出现这种情况的旋转。
因此,所有我需要的是用一些其他的方法来找到右键载体。 当我知道摄像机的旋转角度(水平和垂直),我决定用它来寻找右键矢量:

In case anyone wonders how I solved this.
I have based my solution on Quonux's answer, the only problem with it was that the billboard would rotate very fast when the camera is right above it (when the up vector is almost parallel to the camera look vector). This strange behaviour is a result of using a cross product to find the right vector: when the camera hovers over the top of the billboard, the cross product changes it's sign, and so does the right vector's direction. That explains the rotation that happens.
So all I needed was to find a right vector using some other way. As I knew camera's rotation angles (both horizontal and vertical) I decided to use that to find a right vector:

rotatedRight = Vector4.Transform(unRotatedRight, Matrix4.CreateRotationY((-alpha)));

和几何着色器:

...
uniform vec3 rotRight;
uniform vec3 cameraPos;

out vec2 texCoord;

void main(){

vec3 pos = gl_in[0].gl_Position.xyz;
pos /= gl_in[0].gl_Position.w; //normalized device coordinates
vec3 toCamera = normalize(cameraPos - pos);

vec3 CrossA = rotRight;
... (Continues as Quonux's code)

这篇关于如何使广告牌球形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆