Forum

Better motion blur?

Discuss programming topics that involve the OpenGL API.

Moderator: InsideQC Admins

Better motion blur?

Postby leileilol » Sat Feb 22, 2014 2:46 am

What's a good fixed way for motion blur that doesn't look like a lazy buffer effect?

Doom3 BFG supposedly does a nice multipass motion blur using player velocity and angle differences but the viewmodel is excluded which kind of breaks the illusion. It also implies the blur is done in cgame.


I intend to do this to id Tech 3.
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Better motion blur?

Postby Barnes » Sat Feb 22, 2014 9:09 am

I tried to make motion blur. The algorithm itself is very simple, but requires working with matrices.
effect dont work (problems with velocity vector)

Code: Select all
void R_MotionBlur (void) {
   
   mat4_t pMVP;
   unsigned   defBits = 0;
   int         id;

    if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
            return;
   if (r_newrefdef.rdflags & RDF_IRGOGGLES)
            return;

   // setup program
   GL_BindProgram(motionBlurProgram, defBits);
   id = motionBlurProgram->id[defBits];

   qglUniformMatrix4fv(qglGetUniformLocation(id, "u_PrevModelViewProj"), 1,   GL_FALSE, (const GLfloat*)pMVP);
   qglUniformMatrix4fv(qglGetUniformLocation(id, "u_InverseModelViewMat"), 1,   GL_FALSE, (const GLfloat*)r_newrefdef.unprojMatrix);
   
   qglUniform2f(qglGetUniformLocation(id, "u_screenSize"), vid.width, vid.height);

   GL_SelectTexture      (GL_TEXTURE0_ARB);   
   GL_BindRect            (ScreenMap->texnum);
    qglCopyTexSubImage2D   (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, 0, 0, vid.width, vid.height);
   qglUniform1i         (qglGetUniformLocation(id, "u_ScreenTex"), 0);

   GL_SelectTexture      (GL_TEXTURE1_ARB);   
   GL_BindRect            (depthMap->texnum);
    qglUniform1i         (qglGetUniformLocation(id, "u_DepthTex"), 1);

   R_DrawFullScreenQuad();

   GL_BindNullProgram();
   GL_SelectTexture(GL_TEXTURE0_ARB);   
      
   Mat4_Multiply(r_newrefdef.modelViewMatrix, r_newrefdef.projectionMatrix, pMVP);
}


Code: Select all
uniform sampler2DRect    u_ScreenTex;
uniform sampler2DRect    u_DepthTex;
uniform mat4          u_InverseModelViewMat;
uniform mat4          u_PrevModelViewProj;

void main(void)
{
   float depth = texture2DRect(u_DepthTex, gl_FragCoord.xy).r;
   vec4 v = u_InverseModelViewMat * vec4(gl_FragCoord.xy, depth, 1.0);
   vec3 worldPos = v.xyz / v.w;

     // Current viewport position 
   vec4 currentPos = v; 
   // Use the world position, and transform by the previous view- 
   // projection matrix. 
   vec4 previousPos = vec4(worldPos, 1.0) * u_PrevModelViewProj; 
   // Convert to nonhomogeneous points [-1,1] by dividing by w. 
   previousPos /= previousPos.w; 
   // Use this frame's position and last frame's to compute the pixel 
   // velocity. 
   vec2 velocity = (currentPos - previousPos)/3000.0; 

   // Get the initial color at this pixel. 
   //vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
   
   //for(int i = 0; i < 16; ++i) 
 //     { 
 //     // Sample the color buffer along the velocity vector. 
 //     vec4 currentColor = texture2DRect(u_ScreenTex, gl_FragCoord.xy + vec2(velocity)*i); 
 //     // Add the current color to our color sum. 
 //     color += currentColor; 
   //} 

   vec4 color = texture2DRect(u_ScreenTex, gl_FragCoord.xy); 
   vec2 texCoord = gl_FragCoord.xy;
   
   texCoord += velocity; 
   
   for(int i = 1; i < 32; ++i, texCoord += velocity) 
      { 
      // Sample the color buffer along the velocity vector. 
      vec4 currentColor = texture2DRect(u_ScreenTex, texCoord); 
      // Add the current color to our color sum. 
      color += currentColor; 
      } 
   // Average all of the samples to get the final blur color. 
   gl_FragColor = color / 32.0; 
}
User avatar
Barnes
 
Posts: 223
Joined: Thu Dec 24, 2009 2:26 pm
Location: Russia, Moscow

Re: Better motion blur?

Postby leileilol » Thu May 08, 2014 7:56 pm

I never got the vector-based motion blur to work

but however, I did do a different method that does work. Sort of.


Just capturing the frames alternating between 5 screen texture buffers (which takes up a crapload of VRAM, 40MB at 1920x1080) , then mixing them in a fragment shader. It's most effective at 120-240fps.
Image
Image

Sure, I could take a gradual buffer approach, but i'm trying to retain as much color precision as I can since we already lose some with overbrights.
i should not be here
leileilol
 
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: Better motion blur?

Postby Barnes » Fri May 09, 2014 8:05 am

Damn) I'm thought about this method some days ago :)
User avatar
Barnes
 
Posts: 223
Joined: Thu Dec 24, 2009 2:26 pm
Location: Russia, Moscow

Re: Better motion blur?

Postby Spiney » Thu Aug 28, 2014 4:07 pm

You could try accumulating frames into a HDR buffer. I guess that wouldn't balloon up so much.

As for retro stuff, maybe render 4 quarter res buffers with one pixel view offset and arrange the pixels in a screendoor pattern.
Spiney
 
Posts: 63
Joined: Mon Feb 13, 2012 1:35 pm


Return to OpenGL Programming

Who is online

Users browsing this forum: No registered users and 1 guest