Skip to content

Instantly share code, notes, and snippets.

@runevision
Created October 22, 2017 11:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save runevision/f9a21f5040529470e3635403e870c504 to your computer and use it in GitHub Desktop.
Save runevision/f9a21f5040529470e3635403e870c504 to your computer and use it in GitHub Desktop.
Unity CommandBuffer replacement for GrabPass - works with multiple separate cameras.
using UnityEngine;
using UnityEngine.Rendering;
// This script is added to cameras automatically at runtime by the ObjectNeedingRefraction scripts.
public class CameraTrackingRefraction : MonoBehaviour {
[System.NonSerialized]
public int lastRenderedFrame = -1;
Camera cam;
CommandBuffer buffer;
void Awake () {
cam = Camera.current;
cam.depthTextureMode = DepthTextureMode.Depth;
}
public void SetIsNeededThisFrame () {
lastRenderedFrame = Time.frameCount;
if (buffer == null)
CreateCommandBuffer ();
enabled = true;
}
void Update () {
if (lastRenderedFrame < Time.frameCount - 1) {
DestroyCommandBuffer ();
enabled = false;
}
}
void DestroyCommandBuffer () {
cam.RemoveCommandBuffer (CameraEvent.AfterSkybox, buffer);
buffer = null;
}
void CreateCommandBuffer ()
{
buffer = new CommandBuffer();
buffer.name = "Grab screen";
int screenCopyID = Shader.PropertyToID("_RefractionGrabTexture");
buffer.GetTemporaryRT (screenCopyID, -1, -1, 0, FilterMode.Bilinear);
buffer.Blit (BuiltinRenderTextureType.CurrentActive, screenCopyID);
buffer.SetGlobalTexture("_RefractionGrabTexture", screenCopyID);
cam.AddCommandBuffer (CameraEvent.AfterSkybox, buffer);
}
}
using System.Collections.Generic;
using UnityEngine;
// Place this script on all GameObject with renderers with materials
// that use shaders that need the _RefractionGrabTexture "grab texture".
// The GrabPass in the shader can then be removed and the rest should ideally work as-is.
public class ObjectNeedingRefraction : MonoBehaviour {
static Dictionary<Camera, CameraTrackingRefraction> m_Trackers =
new Dictionary<Camera, CameraTrackingRefraction>();
public void OnWillRenderObject () {
var cam = Camera.current;
if (!cam)
return;
CameraTrackingRefraction tracker;
if (!m_Trackers.TryGetValue (cam, out tracker)) {
tracker = cam.GetComponent<CameraTrackingRefraction> ();
if (!tracker)
tracker = cam.gameObject.AddComponent<CameraTrackingRefraction> ();
m_Trackers[cam] = tracker;
}
tracker.SetIsNeededThisFrame ();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment