Last active
November 17, 2019 12:36
-
-
Save andybak/3743ce0f15cabc0331dce136e0db4168 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
using UnityEngine.Rendering; | |
using UnityEngine.Rendering.Universal; | |
public class DepthNormalsFeature : ScriptableRendererFeature | |
{ | |
private DepthNormalsPass depthNormalsPass; | |
RenderTargetHandle m_DepthNormalsTexture; | |
public override void Create() | |
{ | |
if (depthNormalsPass == null) | |
depthNormalsPass = | |
new DepthNormalsPass(RenderPassEvent.BeforeRenderingPrepasses, RenderQueueRange.opaque, -1); | |
m_DepthNormalsTexture.Init("_CameraDepthNormalsTexture"); | |
} | |
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) | |
{ | |
depthNormalsPass.Setup(renderingData.cameraData.cameraTargetDescriptor, m_DepthNormalsTexture); | |
renderer.EnqueuePass(depthNormalsPass); | |
} | |
void OnValidate() | |
{ | |
depthNormalsPass?.SetLayerMask(-1); | |
} | |
} |
This file contains hidden or 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
using System; | |
using UnityEngine; | |
using UnityEngine.Rendering; | |
using UnityEngine.Rendering.Universal; | |
public class DepthNormalsPass : ScriptableRenderPass | |
{ | |
int kDepthBufferBits = 32; | |
private RenderTargetHandle depthAttachmentHandle { get; set; } | |
internal RenderTextureDescriptor descriptor { get; private set; } | |
private FilteringSettings m_FilteringSettings; | |
string m_ProfilerTag = "DepthNormals Prepass"; | |
ShaderTagId m_ShaderTagId = new ShaderTagId("DepthOnly"); | |
private Material depthNormalsMaterial = null; | |
public DepthNormalsPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask) | |
{ | |
m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask); | |
renderPassEvent = evt; | |
} | |
public void Setup(RenderTextureDescriptor baseDescriptor, RenderTargetHandle depthAttachmentHandle) | |
{ | |
this.depthAttachmentHandle = depthAttachmentHandle; | |
baseDescriptor.colorFormat = RenderTextureFormat.ARGB32; | |
baseDescriptor.depthBufferBits = kDepthBufferBits; | |
descriptor = baseDescriptor; | |
depthNormalsMaterial = | |
CoreUtils.CreateEngineMaterial("Hidden/Internal-DepthNormalsTexture"); | |
} | |
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) | |
{ | |
cmd.GetTemporaryRT(depthAttachmentHandle.id, descriptor, FilterMode.Point); | |
ConfigureTarget(depthAttachmentHandle.Identifier()); | |
ConfigureClear(ClearFlag.All, Color.black); | |
} | |
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) | |
{ | |
CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); | |
using (new ProfilingSample(cmd, m_ProfilerTag)) | |
{ | |
context.ExecuteCommandBuffer(cmd); | |
cmd.Clear(); | |
var sortFlags = renderingData.cameraData.defaultOpaqueSortFlags; | |
var drawSettings = CreateDrawingSettings(m_ShaderTagId, ref renderingData, sortFlags); | |
drawSettings.perObjectData = PerObjectData.None; | |
ref CameraData cameraData = ref renderingData.cameraData; | |
Camera camera = cameraData.camera; | |
if (cameraData.isStereoEnabled) | |
context.StartMultiEye(camera); | |
drawSettings.overrideMaterial = depthNormalsMaterial; | |
context.DrawRenderers(renderingData.cullResults, ref drawSettings, | |
ref m_FilteringSettings); | |
cmd.SetGlobalTexture("_CameraDepthNormalsTexture", depthAttachmentHandle.id); | |
} | |
context.ExecuteCommandBuffer(cmd); | |
CommandBufferPool.Release(cmd); | |
} | |
public void SetLayerMask(LayerMask mask) | |
{ | |
m_FilteringSettings.layerMask = mask; | |
} | |
public override void FrameCleanup(CommandBuffer cmd) | |
{ | |
if (cmd == null) | |
throw new ArgumentNullException("cmd"); | |
if (depthAttachmentHandle != RenderTargetHandle.CameraTarget) | |
{ | |
cmd.ReleaseTemporaryRT(depthAttachmentHandle.id); | |
depthAttachmentHandle = RenderTargetHandle.CameraTarget; | |
} | |
} | |
} |
This file contains hidden or 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
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEditor.Graphing; | |
namespace UnityEditor.ShaderGraph | |
{ | |
[Title("Custom", "Input", "Texture", "_CameraDepthNormalsTexture")] | |
class DepthNormalsTextureNode : AbstractMaterialNode | |
{ | |
public const int OutputSlotId = 0; | |
const string kOutputSlotName = "Out"; | |
private string inputTexture; | |
public DepthNormalsTextureNode() | |
{ | |
name = "_CameraDepthNormalsTexture"; | |
inputTexture = "_CameraDepthNormalsTexture"; | |
UpdateNodeAfterDeserialization(); | |
} | |
public sealed override void UpdateNodeAfterDeserialization() | |
{ | |
AddSlot(new Texture2DMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output)); | |
RemoveSlotsNameNotMatching(new[] {OutputSlotId}); | |
} | |
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode) | |
{ | |
properties.AddShaderProperty(new TextureShaderProperty | |
{ | |
displayName = "Main Texture", | |
overrideReferenceName = GetVariableNameForSlot(OutputSlotId), | |
generatePropertyBlock = false | |
}); | |
} | |
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties) | |
{ | |
properties.Add(new PreviewProperty(PropertyType.Texture2D) | |
{ | |
name = GetVariableNameForSlot(OutputSlotId), | |
textureValue = Shader.GetGlobalTexture(inputTexture) | |
}); | |
} | |
public override string GetVariableNameForSlot(int slotId) | |
{ | |
return slotId == OutputSlotId ? inputTexture : base.GetVariableNameForSlot(slotId); | |
} | |
} | |
} |
This file contains hidden or 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
float3 DecodeViewNormalStereo( float4 enc4 ) | |
{ | |
float kScale = 1.7777; | |
float3 nn = enc4.xyz*float3(2*kScale,2*kScale,0) + float3(-kScale,-kScale,1); | |
float g = 2.0 / dot(nn.xyz,nn.xyz); | |
float3 n; | |
n.xy = g*nn.xy; | |
n.z = g-1; | |
return n; | |
} | |
float3 DecodeNormal( float4 enc) | |
{ | |
return DecodeViewNormalStereo (enc); | |
} | |
void Outline_float(float4 ScreenPos, float Scale, float DepthThreshold, float NormalThreshold, float2 Texel, Texture2D DepthNormalsTexture, Texture2D DepthTexture, SamplerState Sampler, out float Out) | |
{ | |
float halfScaleFloor = floor(Scale * 0.5); | |
float halfScaleCeil = ceil(Scale * 0.5); | |
float2 bottomLeftUV = ScreenPos.xy - float2(Texel.x, Texel.y) * halfScaleFloor; | |
float2 topRightUV = ScreenPos.xy + float2(Texel.x, Texel.y) * halfScaleCeil; | |
float2 bottomRightUV = ScreenPos.xy + float2(Texel.x * halfScaleCeil, -Texel.y * halfScaleFloor); | |
float2 topLeftUV = ScreenPos.xy + float2(-Texel.x * halfScaleFloor, Texel.y * halfScaleCeil); | |
// Depth from DepthTexture | |
float depth0 =SAMPLE_TEXTURE2D(DepthTexture, Sampler, bottomLeftUV).r; | |
float depth1 =SAMPLE_TEXTURE2D(DepthTexture, Sampler, topRightUV).r; | |
float depth2 =SAMPLE_TEXTURE2D(DepthTexture, Sampler, bottomRightUV).r; | |
float depth3 =SAMPLE_TEXTURE2D(DepthTexture, Sampler, bottomLeftUV).r; | |
float depthFiniteDifference0 = depth1 - depth0; | |
float depthFiniteDifference1 = depth3 - depth2; | |
float edgeDepth = sqrt(pow(depthFiniteDifference0, 2) + pow(depthFiniteDifference1, 2)) * 100; | |
float newDepthThreshold = DepthThreshold * depth0; | |
edgeDepth = edgeDepth > newDepthThreshold ? 1 : 0; | |
// Normals extracted from DepthNormalsTexture | |
float3 normal0 = DecodeNormal(SAMPLE_TEXTURE2D(DepthNormalsTexture, Sampler, bottomLeftUV)); | |
float3 normal1 = DecodeNormal(SAMPLE_TEXTURE2D(DepthNormalsTexture, Sampler, topRightUV)); | |
float3 normal2 = DecodeNormal(SAMPLE_TEXTURE2D(DepthNormalsTexture, Sampler, bottomRightUV)); | |
float3 normal3 = DecodeNormal(SAMPLE_TEXTURE2D(DepthNormalsTexture, Sampler, topLeftUV)); | |
float3 normalFiniteDifference0 = normal1 - normal0; | |
float3 normalFiniteDifference1 = normal3 - normal2; | |
float edgeNormal = sqrt(dot(normalFiniteDifference0, normalFiniteDifference0) + dot(normalFiniteDifference1, normalFiniteDifference1)); | |
edgeNormal = edgeNormal > NormalThreshold ? 1 : 0; | |
// Combined | |
float edge = max(edgeDepth, edgeNormal); | |
Out = edge; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment