problem: directional billboarding

problem: directional billboarding

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

problem: directional billboarding

Post by jK »

i am writting a particle system in lua and trying to convert the simpleparticle class to use shaders.

now i have a problem with the "directional" feature of csimpleparticle.
first what it does: it rotates the quad (it is still billboarded) so it points to the speed vector, i.e. an effect that start in a point and the particles escaping from it -> all quads would point away from the start point.
the code that does this is in worldspace:

Code: Select all

float3 dif(particles[i].pos-camera->pos);
float camDist=dif.Length();
dif/=camDist;
float3 dir1(dif.cross(particles[i].speed));
dir1.Normalize();
float3 dir2(dif.cross(dir1));
(dir1 is the up vector and dir2 the right vector)

now i can't copy this code, cuz i use the a vertex shader to billboard my quads. so i have to rotate the quads in eyespace, but all my tries (>4 different codes) don't worked at all or only if the speed vector directly points to the sky (in worldspace coord) :(

my concept is:
  • convert the speed vector into eyespace coord: vec3( gl_ModelViewMatrix * vec4(speed,0.0) )
  • calculate the 2d angle between the eyespace up vector and the eyespace speed vector. i tried many codes to do so, but none worked :(
    Image
    (please note the speed vector still has a z coord, but i only want the up and right components of the speed vector)
  • rotate the quad with: mat2 rotation = mat2( cos(alpha), -sin(alpha), sin(alpha), cos(alpha) )
anyone has a idea, how i can the angle between the speed vector and the eyespace up vector or if there is a much easier way to rotate a billboarded quad in the vertex shader?
User avatar
AlfaSub
Posts: 17
Joined: 07 Feb 2006, 20:28

Post by AlfaSub »

Mathematically speaking, the angle between two vectors a and b is:

arccos( (a dot b)/(|a||b|) )

(a dot b) is the dot product (a1b1+a2b2+a3b3 etc), and |x| is the magnitude function (the length of the vector, sqrt(x1^2+x2^2+x3^2...)

So for your two-dimensional example, the angle between the vectors <x1,y1> and <x2,y2> would be:

arccos( (x1y1+x2y2)/( sqrt(x1^2+y1^2)sqrt(x2^2+y2^2) ) )


http://en.wikipedia.org/wiki/Dot_product (it's near the middle)
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Post by jK »

yeah, i know how to calculate the angle between two vectors, but the problem is how do i get only the eye up and eye right components of the speedvector?
i tried to use Gram-Schmidt to orthogonalize (without normalizing) the speedvector to the eye forward and eye up vector to get the eye right component (of the speed vector) and then the same only this time orthonoalized to eye forward and eye right vector to get the up component, but it didn't worked :(
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Post by Kloot »

Transform both the speed-vector V and an up-vector T [0, 1, 0] to eye-space. Then take the (normalized) crossproduct of the transformed speed- and up-vectors V' and T' to get the eye-right component R. Next calculate the (also normalized) crossproduct of V' and R to get the eye-up component U. From there you can easily find the angle between U and the eye-space up-vector (unless I've misunderstood you and that's not what you want to do ;)).
Last edited by Kloot on 05 Aug 2007, 16:35, edited 1 time in total.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Post by jK »

still doesn't work :(
the rotation angle is now constant 45degree

my code is now the following:

Code: Select all

vec3 eyeup    = vec3( gl_ModelViewMatrix * vec4(0.0,1.0,0.0,0.0) );
vec3 eyespeed = vec3( gl_ModelViewMatrix * vec4(speedv,0.0) );
vec3 R = normalize( cross(eyeup,eyespeed) );
vec3 U = normalize( cross(eyespeed,R) );

float cosf = dot(normalize(U+R), normalize(eyeup)); //here is a problem it should be between -1.0 and 1.0, but it is abs(cosf)>1

float alpha = acos( cosf );
mat2 rotation = mat2( cos(alpha), -sin(alpha), sin(alpha), cos(alpha) );

gl_Position.xy += rotation * (gl_MultiTexCoord1.zw * size);
(gl_MultiTexCoord1.zw saves the offsets per vertex from the center point of the quad)
Post Reply

Return to “Lua Scripts”