Creating a bullet trail effect

All topics about ZGameEditor goes here.

Moderator: Moderators

Post Reply
jinxtengu
Posts: 122
Joined: Wed Oct 14, 2009 2:05 pm
Contact:

Creating a bullet trail effect

Post by jinxtengu »

Hey, I'm trying to make a "trail" that's left behind after a projectile, in a non 2d perspective. Not a smoke trail, but more like a solid beam.
I'm just wondering what options are there for rendering such an effect? I've tried spawning models with a simple stretch/shrink animation on update of the projectile, and this actually looks ok, except it doesn't look very good facing upwards, as iv'e been unable to set the heading of the spawned trail on x/z axis, but perhaps there is a better way to create the desired effect anyway.
I also had a look at a mouse trail effect that was posted on here a while back, however I've been unable to utilize this for said purpose.
Does anyone have any ideas or suggestions to solve my problem? :)
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Creating a bullet trail effect

Post by Kjell »

Hi jinxtengu,

With or without shaders? Also .. in case you have a clip from a game / movie / animation that has a similar effect, that would help too :wink:

K
jinxtengu
Posts: 122
Joined: Wed Oct 14, 2009 2:05 pm
Contact:

Re: Creating a bullet trail effect

Post by jinxtengu »

Shaders aren't necessary for what I'm trying to do, I'd be happy if it were a single color.
I can't think of any examples off the top of my head, but I'd describe the effect as looking like a projectile that spawns a continuous trail of shrinking objects in it's wake(without viable gaps)., kind of like the mouse trail demo but in 3d space, also ideally cheap in terms of cpu usage.
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Creating a bullet trail effect

Post by Kjell »

Hi jinxtengu,
jinxtengu wrote:Shaders aren't necessary for what I'm trying to do, I'd be happy if it were a single color.
I can't think of any examples off the top of my head, but I'd describe the effect as looking like a projectile that spawns a continuous trail of shrinking objects in it's wake(without viable gaps)., kind of like the mouse trail demo but in 3d space, also ideally cheap in terms of cpu usage.
There are a ton of ways to do trails and it completely depends on what look you're going for & your requirements ( z-buffer, blend-mode etc. ) what approach is best. But in general it's pretty difficult to make it lightweight without using a vertex-shader. In any case, here's one shader-less approach ..

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
  <OnLoaded>
    <ZExternalLibrary ModuleName="opengl32">
      <Source>
<![CDATA[//

void glAlphaFunc(int func, float val){}
void glDisable(int cap){}
void glEnable(int cap){}

void glBegin(int mode){}
void glEnd(){}
void glTexCoord2f(float s, float t){}
void glVertex3f(float x, float y, float z){}
void glVertex3i(int x, int y, int z){}]]>
      </Source>
    </ZExternalLibrary>
    <ZExpression>
      <Expression>
<![CDATA[// Set alpha testing to greater-than 0

glAlphaFunc(0x0204, 0);

// Initialize trail

float t, x, y, z;

t = App.Time*8;

x = sin(t/7)*4;
y = cos(t/8)*2+2;
z = sin(t/9)*4;

for(int i=0; i<16; i++)
{
  Trail[i,0] = x;
  Trail[i,1] = y;
  Trail[i,2] = z;
}]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnUpdate>
    <ZExpression>
      <Expression>
<![CDATA[// Camera rotation

App.CameraRotation.Y =   App.MousePosition.X/9*4;
App.CameraRotation.X = 0-App.MousePosition.Y/4;

// Camera position

float x, y;

x = App.CameraRotation.X*PI*2;
y = App.CameraRotation.Y*PI*2;

App.CameraPosition.X = 0-cos(x)*sin(y)*16;
App.CameraPosition.Y = 2+sin(x)       *16;
App.CameraPosition.Z =   cos(x)*cos(y)*16;]]>
      </Expression>
    </ZExpression>
    <ZExpression>
      <Expression>
<![CDATA[// Update timer ( 5fps ) & increment index

int i = TrailIndex;

TrailTimer += App.DeltaTime;

if(TrailTimer > 1/5)
{
  TrailTimer -= 1/5;
  i = TrailIndex = (TrailIndex + 1) & 15;
}

TrailTexture.TextureX = TrailTimer*5/16;

// Update active segment

float t = App.Time*8;

Trail[i,0] = sin(t/7)*4;
Trail[i,1] = cos(t/8)*2+2;
Trail[i,2] = sin(t/9)*4;]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <OnRender>
    <UseMaterial Material="GridMaterial"/>
    <ZExpression>
      <Expression>
<![CDATA[// Quick & dirty grid rendering

glBegin(1);

for(int i=-4; i<=4; i++)
{
  glVertex3i(i, 0, -4); glVertex3i(i, 0, 4);
  glVertex3i(-4, 0, i); glVertex3i(4, 0, i);
}

glEnd();]]>
      </Expression>
    </ZExpression>
    <UseMaterial Material="TrailMaterial"/>
    <ZExpression>
      <Expression>
<![CDATA[// Quick & dirty trail rendering*

float x, y, z;

glEnable(0x0BC0);
glBegin(5);

for(int i=0; i<16; i++)
{
  int p = (TrailIndex-i) & 15;

  x = Trail[p,0];
  y = Trail[p,1];
  z = Trail[p,2];

  glTexCoord2f(i/16f,0); glVertex3f(x, y-0.5, z);
  glTexCoord2f(i/16f,1); glVertex3f(x, y+0.5, z);
}

glEnd();
glDisable(0x0BC0);

/*
 * You want to init & upload a texture buffer only once ( since it's always the same )
 * and only update the active trail node using glBufferSubData for the best performance.
 */]]>
      </Expression>
    </ZExpression>
  </OnRender>
  <Content>
    <Material Name="GridMaterial" Light="0"/>
    <Array Name="Trail" Dimensions="1" SizeDim1="16" SizeDim2="3">
      <Values>
<![CDATA[78DA636018DA000000C00001]]>
      </Values>
    </Array>
    <Variable Name="TrailIndex" Type="1"/>
    <Variable Name="TrailTimer"/>
    <Bitmap Name="TrailBitmap" Width="256" Filter="1">
      <Producers>
        <BitmapExpression>
          <Expression>
<![CDATA[//

Pixel.R = 1;
Pixel.G = 1;
Pixel.B = 1;
Pixel.A = -0.5-(abs(Y-0.5)*2-(1-X))*8;]]>
          </Expression>
        </BitmapExpression>
      </Producers>
    </Bitmap>
    <Material Name="TrailMaterial" Shading="1" Color="1 0 0 0.5" Light="0" DrawBackFace="255">
      <Textures>
        <MaterialTexture Name="TrailTexture" Texture="TrailBitmap" TextureX="0.0387" TexCoords="1" Origin="0 0 0"/>
      </Textures>
    </Material>
  </Content>
</ZApplication>
.. it's rendered pretty shoddily way at the moment, but it's only meant as a conceptual example ( I doubt this will be useful in your specific case anyway .. whatever that may be ). The way it works is that only a single segment ( 2 vertices ) of the trail is updated and a texture is translated along the mesh to give the illusion that it's moving.

K
Post Reply