Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyanilux authored Sep 1, 2020
1 parent da730ef commit c4a753f
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 0 deletions.
175 changes: 175 additions & 0 deletions Blit.cs
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);
}
}
11 changes: 11 additions & 0 deletions Blit.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Editor.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions Editor/BlitPropertyDrawer.cs
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();
}

}
11 changes: 11 additions & 0 deletions Editor/BlitPropertyDrawer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c4a753f

Please sign in to comment.