diff --git a/Assets/Code/Scripts/Rendering.meta b/Assets/Code/Scripts/Rendering.meta new file mode 100644 index 0000000..3510470 --- /dev/null +++ b/Assets/Code/Scripts/Rendering.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 97a4ae8015df4732ac9524441048a765 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Code/Scripts/Rendering/CRTRendererFeature.cs b/Assets/Code/Scripts/Rendering/CRTRendererFeature.cs new file mode 100644 index 0000000..4f708bd --- /dev/null +++ b/Assets/Code/Scripts/Rendering/CRTRendererFeature.cs @@ -0,0 +1,173 @@ +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.RenderGraphModule; +using UnityEngine.Rendering.RenderGraphModule.Util; +using UnityEngine.Rendering.Universal; + +public class CRTRendererFeature : ScriptableRendererFeature +{ + [System.Serializable] + public class CRTSettings + { + public bool EffectEnabled = true; + public RenderPassEvent PassEvent = RenderPassEvent.AfterRenderingPostProcessing; + public Shader CRTShader; + + [Range(0f, 1f)] public float Intensity = 0.65f; + [Range(0f, 2f)] public float ScanlineDensity = 1.2f; + [Range(0f, 1f)] public float ScanlineStrength = 0.18f; + [Range(0f, 0.2f)] public float Curvature = 0.04f; + [Range(0f, 1f)] public float VignetteStrength = 0.28f; + [Range(0f, 0.05f)] public float ChromaticAberration = 0.004f; + [Range(0f, 0.2f)] public float NoiseStrength = 0.03f; + [Range(0f, 0.1f)] public float FlickerStrength = 0.015f; + } + + class CRTPass : ScriptableRenderPass + { + private readonly ProfilingSampler m_ProfilingSampler = new("CRT Effect"); + + private Material m_Material; + private CRTSettings m_Settings; + private RTHandle m_TempColorTexture; + + public void Setup(Material material, CRTSettings settings) + { + m_Material = material; + m_Settings = settings; + renderPassEvent = settings.PassEvent; + requiresIntermediateTexture = true; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + if (m_Material == null || m_Settings == null || !m_Settings.EffectEnabled) + { + return; + } + + UniversalResourceData resourceData = frameData.Get(); + if (resourceData.isActiveTargetBackBuffer) + { + return; + } + + m_Material.SetFloat("_Intensity", m_Settings.Intensity); + m_Material.SetFloat("_ScanlineDensity", m_Settings.ScanlineDensity); + m_Material.SetFloat("_ScanlineStrength", m_Settings.ScanlineStrength); + m_Material.SetFloat("_Curvature", m_Settings.Curvature); + m_Material.SetFloat("_VignetteStrength", m_Settings.VignetteStrength); + m_Material.SetFloat("_ChromaticAberration", m_Settings.ChromaticAberration); + m_Material.SetFloat("_NoiseStrength", m_Settings.NoiseStrength); + m_Material.SetFloat("_FlickerStrength", m_Settings.FlickerStrength); + + TextureHandle source = resourceData.activeColorTexture; + TextureDesc destinationDesc = renderGraph.GetTextureDesc(source); + destinationDesc.name = "CameraColor-CRT"; + destinationDesc.clearBuffer = false; + + TextureHandle destination = renderGraph.CreateTexture(destinationDesc); + RenderGraphUtils.BlitMaterialParameters blitParams = new(source, destination, m_Material, 0); + renderGraph.AddBlitPass(blitParams, "CRT Effect"); + + resourceData.cameraColor = destination; + } + + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + cameraTextureDescriptor.depthBufferBits = 0; + RenderingUtils.ReAllocateHandleIfNeeded( + ref m_TempColorTexture, + cameraTextureDescriptor, + FilterMode.Bilinear, + TextureWrapMode.Clamp, + name: "_CRTTempColorTexture" + ); + } + + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + if (m_Material == null || m_Settings == null || !m_Settings.EffectEnabled) + { + return; + } + + if (renderingData.cameraData.isSceneViewCamera) + { + return; + } + + CommandBuffer cmd = CommandBufferPool.Get(); + + using (new ProfilingScope(cmd, m_ProfilingSampler)) + { + m_Material.SetFloat("_Intensity", m_Settings.Intensity); + m_Material.SetFloat("_ScanlineDensity", m_Settings.ScanlineDensity); + m_Material.SetFloat("_ScanlineStrength", m_Settings.ScanlineStrength); + m_Material.SetFloat("_Curvature", m_Settings.Curvature); + m_Material.SetFloat("_VignetteStrength", m_Settings.VignetteStrength); + m_Material.SetFloat("_ChromaticAberration", m_Settings.ChromaticAberration); + m_Material.SetFloat("_NoiseStrength", m_Settings.NoiseStrength); + m_Material.SetFloat("_FlickerStrength", m_Settings.FlickerStrength); + + RTHandle source = renderingData.cameraData.renderer.cameraColorTargetHandle; + Blitter.BlitCameraTexture(cmd, source, m_TempColorTexture, m_Material, 0); + Blitter.BlitCameraTexture(cmd, m_TempColorTexture, source); + } + + context.ExecuteCommandBuffer(cmd); + CommandBufferPool.Release(cmd); + } + + public void Dispose() + { + m_TempColorTexture?.Release(); + m_TempColorTexture = null; + } + } + + public CRTSettings Settings = new(); + + private CRTPass m_Pass; + private Material m_Material; + + public override void Create() + { + if (Settings.CRTShader == null) + { + Settings.CRTShader = Shader.Find("Hidden/HeadlessHazard/CRT"); + } + + if (Settings.CRTShader != null) + { + m_Material = CoreUtils.CreateEngineMaterial(Settings.CRTShader); + } + + m_Pass ??= new CRTPass(); + } + + public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) + { + if (m_Material == null || !Settings.EffectEnabled) + { + return; + } + + if (renderingData.cameraData.cameraType != CameraType.Game) + { + return; + } + + m_Pass.Setup(m_Material, Settings); + renderer.EnqueuePass(m_Pass); + } + + protected override void Dispose(bool disposing) + { + m_Pass?.Dispose(); + m_Pass = null; + + CoreUtils.Destroy(m_Material); + m_Material = null; + } +} diff --git a/Assets/Code/Scripts/Rendering/CRTRendererFeature.cs.meta b/Assets/Code/Scripts/Rendering/CRTRendererFeature.cs.meta new file mode 100644 index 0000000..7bcc2e6 --- /dev/null +++ b/Assets/Code/Scripts/Rendering/CRTRendererFeature.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f2de7a6cfbd47c8bc740d43bb991205 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Code/Shaders/CRTScreenEffect.shader b/Assets/Code/Shaders/CRTScreenEffect.shader new file mode 100644 index 0000000..8f55a39 --- /dev/null +++ b/Assets/Code/Shaders/CRTScreenEffect.shader @@ -0,0 +1,97 @@ +Shader "Hidden/HeadlessHazard/CRT" +{ + Properties + { + _Intensity ("Intensity", Range(0,1)) = 0.65 + _ScanlineDensity ("Scanline Density", Range(0,2)) = 1.2 + _ScanlineStrength ("Scanline Strength", Range(0,1)) = 0.18 + _Curvature ("Curvature", Range(0,0.2)) = 0.04 + _VignetteStrength ("Vignette Strength", Range(0,1)) = 0.28 + _ChromaticAberration ("Chromatic Aberration", Range(0,0.05)) = 0.004 + _NoiseStrength ("Noise Strength", Range(0,0.2)) = 0.03 + _FlickerStrength ("Flicker Strength", Range(0,0.1)) = 0.015 + } + + SubShader + { + Tags { "RenderPipeline" = "UniversalPipeline" } + + Pass + { + Name "CRT" + ZWrite Off + ZTest Always + Cull Off + Blend One Zero + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment Frag + #pragma target 3.5 + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" + + float _Intensity; + float _ScanlineDensity; + float _ScanlineStrength; + float _Curvature; + float _VignetteStrength; + float _ChromaticAberration; + float _NoiseStrength; + float _FlickerStrength; + + float Random01(float2 seed) + { + return frac(sin(dot(seed, float2(12.9898, 78.233))) * 43758.5453); + } + + float2 DistortUV(float2 uv, float curvature) + { + float2 center = uv * 2.0 - 1.0; + float radius2 = dot(center, center); + center *= 1.0 + (radius2 * curvature); + return center * 0.5 + 0.5; + } + + half4 Frag(Varyings input) : SV_Target + { + float2 uv = input.texcoord; + float2 curvedUV = DistortUV(uv, _Curvature); + + if (curvedUV.x < 0.0 || curvedUV.x > 1.0 || curvedUV.y < 0.0 || curvedUV.y > 1.0) + { + return half4(0.0, 0.0, 0.0, 1.0); + } + + float2 fromCenter = curvedUV - 0.5; + float2 aberrationOffset = fromCenter * _ChromaticAberration; + + half red = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, curvedUV + aberrationOffset).r; + half green = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, curvedUV).g; + half blue = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, curvedUV - aberrationOffset).b; + half3 color = half3(red, green, blue); + + float scanlineWave = sin((curvedUV.y * _ScreenParams.y * 0.5 * _ScanlineDensity) + (_Time.y * 18.0)); + float scanlineMask = lerp(1.0, saturate(0.7 + 0.3 * scanlineWave), _ScanlineStrength); + color *= scanlineMask; + + float noise = Random01(curvedUV * _ScreenParams.xy + _Time.yy * 37.0) - 0.5; + color += noise * _NoiseStrength; + + float flicker = 1.0 - (_FlickerStrength * (0.5 + 0.5 * sin(_Time.y * 32.0))); + color *= flicker; + + float2 vignetteUV = curvedUV * (1.0 - curvedUV.yx); + float vignette = saturate(pow(vignetteUV.x * vignetteUV.y * 18.0, 0.2)); + color *= lerp(1.0 - _VignetteStrength, 1.0, vignette); + + half3 baseColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv).rgb; + half3 finalColor = lerp(baseColor, color, _Intensity); + + return half4(finalColor, 1.0); + } + ENDHLSL + } + } +} diff --git a/Assets/Code/Shaders/CRTScreenEffect.shader.meta b/Assets/Code/Shaders/CRTScreenEffect.shader.meta new file mode 100644 index 0000000..6936b44 --- /dev/null +++ b/Assets/Code/Shaders/CRTScreenEffect.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0a9f7eb85c2f4f9f8ec82c8565f4e8b1 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + preprocessorOverride: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Settings/PC_Renderer.asset b/Assets/Settings/PC_Renderer.asset index 475b02e..c110d16 100644 --- a/Assets/Settings/PC_Renderer.asset +++ b/Assets/Settings/PC_Renderer.asset @@ -1,5 +1,30 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!114 &-4377071725885749089 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f2de7a6cfbd47c8bc740d43bb991205, type: 3} + m_Name: CRTRendererFeature + m_EditorClassIdentifier: Assembly-CSharp::CRTRendererFeature + m_Active: 1 + Settings: + EffectEnabled: 1 + PassEvent: 600 + CRTShader: {fileID: 4800000, guid: 0a9f7eb85c2f4f9f8ec82c8565f4e8b1, type: 3} + Intensity: 0.65 + ScanlineDensity: 1.2 + ScanlineStrength: 0.18 + Curvature: 0.04 + VignetteStrength: 0.28 + ChromaticAberration: 0.004 + NoiseStrength: 0.03 + FlickerStrength: 0.015 --- !u!114 &11400000 MonoBehaviour: m_ObjectHideFlags: 0 @@ -13,32 +38,28 @@ MonoBehaviour: m_Name: PC_Renderer m_EditorClassIdentifier: debugShaders: - debugReplacementPS: {fileID: 4800000, guid: cf852408f2e174538bcd9b7fda1c5ae7, - type: 3} + debugReplacementPS: {fileID: 4800000, guid: cf852408f2e174538bcd9b7fda1c5ae7, type: 3} hdrDebugViewPS: {fileID: 4800000, guid: 573620ae32aec764abd4d728906d2587, type: 3} - probeVolumeSamplingDebugComputeShader: {fileID: 7200000, guid: 53626a513ea68ce47b59dc1299fe3959, - type: 3} + probeVolumeSamplingDebugComputeShader: {fileID: 7200000, guid: 53626a513ea68ce47b59dc1299fe3959, type: 3} probeVolumeResources: - probeVolumeDebugShader: {fileID: 4800000, guid: e5c6678ed2aaa91408dd3df699057aae, - type: 3} - probeVolumeFragmentationDebugShader: {fileID: 4800000, guid: 03cfc4915c15d504a9ed85ecc404e607, - type: 3} - probeVolumeOffsetDebugShader: {fileID: 4800000, guid: 53a11f4ebaebf4049b3638ef78dc9664, - type: 3} - probeVolumeSamplingDebugShader: {fileID: 4800000, guid: 8f96cd657dc40064aa21efcc7e50a2e7, - type: 3} - probeSamplingDebugMesh: {fileID: -3555484719484374845, guid: 57d7c4c16e2765b47a4d2069b311bffe, - type: 3} - probeSamplingDebugTexture: {fileID: 2800000, guid: 24ec0e140fb444a44ab96ee80844e18e, - type: 3} - probeVolumeBlendStatesCS: {fileID: 7200000, guid: b9a23f869c4fd45f19c5ada54dd82176, - type: 3} + probeVolumeDebugShader: {fileID: 4800000, guid: e5c6678ed2aaa91408dd3df699057aae, type: 3} + probeVolumeFragmentationDebugShader: {fileID: 4800000, guid: 03cfc4915c15d504a9ed85ecc404e607, type: 3} + probeVolumeOffsetDebugShader: {fileID: 4800000, guid: 53a11f4ebaebf4049b3638ef78dc9664, type: 3} + probeVolumeSamplingDebugShader: {fileID: 4800000, guid: 8f96cd657dc40064aa21efcc7e50a2e7, type: 3} + probeSamplingDebugMesh: {fileID: -3555484719484374845, guid: 57d7c4c16e2765b47a4d2069b311bffe, type: 3} + probeSamplingDebugTexture: {fileID: 2800000, guid: 24ec0e140fb444a44ab96ee80844e18e, type: 3} + probeVolumeBlendStatesCS: {fileID: 7200000, guid: b9a23f869c4fd45f19c5ada54dd82176, type: 3} m_RendererFeatures: - {fileID: 7833122117494664109} - m_RendererFeatureMap: ad6b866f10d7b46c + - {fileID: -4377071725885749089} + m_RendererFeatureMap: ad6b866f10d7b46c9f882cbe748441c3 m_UseNativeRenderPass: 1 + xrSystemData: {fileID: 0} postProcessData: {fileID: 11400000, guid: 41439944d30ece34e96484bdb6645b55, type: 2} - m_AssetVersion: 2 + m_AssetVersion: 3 + m_PrepassLayerMask: + serializedVersion: 2 + m_Bits: 4294967295 m_OpaqueLayerMask: serializedVersion: 2 m_Bits: 4294967295 @@ -56,6 +77,8 @@ MonoBehaviour: m_RenderingMode: 2 m_DepthPrimingMode: 0 m_CopyDepthMode: 0 + m_DepthAttachmentFormat: 0 + m_DepthTextureFormat: 0 m_AccurateGbufferNormals: 0 m_IntermediateTextureMode: 0 --- !u!114 &7833122117494664109 @@ -84,12 +107,3 @@ MonoBehaviour: BlurQuality: 0 Falloff: 100 SampleCount: -1 - m_BlueNoise256Textures: - - {fileID: 2800000, guid: 36f118343fc974119bee3d09e2111500, type: 3} - - {fileID: 2800000, guid: 4b7b083e6b6734e8bb2838b0b50a0bc8, type: 3} - - {fileID: 2800000, guid: c06cc21c692f94f5fb5206247191eeee, type: 3} - - {fileID: 2800000, guid: cb76dd40fa7654f9587f6a344f125c9a, type: 3} - - {fileID: 2800000, guid: e32226222ff144b24bf3a5a451de54bc, type: 3} - - {fileID: 2800000, guid: 3302065f671a8450b82c9ddf07426f3a, type: 3} - - {fileID: 2800000, guid: 56a77a3e8d64f47b6afe9e3c95cb57d5, type: 3} - m_Shader: {fileID: 4800000, guid: 0849e84e3d62649e8882e9d6f056a017, type: 3}