2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.5 KiB
C#

using UnityEngine;
using UnityEngine.Rendering;
[ExecuteInEditMode]
[ImageEffectAllowedInSceneView]
[RequireComponent(typeof(Camera))]
public class CommandBufferBlur : MonoBehaviour
{
Shader _shader;
Material _material = null;
Camera _camera = null;
CommandBuffer _commandBuffer = null;
Vector2 _screenResolution = Vector2.zero;
RenderTextureFormat _textureFormat = RenderTextureFormat.ARGB32;
public void Cleanup()
{
if (!Initialized)
return;
_camera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, _commandBuffer);
_commandBuffer = null;
Object.DestroyImmediate(_material);
}
public void OnEnable()
{
Cleanup();
Initialize();
}
public void OnDisable()
{
Cleanup();
}
public bool Initialized
{
get { return _commandBuffer != null; }
}
void Initialize()
{
if (Initialized)
return;
if (!_shader)
{
_shader = Shader.Find("Hidden/SeparableGlassBlur");
if (!_shader)
throw new MissingReferenceException("Unable to find required shader \"Hidden/SeparableGlassBlur\"");
}
if (!_material)
{
_material = new Material(_shader);
_material.hideFlags = HideFlags.HideAndDontSave;
}
_camera = GetComponent<Camera>();
if (_camera.allowHDR && SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.DefaultHDR))
_textureFormat = RenderTextureFormat.DefaultHDR;
_commandBuffer = new CommandBuffer();
_commandBuffer.name = "Blur screen";
int numIterations = 4;
Vector2[] sizes = {
new Vector2(Screen.width, Screen.height),
new Vector2(Screen.width / 2, Screen.height / 2),
new Vector2(Screen.width / 4, Screen.height / 4),
new Vector2(Screen.width / 8, Screen.height / 8),
};
for (int i = 0; i < numIterations; ++i)
{
int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture");
_commandBuffer.GetTemporaryRT(screenCopyID, -1, -1, 0, FilterMode.Bilinear, _textureFormat);
_commandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, screenCopyID);
int blurredID = Shader.PropertyToID("_Grab" + i + "_Temp1");
int blurredID2 = Shader.PropertyToID("_Grab" + i + "_Temp2");
_commandBuffer.GetTemporaryRT(blurredID, (int)sizes[i].x, (int)sizes[i].y, 0, FilterMode.Bilinear, _textureFormat);
_commandBuffer.GetTemporaryRT(blurredID2, (int)sizes[i].x, (int)sizes[i].y, 0, FilterMode.Bilinear, _textureFormat);
_commandBuffer.Blit(screenCopyID, blurredID);
_commandBuffer.ReleaseTemporaryRT(screenCopyID);
_commandBuffer.SetGlobalVector("offsets", new Vector4(2.0f / sizes[i].x, 0, 0, 0));
_commandBuffer.Blit(blurredID, blurredID2, _material);
_commandBuffer.SetGlobalVector("offsets", new Vector4(0, 2.0f / sizes[i].y, 0, 0));
_commandBuffer.Blit(blurredID2, blurredID, _material);
_commandBuffer.SetGlobalTexture("_GrabBlurTexture_" + i, blurredID);
}
_camera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, _commandBuffer);
_screenResolution = new Vector2(Screen.width, Screen.height);
}
void OnPreRender()
{
if (_screenResolution != new Vector2(Screen.width, Screen.height))
Cleanup();
Initialize();
}
}