Cool spark/particle effect demo

Check out: http://www.nvidia.com/Powerof3d.nsf

And have a look at the lightning demo. In the mpeg of the demo it shows it in wireframe at one point(I don’t know about the demo itself as I don’t have a GeForce). What I’m wondering is how they achieved the spark effect. It looks like the same effect achieved in Half-Life for sparks and I had thought that it was a GL_LINES type of thing but after seeing this demo in wireframe, it’s not. It looks like a distorted quad. But it’s not being billboarded quite. It changes shape depending on its orientation. But then how are they mapping the spark effect onto the quad? Anyway, thought this might add some to the board. Thanks!

I got the demo to work.

It looks to me like billboarded distorted
quads. Pressing W while running the demo will
draw in wireframe mode.

The texture is probably a diffuse spot with
100% opacity in the middle and 0% at the
edges; then stretching the quad would “shape”
the sparks. Probably the quads are also
oriented so that the viewer will not see them
edge-on.

[This message has been edited by bgl (edited 02-14-2001).]

Hehe, don’t even try the demo on a TNT (I was hoping to at least see the demo in wireframe). It screws up Windows98 royally if you do .

Yeah, I think it doesn’t do any checking for supported features and just goes ahead and calls them so if your card doesn’t support them, you get a GPF. Anyway, so are you saying that it’s just a texture of a diffuse spot and the distortion of the quad shapes it? Sounds reasonable… however, I guess the real question then is this: how do they control the orientation of the quad the way they do??? It’s billboarded, but yet the vertices of the quad are altered in accordance with the orientation of the spark. I’d really like to know how they’re doing this because it has virtually unlimited uses!

If you go to my web page and download the source code to Q2toQ3A (it converted Q2 maps, but also let you fly around Q3 maps) and you dig through the code, you’ll find the code I used to achieve a similiar effect. I believe it is in the mapgl.cpp file. I used the long axis billboard code to keep links between triggers and trigger targets facing the viewer.

[This message has been edited by DFrey (edited 02-14-2001).]

What’s the URL?

It’s in my profile

Oh, duh! Sorry.

And the particular function of interest is void DrawTargetLink(float *from, float *to) in the MapGL.cpp file.

Traditional “sprite” billboarding orients the
entire face towards the viewer. I think these
sparks first orient the quad using simple
animation, and then rotates the spark only
around the lengthwise (motion) axis so as
to display the most area to the viewer. But
that’s just a guess.

My guess (and this is based on the fact that when the spark is either facing towards or away from you it looks like an ordinary quad) is that they take a quad, then elongate the vertex they wish to be at the tail of the spark, then, based upon orientation, collapse the quad down until it’s a normal quad. Put another way, I think they use the length of the velocity vector of the spark for the length and angle of the quad but do not allow it to shrink beyond a regular square. So they probably just have a center and a velocity vector for the spark. Then, they take the point and vector and project the start and end points of the quad and then they might find the other two vetices by a cross product.

Okay, a couple of more questions. First, since I can’t run the demo myself, all I have to go on is the mpeg. And in the mpeg, the lightning bolt looks really funky. I can’t tell how the heck they’re doing it. In the mpeg it looks like a bunch of lines that run at a right angle to the axis of the bolt segment. Also, any clues as to how they’re doing the crona of the bolt (the glow at the edges of the bolt)? Perhaps a 1D texture? Also, how do you think they achieved the dull red glow of the most recently zapped areas of the plate? I also noticed a really cool effect of the semi-reflection of lightsources above the plate. What’s cool about it is that it doesn’t look like the scene was rendered a second time only upside down and blended. Instead, it’s kind of a fuzzy reflection as you would expect from such a surface. It even seems to reflect the glow of sparks atop it. Very nice!

[This message has been edited by Punchey (edited 02-14-2001).]

Seeing as this demo uses OpenGL, maybe Matt or Cass can convince someone to release the source?

I can’t see why not… after all, it’s a demo to show you what the GeForce can do. So it could only help nVidia to release info about how to accomplish these things for a GeForce.

Here’s some (crappy) code I wrote to implement the sparks as seen in the nVidia demo. The problem is, currently, I’m having to do a sqrt() to get a normalized vector so that my quad never becomes concave. Does anyone know how I could avoid the sqrt()?

Vertex3V pos, vect;
float life;

draw(float size)
{
static Vertex3V front, left, right, tail, tempVect;
static float length;

  tempVect = vect;

  tempVect.z = 0.0f;
  tempVect.normalize();

  tail.x = pos.x - vect.x*10 - tempVect.x;
  tail.y = pos.y - vect.y*10 - tempVect.y;
  tail.z = pos.z;

  front.x = pos.x + tempVect.x;
  front.y = pos.y + tempVect.y;
  front.z = pos.z;

  left = pos + (tempVect * Vertex3V(0,0,-1));
  right = pos + (tempVect * Vertex3V(0,0,1));

  glColor4f(1.0f,1.0f,1.0f,life);
  glBegin(GL_QUADS);
  	glTexCoord2f(1,1); glVertex3fv((float*)&right);
  	glTexCoord2f(0,1); glVertex3fv((float*)&front);
  	glTexCoord2f(0,0); glVertex3fv((float*)&left);
  	glColor3f(0.0f,0.0f,0.0f);
  	glTexCoord2f(1,0); glVertex3fv((float*)&tail);
  glEnd();

BTW, the “tempVect * Vertex3V(0,0,-1)” indicates a cross product thus finding a point at a right angle to these two vectors.

[This message has been edited by Punchey (edited 02-16-2001).]

Okay, can anyone tell me what’s going on with this? I was doing the spark thing just fine on a Matrox G450. It looked like a regular quad and everything only one vertex was stretched out making it look like an elongated spark. However, after running it on a TNT2 M64 and a Voodoo3, instead of looking like:
(> (try to imagine that as round on one side and elongated on the right)
it looks like:
>>

Or, in other words, it stretches both the front AND back of the texture towards the stretched vertex thus making it look like crap. I guess this is a difference in how the drivers of the different cards handle a quad with a stretched vertex. Anyone now how to counter act this?

Yes, the difference you are seeing is in how the drivers tesselate the quad. You’ll have to use either discrete triangles (or a triangle strip), or you might be able to use glTexCoord4f(…) to set the texture coordinates (you need to specify q since you are projecting a square texture onto a non-rectilinear quad). Personally, I’d go with the triangle strip. The spark you are making has a natural axis right down its middle from left to right (making a tip triangle and a tail triangle) that is perfect for splitting the quad.

[This message has been edited by DFrey (edited 02-16-2001).]

So does that entail the same q-coord that you posted just a while back to another guy about texturing trapezoids?

Yes. But as you’ll see in my edited post above, I wouldn’t worry with homogenous texture coordinates. Instead I’d prefer drawing the sparks as triangle strips. This way you can explicitly set the tesselation of the quad.

Ok I downloaded the demo and ran it. I see the nice pretty chamber and pipes but no lightning. Whats up? I have a GeForce2 GTS…