- Home /
Full scene speed-based motion blur
I am looking for a motion blur effect that is applied to the whole scene as the camera moves or rotates. The problem with Unity's built-in motion blur image effect is that it is not speed based, and only looks acceptable if you are moving very fast. I don't want a motion blur that creates an added effect, but rather one that blurs out the space between frames and makes the game smooth. I found such a script [here][1].
It does exactly what I need it to, however, as said in the link above, it does not support translational blur, only rotational. How can I fix this code to work with translational blur?
CameraMBlurScript.js:
#pragma strict
@script ExecuteInEditMode
@script AddComponentMenu("Image Effects/CameraMBlur")
@script RequireComponent(Camera)
var compositeShader : Shader;
var Strength = 13.0;
private var m_CompositeMaterial : Material;
private function GetCompositeMaterial() : Material {
if (m_CompositeMaterial == null) {
m_CompositeMaterial = new Material( compositeShader );
m_CompositeMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return m_CompositeMaterial;
}
function OnDisable() {
DestroyImmediate (m_CompositeMaterial);
}
function OnPreCull()
{
var Iview=(camera.worldToCameraMatrix.inverse* camera.projectionMatrix);
Shader.SetGlobalMatrix("_Myview", Iview.inverse);
}
// Called by the camera to apply the image effect
function OnRenderImage (source : RenderTexture, destination : RenderTexture) : void
{
var compositeMat = GetCompositeMaterial();
compositeMat.SetFloat("_Strength", Strength);
ImageEffects.BlitWithMaterial(compositeMat, source, destination);
}
function OnPostRender()
{
renderlate();
}
function renderlate ()
{
yield WaitForEndOfFrame();
var Iviewprev=(camera.worldToCameraMatrix.inverse*camera.projectionMatrix);
Shader.SetGlobalMatrix("_Myviewprev", Iviewprev);
}
and CameraMBlur.shader:
// Upgrade NOTE: replaced 'glstate.matrix.mvp' with 'UNITY_MATRIX_MVP'
// Upgrade NOTE: replaced 'samplerRECT' with 'sampler2D'
// Upgrade NOTE: replaced 'texRECT' with 'tex2D'
Shader "CameraMBlur" {
Properties {
_MainTex ("", RECT) = "white" {}
_Strength ("Strength", Range (1, 30)) = 15.0
}
SubShader {
Pass {
ZTest Always Cull off ZWrite Off Fog { Mode off }
CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it does not contain a surface program or both vertex and fragment programs.
#pragma exclude_renderers gles
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv.xy=v.texcoord;
return o;
}
uniform float4x4 _Myview;
uniform float4x4 _Myviewprev;
uniform float _Strength;
half4 frag (v2f i) : COLOR
{
float2 Texcoord =i.uv;
// Get the depth buffer value at this pixel.
float zOverW = 1;
// H is the viewport position at this pixel in the range -1 to 1.
float4 H = float4(Texcoord.x * 2 - 1, (1 - Texcoord.y) * 2 - 1,zOverW, 1);
// Transform by the view-projection inverse.
float4 D = mul(H, _Myview);
// Divide by w to get the world position.
float4 worldPos = D / D.w;
// Current viewport position
float4 currentPos = H;
// Use the world position, and transform by the previous view-
// projection matrix.
float4 previousPos = mul(worldPos, _Myviewprev);
// 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.
float2 velocity = (currentPos - previousPos)/_Strength;
// Get the initial color at this pixel.
float4 color = tex2D(_MainTex, Texcoord);
Texcoord += velocity;
for(int i = 1; i < 12; ++i, Texcoord += velocity)
{
// Sample the color buffer along the velocity vector.
float4 currentColor = tex2D(_MainTex, Texcoord);
// Add the current color to our color sum.
color += currentColor;
}
// Average all of the samples to get the final blur color.
float4 finalColor = color / 12;
return finalColor;
}
ENDCG
}
}
Fallback off
}
Thanks in advance to whomever can help me, as I'm not too familiar with the shaders/scripts as of now. [1]: http://forum.unity3d.com/threads/35927-Camera-motion-blur
Answer by Matt-Downey · May 26, 2012 at 01:05 AM
This guy has made some epic code: http://forum.unity3d.com/threads/61133-Motion-blur-for-Unity-3
Here's his demo: http://vimeo.com/10287910
Answer by metaleap · Oct 24, 2013 at 08:03 PM
Did you ever figure out the translational part? This 2006 shader would be pretty awesome for mobile these days, and it looks awesome with rotational velocity but I too haven't figured out a way to accommodate translational velocity..
Your answer
Follow this Question
Related Questions
How to add motion blur effect to your camera 1 Answer
Inspection camera script problem 2 Answers
How can I do a smooth tracking camera, using the animator controller? 1 Answer
show a camera in one monitor and another camera in another monitor 1 Answer
How do I render a scene's depth buffer when I have custom vertex shaders? 0 Answers