Page 1 of 1

Better motion blur?

Posted: Sat Feb 22, 2014 2:46 am
by leileilol
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.

Re: Better motion blur?

Posted: Sat Feb 22, 2014 9:09 am
by Barnes
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;  
}

Re: Better motion blur?

Posted: Thu May 08, 2014 7:56 pm
by leileilol
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.

Re: Better motion blur?

Posted: Fri May 09, 2014 8:05 am
by Barnes
Damn) I'm thought about this method some days ago :)

Re: Better motion blur?

Posted: Thu Aug 28, 2014 4:07 pm
by Spiney
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.