Question

I have a 2D mode which displays moving sprites over the world. each sprite has rotation.

When i'm trying to implement the same in 3D world, over a sphere, i met a problem calculating the sprite rotation so it will look like it is moving toward the direction. I'm aware that the sprite is billboard only and the rotation will be 2D only, and will not be 100% rotated toward the direction but at least to make it look reasonable for the eye.

The 2D Mode that works fine The problem in the 3D Mode

I've tried to consider the vector to the north (of the world) in my rotation but still, there are allot of cases when we move the camera around the sphere that the sprite arrow is not in the direction of the movement.

Can anyone direct me for a solution ?

-------- ADDITION -----------

More explanation: I have 2D world (x,y). In this world I have a point that moves toward a direction (an angle is saved in the object). The rotations are calculated in the fragment shader of course.

In the 3D world, i'm converting this (x, y) to a (x,y,z) by simple sphere formula. My sphere (world) origin is (0,0,0) with radius 1.

The angle (saved in the point for the direction of movement) is used in 2D for rotating the texture as well (As shown above in the first image). The problem is the rotation of the texture in 3D. The rotating should consider the point direction angle, and the camera.

-------- ADDITION -----------

My fragment shader for 2D - If it is helping. And few more pictures and my wish

varying vec2 TextureCoord;
varying vec2 TextureSize;
uniform sampler2D sampler;

varying float angle;
uniform vec4 uColor;

void main()
{
    vec2 calcedCoord = gl_PointCoord;
    float c = cos(angle);
    float s = sin(angle);
    vec2 trans = vec2(-0.5, -0.5);
    mat2 rot = mat2(c, s, -s, c);
    calcedCoord = calcedCoord + trans;
    calcedCoord = rot * calcedCoord;
    calcedCoord = calcedCoord - trans;

    vec2 realTexCoord = TextureCoord + (calcedCoord * TextureSize);
    vec4 fragColor = texture2D(sampler, realTexCoord);
    gl_FragColor = fragColor * uColor;
}

enter image description here enter image description here enter image description here enter image description here enter image description here

Was it helpful?

Solution

After struggling allot with this issue I came into this solution.

Instead of attaching as attribute the direction angle to each sprite, I sent the next sprite location instead. And calculating the 2D angle in the vertex shader as follow:

varying float angle;

attribute vec3 nextPointAtt;

void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;    
    vec4 nextPnt = gl_ModelViewProjectionMatrix * vec4(nextPointAtt, gl_Vertex.w);

    vec2 ver = gl_Position.xy / gl_Position.w;
    vec2 nextVer = nextPnt.xy / nextPnt.w;

    vec2 d = nextVer - ver;
    angle = atan(d.y, d.x);
}

The angle will be used in the fragment shader (Look at my question for the fragment shader code).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top