forked from Cyanilux/URP_BlitRenderFeature
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
using UnityEngine; | ||
using UnityEngine.Rendering; | ||
using UnityEngine.Rendering.Universal; | ||
|
||
// Blit Renderer Feature | ||
// Based on the Blit from the UniversalRenderingExamples | ||
// https://github.com/Unity-Technologies/UniversalRenderingExamples/tree/master/Assets/Scripts/Runtime/RenderPasses | ||
// Extended to allow for : | ||
// - Specific access to selecting a source and destination (via current camera's color / texture id / render texture object | ||
// - Automatic switching to using _AfterPostProcessTexture for After Rendering event | ||
// - Setting a _InverseView matrix (cameraToWorldMatrix), for shaders that might need it to handle calculations from screen space to world. | ||
// e.g. reconstruct world pos from depth : https://twitter.com/Cyanilux/status/1269353975058501636 | ||
// @Cyanilux | ||
public class Blit : ScriptableRendererFeature { | ||
|
||
public class BlitPass : ScriptableRenderPass { | ||
|
||
public Material blitMaterial = null; | ||
public FilterMode filterMode { get; set; } | ||
|
||
private BlitSettings settings; | ||
|
||
private RenderTargetIdentifier source { get; set; } | ||
private RenderTargetIdentifier destination { get; set; } | ||
|
||
RenderTargetHandle m_TemporaryColorTexture; | ||
string m_ProfilerTag; | ||
|
||
public BlitPass(RenderPassEvent renderPassEvent, BlitSettings settings, string tag) { | ||
this.renderPassEvent = renderPassEvent; | ||
this.settings = settings; | ||
blitMaterial = settings.blitMaterial; | ||
m_ProfilerTag = tag; | ||
m_TemporaryColorTexture.Init("_TemporaryColorTexture"); | ||
} | ||
|
||
public void Setup(RenderTargetIdentifier source, RenderTargetIdentifier destination) { | ||
this.source = source; | ||
this.destination = destination; | ||
} | ||
|
||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { | ||
CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); | ||
|
||
RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor; | ||
opaqueDesc.depthBufferBits = 0; | ||
|
||
if (settings.setInverseViewMatrix) { | ||
Shader.SetGlobalMatrix("_InverseView", renderingData.cameraData.camera.cameraToWorldMatrix); | ||
} | ||
|
||
//Debug.Log($"src = {source}, dst = {destination} "); | ||
// Can't read and write to same color target, use a TemporaryRT | ||
if (source == destination || (settings.srcType == settings.dstType && settings.srcType == Target.CameraColor)) { | ||
cmd.GetTemporaryRT(m_TemporaryColorTexture.id, opaqueDesc, filterMode); | ||
Blit(cmd, source, m_TemporaryColorTexture.Identifier(), blitMaterial, settings.blitMaterialPassIndex); | ||
Blit(cmd, m_TemporaryColorTexture.Identifier(), destination); | ||
} else { | ||
Blit(cmd, source, destination, blitMaterial, settings.blitMaterialPassIndex); | ||
} | ||
|
||
context.ExecuteCommandBuffer(cmd); | ||
CommandBufferPool.Release(cmd); | ||
} | ||
|
||
public override void FrameCleanup(CommandBuffer cmd) { | ||
if (destination == BuiltinRenderTextureType.CameraTarget) { | ||
cmd.ReleaseTemporaryRT(m_TemporaryColorTexture.id); | ||
} | ||
} | ||
} | ||
|
||
[System.Serializable] | ||
public class BlitSettings { | ||
public RenderPassEvent Event = RenderPassEvent.AfterRenderingOpaques; | ||
|
||
public Material blitMaterial = null; | ||
public int blitMaterialPassIndex = 0; | ||
public bool setInverseViewMatrix = false; | ||
|
||
public Target srcType = Target.CameraColor; | ||
public string srcTextureId = "_CameraColorTexture"; | ||
public RenderTexture srcTextureObject; | ||
|
||
public Target dstType = Target.CameraColor; | ||
public string dstTextureId = "_BlitPassTexture"; | ||
public RenderTexture dstTextureObject; | ||
} | ||
|
||
public enum Target { | ||
CameraColor, | ||
TextureID, | ||
RenderTextureObject | ||
} | ||
|
||
public BlitSettings settings = new BlitSettings(); | ||
|
||
BlitPass blitPass; | ||
|
||
private RenderTargetIdentifier srcIdentifier, dstIdentifier; | ||
|
||
public override void Create() { | ||
var passIndex = settings.blitMaterial != null ? settings.blitMaterial.passCount - 1 : 1; | ||
settings.blitMaterialPassIndex = Mathf.Clamp(settings.blitMaterialPassIndex, -1, passIndex); | ||
blitPass = new BlitPass(settings.Event, settings, name); | ||
|
||
if (settings.Event == RenderPassEvent.AfterRenderingPostProcessing) { | ||
Debug.LogWarning("Note that the \"After Rendering Post Processing\"'s Color target doesn't seem to work? (or might work, but doesn't contain the post processing) :( -- Use \"After Rendering\" instead!"); | ||
} | ||
|
||
UpdateSrcIdentifier(); | ||
UpdateDstIdentifier(); | ||
} | ||
|
||
private void UpdateSrcIdentifier() { | ||
srcIdentifier = UpdateIdentifier(settings.srcType, settings.srcTextureId, settings.srcTextureObject); | ||
} | ||
|
||
private void UpdateDstIdentifier() { | ||
dstIdentifier = UpdateIdentifier(settings.dstType, settings.dstTextureId, settings.dstTextureObject); | ||
} | ||
|
||
private RenderTargetIdentifier UpdateIdentifier(Target type, string s, RenderTexture obj) { | ||
if (type == Target.RenderTextureObject) { | ||
return obj; | ||
} else if (type == Target.TextureID) { | ||
//RenderTargetHandle m_RTHandle = new RenderTargetHandle(); | ||
//m_RTHandle.Init(s); | ||
//return m_RTHandle.Identifier(); | ||
return s; | ||
} | ||
return new RenderTargetIdentifier(); | ||
} | ||
|
||
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { | ||
|
||
if (settings.blitMaterial == null) { | ||
Debug.LogWarningFormat("Missing Blit Material. {0} blit pass will not execute. Check for missing reference in the assigned renderer.", GetType().Name); | ||
return; | ||
} | ||
|
||
if (settings.Event == RenderPassEvent.AfterRenderingPostProcessing) { | ||
} else if (settings.Event == RenderPassEvent.AfterRendering && renderingData.postProcessingEnabled) { | ||
// If event is AfterRendering, and src/dst is using CameraColor, switch to _AfterPostProcessTexture instead. | ||
if (settings.srcType == Target.CameraColor) { | ||
settings.srcType = Target.TextureID; | ||
settings.srcTextureId = "_AfterPostProcessTexture"; | ||
UpdateSrcIdentifier(); | ||
} | ||
if (settings.dstType == Target.CameraColor) { | ||
settings.dstType = Target.TextureID; | ||
settings.dstTextureId = "_AfterPostProcessTexture"; | ||
UpdateDstIdentifier(); | ||
} | ||
} else { | ||
// If src/dst is using _AfterPostProcessTexture, switch back to CameraColor | ||
if (settings.srcType == Target.TextureID && settings.srcTextureId == "_AfterPostProcessTexture") { | ||
settings.srcType = Target.CameraColor; | ||
settings.srcTextureId = ""; | ||
UpdateSrcIdentifier(); | ||
} | ||
if (settings.dstType == Target.TextureID && settings.dstTextureId == "_AfterPostProcessTexture") { | ||
settings.dstType = Target.CameraColor; | ||
settings.dstTextureId = ""; | ||
UpdateDstIdentifier(); | ||
} | ||
} | ||
|
||
var src = (settings.srcType == Target.CameraColor) ? renderer.cameraColorTarget : srcIdentifier; | ||
var dest = (settings.dstType == Target.CameraColor) ? renderer.cameraColorTarget : dstIdentifier; | ||
|
||
blitPass.Setup(src, dest); | ||
renderer.EnqueuePass(blitPass); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using UnityEngine; | ||
using UnityEditor; | ||
|
||
[CustomPropertyDrawer(typeof(Blit.BlitSettings))] | ||
public class BlitEditor : PropertyDrawer { | ||
|
||
private bool foldout = true; | ||
|
||
private bool createdStyles = false; | ||
private GUIStyle boldLabel; | ||
|
||
private void CreateStyles() { | ||
createdStyles = true; | ||
boldLabel = GUI.skin.label; | ||
boldLabel.fontStyle = FontStyle.Bold; | ||
} | ||
|
||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { | ||
//base.OnGUI(position, property, label); | ||
if (!createdStyles) CreateStyles(); | ||
|
||
EditorGUI.BeginProperty(position, label, property); | ||
EditorGUI.LabelField(position, "Blit Settings", boldLabel); | ||
SerializedProperty _event = property.FindPropertyRelative("Event"); | ||
EditorGUILayout.PropertyField(_event); | ||
if (_event.intValue == (int)UnityEngine.Rendering.Universal.RenderPassEvent.AfterRenderingPostProcessing) { | ||
EditorGUILayout.HelpBox("The \"After Rendering Post Processing\" event does not work with Camera Color targets. " + | ||
"Unsure how to actually obtain the target after post processing has been applied. " + | ||
"Frame debugger seems to suggest a <no name> target?\n\n" + | ||
"Use the \"After Rendering\" event instead!", MessageType.Warning, true); | ||
} | ||
|
||
EditorGUILayout.PropertyField(property.FindPropertyRelative("blitMaterial")); | ||
EditorGUILayout.PropertyField(property.FindPropertyRelative("blitMaterialPassIndex")); | ||
EditorGUILayout.PropertyField(property.FindPropertyRelative("setInverseViewMatrix")); | ||
|
||
EditorGUILayout.Separator(); | ||
EditorGUILayout.LabelField("Source", boldLabel); | ||
SerializedProperty srcType = property.FindPropertyRelative("srcType"); | ||
EditorGUILayout.PropertyField(srcType); | ||
int enumValue = srcType.intValue; | ||
if (enumValue == (int)Blit.Target.TextureID) { | ||
EditorGUILayout.PropertyField(property.FindPropertyRelative("srcTextureId")); | ||
} else if (enumValue == (int)Blit.Target.RenderTextureObject) { | ||
EditorGUILayout.PropertyField(property.FindPropertyRelative("srcTextureObject")); | ||
} | ||
|
||
EditorGUILayout.Separator(); | ||
EditorGUILayout.LabelField("Destination", boldLabel); | ||
SerializedProperty dstType = property.FindPropertyRelative("dstType"); | ||
EditorGUILayout.PropertyField(dstType); | ||
enumValue = dstType.intValue; | ||
if (enumValue == (int)Blit.Target.TextureID) { | ||
EditorGUILayout.PropertyField(property.FindPropertyRelative("dstTextureId")); | ||
} else if (enumValue == (int)Blit.Target.RenderTextureObject) { | ||
EditorGUILayout.PropertyField(property.FindPropertyRelative("dstTextureObject")); | ||
} | ||
|
||
EditorGUI.indentLevel = 1; | ||
|
||
EditorGUI.EndProperty(); | ||
|
||
property.serializedObject.ApplyModifiedProperties(); | ||
} | ||
|
||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.