PDA

View Full Version : motion blur post effect shader in GLSL



def
03-13-2011, 08:55 AM
Hi,

I am trying to implement motion blur from "GPU Gems 3" as a post effect using a fragment shader.
(http://http.developer.nvidia.com/GPUGems3/gpugems3_ch27.html)
The sample code is in HLSL/Cg and I am having difficulties doing the conversion to GLSL right.

The "ViewProjectionMatrix" and it's reverse are the problem, I guess.
I am using gl_ModelViewProjectionMatrixInverse and as a uniform I upload the GL_MODELVIEW matrix.

Here is my fragment shader code:
(using OpenGL 2.0)


uniform sampler2D tex;
uniform sampler2D tex2;
uniform mat4 PrevMatrix;
varying vec2 vTexCoord;

void main(void)
{
vec4 color = texture2D(tex, vTexCoord);
vec4 zOverW = texture2D(tex2, vTexCoord);
// H is the viewport position at this pixel in the range -1 to 1.
vec4 H = vec4(vTexCoord.x * 2 - 1, (1 - vTexCoord.y) * 2 - 1, zOverW.g, 1);
// Transform by the view-projection inverse.
vec4 D = gl_ModelViewProjectionMatrixInverse * H;
// Divide by w to get the world position.
vec4 worldPos = D / vec4(D.w);

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

gl_FragColor = vec4(velocity.x, velocity.y, color.g, 1.0);
}


here I set the previous frame's matrix:


GLint loc = glGetUniformLocation(program_object, "PrevMatrix" );
glUniformMatrix4fv( loc, 1, GL_FALSE, &prevMat[0]);

glGetFloatv(GL_MODELVIEW_MATRIX, prevMat);



Any help would be appreciated!

sgsrules
03-23-2011, 01:13 PM
You need to use the InverseViewProjectionMatrix to go from clip space to world space when reading a pixels position. using gl_ModelViewProjectionMatrixInverse won't work it takes you back to object space.

"Once we determine the world-space position, we can transform it by using the previous frame's view-projection matrix"

The view-projection matrix not the GL_MODELVIEW_MATRIX. You've got you're matrices setup wrong.

Instead of getting your previous matrix with


glGetFloatv(GL_MODELVIEW_MATRIX, prevMat);


Just keep an extra copy of your view_matrix that you set to your current view matrix before you transform the current view matrix, use this as the previous view matrix.

I'd highly recommend doing all your own matrix math instead of using the old fixed functionality stuff. It'll make your life easier in the long run.