Forum

Quake Motion Blur

Post tutorials on how to do certain tasks within game or engine code here.

Moderator: InsideQC Admins

Quake Motion Blur

Postby mh » Thu Apr 16, 2009 4:54 pm

This somewhere in gl_rmain.c:

Code: Select all
extern cvar_t r_motionblur;

void DrawAccumBlur (void)
{
   static int blurstate = 0;
   float accblur;
   static float damagetime = -1.0f;

   if (!r_motionblur.value) return;

   // evaluate blur conditions
   if (cl.stats[STAT_HEALTH] <= 0)
   {
      // being dead always overrides everything else
      accblur = 0.75f;
   }
   else if (cl.cshifts[CSHIFT_DAMAGE].percent)
   {
      // initial damage blur
      accblur = 0.75f;
      damagetime = 0.5f;
   }
   else if (damagetime >= 0.0f)
   {
      // persist damage blur
      damagetime -= r_frametime;
      accblur = 0.75f;
   }
   else if (cl.cshifts[CSHIFT_CONTENTS].percent)
   {
      // blur less if underwater
      accblur = 0.666f;
   }
   else accblur = -1.0f;

   if (accblur <= 0.0f)
   {
      // reinit if we're not blurring so that the contents of the
      // accumulation buffer are valid for the frame
      blurstate = 0;
      return;
   }

   if (!blurstate)
   {
      // load the scene into the accumulation buffer
      glAccum (GL_LOAD, 1.0f);
   }
   else
   {
      glAccum (GL_MULT, accblur); // scale contents of accumulation buffer
      glAccum (GL_ACCUM, 1.0f - accblur); // add screen contents
      glAccum (GL_RETURN, 1.0f); // read result back
   }

   blurstate = 1;
}


(Declare and register the r_motionblur cvar somewhere too, and you may also need to have a global called r_frametime, so just set it up the same way as frametime in R_DrawParticles...)

Call it like this, at the end of R_RenderView, after everything else is drawn:

Code: Select all
   // draw motion blur effects on the full 3D view
   DrawAccumBlur ();


Finally, in gl_vidnt.c, when setting up your PIXELFORMATDESCRIPTOR, just set the cAccumBits member to 64.

There's no need to clear the accumulation buffer between frames, should work just fine on any engine out of the box.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby MeTcHsteekle » Thu Apr 16, 2009 5:47 pm

sweet 8)
bah
MeTcHsteekle
 
Posts: 399
Joined: Thu May 15, 2008 10:46 pm
Location: its a secret

Re: Quake Motion Blur

Postby leileilol » Thu Jun 05, 2014 9:05 pm

Just chiming in that this can also be applied to Q3A as well (though replacing the whole stat/damage checking with some variable framerate smoothing thing, since you can't access player stats from the renderer module anyway).

Thanks!
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Quake Motion Blur

Postby r00k » Sat Jun 07, 2014 8:24 am

works!
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: Quake Motion Blur

Postby leileilol » Sat Jun 07, 2014 12:44 pm

By the way and FYI - accumulation buffers in consumer videogaming video hardware only begin their support starting from shader model 2.0 hardware, despite this predating the whole programmable shader thing for ages.
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Quake Motion Blur

Postby toneddu2000 » Sat Jun 07, 2014 9:41 pm

I can't understand the last step.
Finally, in gl_vidnt.c, when setting up your PIXELFORMATDESCRIPTOR, just set the cAccumBits member to 64.
I use quakespasm and there's no gl_vidnt.c but gl_vidsdl.c. I hope it's the same. Now what should I set?
thanks
toneddu2000
 
Posts: 1323
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Postby hogsy » Sat Jun 07, 2014 9:57 pm

Rather than doing that I'd suppose you'd set the following in the case of SDL.

Code: Select all
SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE,8);
User avatar
hogsy
 
Posts: 198
Joined: Wed Aug 03, 2011 3:44 pm
Location: UK

Re: Quake Motion Blur

Postby toneddu2000 » Sat Jun 07, 2014 10:37 pm

thanks hogsy but where should I put those functions?
toneddu2000
 
Posts: 1323
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Postby hogsy » Sat Jun 07, 2014 10:42 pm

I haven't touched QuakeSpasm but if you take a look in gl_vidsdl there should be a bunch of the same functions where the SDL window is created and you can just plop it in with those, shouldn't be too hard to find if you just do a quick search :wink:
User avatar
hogsy
 
Posts: 198
Joined: Wed Aug 03, 2011 3:44 pm
Location: UK

Re: Quake Motion Blur

Postby toneddu2000 » Sat Jun 07, 2014 10:51 pm

the only SDL_GL_SetAttribute() function I found it's in VID_SetMode () int gl_vidsdl.c and it's called like this:

Code: Select all
if (SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vid_vsync.value) ? 1 : 0) == -1)
      gl_swap_control = false;


There's no bunch of SDL functions

thanks
toneddu2000
 
Posts: 1323
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Postby hogsy » Sat Jun 07, 2014 10:56 pm

Just plop it under those two lines then.
User avatar
hogsy
 
Posts: 198
Joined: Wed Aug 03, 2011 3:44 pm
Location: UK

Re: Quake Motion Blur

Postby toneddu2000 » Sat Jun 07, 2014 11:17 pm

It worked! Thanks a lot hogsy and of course mh for this great addition!

For the QuakeSpasm lovers:
declare at the start of the gl_rmain.c
Code: Select all
float  r_frametime;


put at the start of the DrawAccumBlur() function
Code: Select all
r_frametime = cl.time - cl.oldtime;

in gl_vidsdl.c, in VID_SetMode function,after:
Code: Select all
if (SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vid_vsync.value) ? 1 : 0) == -1)
      gl_swap_control = false;

put those lines as hogsy stated
Code: Select all
SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8);


I avoided the
Code: Select all
if (!r_motionblur.value) return;
line because I still didn't understand how send the cvars to quakec, so in my case motion blur is on by default.

There's a chance to mimic that cool Doom3 pain rotating head effect?
toneddu2000
 
Posts: 1323
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Postby leileilol » Sun Jun 08, 2014 12:37 am

You could do something derivative of v_idlescale in view.c to make that scale from damagetime.
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Quake Motion Blur

Postby toneddu2000 » Sun Jun 08, 2014 1:09 pm

thanks leilei, I tried in V_AddIdle:
Code: Select all
void V_AddIdle (void)
{
   r_refdef.viewangles[ROLL] += v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value;
   r_refdef.viewangles[PITCH] += v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value;
   r_refdef.viewangles[YAW] += v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value;
   //code below added by me
   if (cl.cshifts[CSHIFT_DAMAGE].percent)
   {
      cl.viewent.angles[ROLL] -= v_idlescale.value * 250.0f;
      cl.viewent.angles[PITCH] -= v_idlescale.value * 250.0f;
      cl.viewent.angles[YAW] -= v_idlescale.value * 250.0f;
   }
}

Then I set cvar r_idlescale to 1 but nothing. I exagerated roll,pitch and yaw movements to maximum just to test if it could work but it doesn't do anything
toneddu2000
 
Posts: 1323
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Quake Motion Blur

Postby leileilol » Sun Jun 08, 2014 7:23 pm

Because you have to alter the refdef's angles not the viewent itself. IIRC, viewent is the gun. The gun gets its origin and angles calculated in another function that comes after addidle. iirc
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Next

Return to Programming Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest