ether shader modified to work with spectrum

This commit is contained in:
ntr committed 2022-05-26 13:29:30 +10:00
1 parent a2f0ed170b
commit 8e9f8c598f
41 files changed
+2982 -260

No files matched your search

+133
View File
@@ -0,0 +1,133 @@
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
#if UNITY_EDITOR
using UnityEditor.Rendering.HighDefinition;
using UnityEditor;
[CustomPassDrawerAttribute(typeof(TIPS))]
class TIPSEditor : CustomPassDrawer
{
private class Styles
{
public static float defaultLineSpace = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
public static GUIContent mesh = new GUIContent("Mesh", "Mesh used for the scanner effect.");
public static GUIContent size = new GUIContent("Size", "Size of the effect.");
public static GUIContent rotationSpeed = new GUIContent("Speed", "Speed of rotation.");
public static GUIContent edgeThreshold = new GUIContent("Edge Threshold", "Edge detect effect threshold.");
public static GUIContent edgeRadius = new GUIContent("Edge Radius", "Radius of the edge detect effect.");
public static GUIContent glowColor = new GUIContent("Color", "Color of the effect");
}
SerializedProperty mesh;
SerializedProperty size;
SerializedProperty rotationSpeed;
SerializedProperty edgeDetectThreshold;
SerializedProperty edgeRadius;
SerializedProperty glowColor;
protected override void Initialize(SerializedProperty customPass)
{
mesh = customPass.FindPropertyRelative("mesh");
size = customPass.FindPropertyRelative("size");
rotationSpeed = customPass.FindPropertyRelative("rotationSpeed");
edgeDetectThreshold = customPass.FindPropertyRelative("edgeDetectThreshold");
edgeRadius = customPass.FindPropertyRelative("edgeRadius");
glowColor = customPass.FindPropertyRelative("glowColor");
}
// We only need the name to be displayed, the rest is controlled by the TIPS effect
protected override PassUIFlag commonPassUIFlags => PassUIFlag.Name;
protected override void DoPassGUI(SerializedProperty customPass, Rect rect)
{
mesh.objectReferenceValue = EditorGUI.ObjectField(rect, Styles.mesh, mesh.objectReferenceValue, typeof(Mesh), false);
rect.y += Styles.defaultLineSpace;
size.floatValue = EditorGUI.Slider(rect, Styles.size, size.floatValue, 0.2f, TIPS.kMaxDistance);
rect.y += Styles.defaultLineSpace;
rotationSpeed.floatValue = EditorGUI.Slider(rect, Styles.rotationSpeed, rotationSpeed.floatValue, 0f, 30f);
rect.y += Styles.defaultLineSpace;
edgeDetectThreshold.floatValue = EditorGUI.Slider(rect, Styles.edgeThreshold, edgeDetectThreshold.floatValue, 0.1f, 5f);
rect.y += Styles.defaultLineSpace;
edgeRadius.intValue = EditorGUI.IntSlider(rect, Styles.edgeRadius, edgeRadius.intValue, 1, 6);
rect.y += Styles.defaultLineSpace;
glowColor.colorValue = EditorGUI.ColorField(rect, Styles.glowColor, glowColor.colorValue, true, false, true);
}
protected override float GetPassHeight(SerializedProperty customPass) => Styles.defaultLineSpace * 6;
}
#endif
class TIPS : CustomPass
{
public Mesh mesh = null;
public float size = 5;
public float rotationSpeed = 5;
public float edgeDetectThreshold = 1;
public int edgeRadius = 2;
public Color glowColor = Color.white;
public const float kMaxDistance = 1000;
public Material tipsMeshMaterial;
Material fullscreenMaterial;
RTHandle tipsBuffer; // additional render target for compositing the custom and camera color buffers
int compositingPass;
int blurPass;
// It can be used to configure render targets and their clear state. Also to create temporary render target textures.
// When empty this render pass will render to the active camera render target.
// You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
// The render pipeline will ensure target setup and clearing happens in an performance manner.
protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
{
tipsMeshMaterial = Resources.Load<Material>("Shader Graphs_TIPS_Effect");
fullscreenMaterial = CoreUtils.CreateEngineMaterial("FullScreen/TIPS");
tipsBuffer = RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, useDynamicScale: true, name: "TIPS Buffer");
compositingPass = fullscreenMaterial.FindPass("Compositing");
blurPass = fullscreenMaterial.FindPass("Blur");
targetColorBuffer = TargetBuffer.Custom;
targetDepthBuffer = TargetBuffer.Custom;
clearFlags = ClearFlag.All;
}
protected override void Execute(CustomPassContext ctx)
{
if (fullscreenMaterial == null)
return ;
if (mesh != null && tipsMeshMaterial != null)
{
Transform cameraTransform = ctx.hdCamera.camera.transform;
Matrix4x4 trs = Matrix4x4.TRS(cameraTransform.position, Quaternion.Euler(0f, Time.realtimeSinceStartup * rotationSpeed, Time.realtimeSinceStartup * rotationSpeed * 0.5f), Vector3.one * size);
tipsMeshMaterial.SetFloat("_Intensity", (0.2f / size) * kMaxDistance);
ctx.cmd.DrawMesh(mesh, trs, tipsMeshMaterial, 0, tipsMeshMaterial.FindPass("ForwardOnly"));
}
ctx.propertyBlock.SetFloat("_EdgeDetectThreshold", edgeDetectThreshold);
ctx.propertyBlock.SetColor("_GlowColor", glowColor);
ctx.propertyBlock.SetFloat("_EdgeRadius", (float)edgeRadius);
ctx.propertyBlock.SetFloat("_BypassMeshDepth", (mesh != null) ? 0 : size);
CoreUtils.SetRenderTarget(ctx.cmd, tipsBuffer, ClearFlag.Color);
CoreUtils.DrawFullScreen(ctx.cmd, fullscreenMaterial, shaderPassId: compositingPass, properties: ctx.propertyBlock);
ctx.propertyBlock.SetTexture("_TIPSBuffer", tipsBuffer);
CoreUtils.SetRenderTarget(ctx.cmd, ctx.cameraColorBuffer);
CoreUtils.DrawFullScreen(ctx.cmd, fullscreenMaterial, shaderPassId: blurPass, properties: ctx.propertyBlock);
}
protected override void Cleanup()
{
CoreUtils.Destroy(fullscreenMaterial);
tipsBuffer.Release();
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f0ebb66443d21f744bd46bb07576d93a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+194
View File
@@ -0,0 +1,194 @@
Shader "FullScreen/TIPS"
{
HLSLINCLUDE
#pragma vertex Vert
#pragma target 4.5
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl"
// The PositionInputs struct allow you to retrieve a lot of useful information for your fullScreenShader:
// struct PositionInputs
// {
// float3 positionWS; // World space position (could be camera-relative)
// float2 positionNDC; // Normalized screen coordinates within the viewport : [0, 1) (with the half-pixel offset)
// uint2 positionSS; // Screen space pixel coordinates : [0, NumPixels)
// uint2 tileCoord; // Screen tile coordinates : [0, NumTiles)
// float deviceDepth; // Depth from the depth buffer : [0, 1] (typically reversed)
// float linearDepth; // View space Z coordinate : [Near, Far]
// };
// To sample custom buffers, you have access to these functions:
// But be careful, on most platforms you can't sample to the bound color buffer. It means that you
// can't use the SampleCustomColor when the pass color buffer is set to custom (and same for camera the buffer).
// float4 SampleCustomColor(float2 uv);
// float4 LoadCustomColor(uint2 pixelCoords);
// float LoadCustomDepth(uint2 pixelCoords);
// float SampleCustomDepth(float2 uv);
// There are also a lot of utility function you can use inside Common.hlsl and Color.hlsl,
// you can check them out in the source code of the core SRP package.
TEXTURE2D_X(_TIPSBuffer);
float _EdgeDetectThreshold;
float3 _GlowColor;
float _EdgeRadius;
float _BypassMeshDepth;
float SampleClampedDepth(float2 uv) { return SampleCameraDepth(clamp(uv, _ScreenSize.zw, 1 - _ScreenSize.zw)).r; }
float EdgeDetect(float2 uv, float depthThreshold, float normalThreshold)
{
normalThreshold *= _EdgeDetectThreshold;
depthThreshold *= _EdgeDetectThreshold;
float halfScaleFloor = floor(_EdgeRadius * 0.5);
float halfScaleCeil = ceil(_EdgeRadius * 0.5);
// Compute uv position to fetch depth informations
float2 bottomLeftUV = uv - float2(_ScreenSize.zw.x, _ScreenSize.zw.y) * halfScaleFloor;
float2 topRightUV = uv + float2(_ScreenSize.zw.x, _ScreenSize.zw.y) * halfScaleCeil;
float2 bottomRightUV = uv + float2(_ScreenSize.zw.x * halfScaleCeil, -_ScreenSize.zw.y * halfScaleFloor);
float2 topLeftUV = uv + float2(-_ScreenSize.zw.x * halfScaleFloor, _ScreenSize.zw.y * halfScaleCeil);
// Depth from camera buffer
float depth0 = SampleClampedDepth(bottomLeftUV);
float depth1 = SampleClampedDepth(topRightUV);
float depth2 = SampleClampedDepth(bottomRightUV);
float depth3 = SampleClampedDepth(topLeftUV);
float depthDerivative0 = depth1 - depth0;
float depthDerivative1 = depth3 - depth2;
float edgeDepth = sqrt(pow(depthDerivative0, 2) + pow(depthDerivative1, 2)) * 100;
float newDepthThreshold = depthThreshold * depth0;
edgeDepth = edgeDepth > newDepthThreshold ? 1 : 0;
// Normals extracted from the camera normal buffer
NormalData normalData0, normalData1, normalData2, normalData3;
DecodeFromNormalBuffer(_ScreenSize.xy * bottomLeftUV, normalData0);
DecodeFromNormalBuffer(_ScreenSize.xy * topRightUV, normalData1);
DecodeFromNormalBuffer(_ScreenSize.xy * bottomRightUV, normalData2);
DecodeFromNormalBuffer(_ScreenSize.xy * topLeftUV, normalData3);
float3 normalFiniteDifference0 = normalData1.normalWS - normalData0.normalWS;
float3 normalFiniteDifference1 = normalData3.normalWS - normalData2.normalWS;
float edgeNormal = sqrt(dot(normalFiniteDifference0, normalFiniteDifference0) + dot(normalFiniteDifference1, normalFiniteDifference1));
edgeNormal = edgeNormal > normalThreshold ? 1 : 0;
// Combined
return max(edgeDepth, edgeNormal);
}
float4 Compositing(Varyings varyings) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
float depth = LoadCameraDepth(varyings.positionCS.xy);
PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
float4 color = float4(0.0, 0.0, 0.0, 0.0);
// Load the camera color buffer at the mip 0 if we're not at the before rendering injection point
if (_CustomPassInjectionPoint != CUSTOMPASSINJECTIONPOINT_BEFORE_RENDERING)
color = float4(CustomPassSampleCameraColor(posInput.positionNDC.xy, 0), 1);
// Do some normal and depth based edge detection on the camera buffers.
float3 edgeDetectColor = EdgeDetect(posInput.positionNDC.xy, 2, 1) * _GlowColor;
// Remove the edge detect effect between the sky and objects when the object is inside the sphere
edgeDetectColor *= depth != UNITY_RAW_FAR_CLIP_VALUE;
// Load depth and color information from the custom buffer
float meshDepthPos = LoadCustomDepth(posInput.positionSS.xy);
float4 meshColor = LoadCustomColor(posInput.positionSS.xy);
// Change the color of the icosahedron mesh
meshColor = float4(_GlowColor, 1) * meshColor;
// Transform the raw depth into eye space depth
float sceneDepth = LinearEyeDepth(depth, _ZBufferParams);
float meshDepth = LinearEyeDepth(meshDepthPos, _ZBufferParams);
if (_BypassMeshDepth != 0)
meshDepth = _BypassMeshDepth;
// Add the intersection with mesh and scene depth to the edge detect result
edgeDetectColor = lerp(edgeDetectColor, _GlowColor, saturate(2 - abs(meshDepth - sceneDepth) * 200 * rcp(_EdgeRadius)));
// Blend the mesh color and edge detect color using the mesh alpha transparency
float3 edgeMeshColor = lerp(edgeDetectColor, meshColor.xyz, (meshDepth < sceneDepth) ? meshColor.a : 0);
// Avoid edge detection effect to leak inside the isocahedron mesh
float3 finalColor = saturate(meshDepth - sceneDepth) > 0 ? color.xyz : edgeMeshColor;
return float4(finalColor, 1);
}
// Try to remove fireflies
float4 Blur(Varyings varyings) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
float depth = LoadCameraDepth(varyings.positionCS.xy);
float meshDepth = LoadCustomDepth(varyings.positionCS.xy);
PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
// It didn't worked :p
return float4(LOAD_TEXTURE2D_X_LOD(_TIPSBuffer, posInput.positionSS.xy, 0).rgb, 1);
float3 color = LOAD_TEXTURE2D_X_LOD(_TIPSBuffer, posInput.positionSS.xy, 0).rgb;
// don't blur non outlined image
if (LinearEyeDepth(depth, _ZBufferParams) < LinearEyeDepth(meshDepth, _ZBufferParams) + 0.1)
return float4(color.r, 0, 0, 1);
float3 t;
for (float x = -1; x <= 1; x++)
for (float y = -1; y <= 1; y++)
{
t += LOAD_TEXTURE2D_X_LOD(_TIPSBuffer, posInput.positionSS.xy + float2(x, y), 0).rgb;
}
if (Luminance(t) < Luminance(_GlowColor) * 3)
color = 0;
return float4(color, 1);
}
ENDHLSL
SubShader
{
Pass
{
Name "Compositing"
ZWrite Off
ZTest Always
Blend Off
Cull Off
HLSLPROGRAM
#pragma fragment Compositing
ENDHLSL
}
Pass
{
Name "Blur"
ZWrite Off
ZTest Always
Blend Off
Cull Off
HLSLPROGRAM
#pragma fragment Blur
ENDHLSL
}
}
Fallback Off
}
+10
View File
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: cb4760d54220b584582c8a12cc4c42ed
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant: