using System; using System.Collections.Generic; #if UNITY_EDITOR using System.Reflection; using UnityEditor.Build.Reporting; #endif using UnityEngine; using UnityEngine.Rendering; #if UNITY_2023_3_OR_NEWER using UnityEngine.Rendering.RenderGraphModule; #endif using UnityEngine.Rendering.Universal; using UnityEngine.SceneManagement; using static Beautify.Universal.Beautify; namespace Beautify.Universal { public static class ShaderParams { public static int mainTex = Shader.PropertyToID("_MainTex"); public static int inputTex = Shader.PropertyToID("_BeautifyInputTex"); public static int blueNoiseTex = Shader.PropertyToID("_BlueNoise"); public static int sharpen = Shader.PropertyToID("_Sharpen"); public static int colorParams = Shader.PropertyToID("_Params"); public static int colorBoost = Shader.PropertyToID("_ColorBoost"); public static int tintColor = Shader.PropertyToID("_TintColor"); public static int compareTex = Shader.PropertyToID("_CompareTex"); public static int compareParams = Shader.PropertyToID("_CompareParams"); public static int fxColor = Shader.PropertyToID("_FXColor"); public static int lutTex = Shader.PropertyToID("_LUTTex"); public static int lut3DTexture = Shader.PropertyToID("_LUT3DTex"); public static int lut3DParams = Shader.PropertyToID("_LUT3DParams"); public static int colorTemp = Shader.PropertyToID("_ColorTemp"); public static int flipY = Shader.PropertyToID("_FlipY"); public static int tonemapAGXGamma = Shader.PropertyToID("_TonemapAGXGamma"); public static int blurScale = Shader.PropertyToID("_BlurScale"); public static int tempBlurRT = Shader.PropertyToID("_BeautifyTempBlurRT"); public static int tempBloomCustomComposeRT = Shader.PropertyToID("_BeautifyTempBloomCustomComposeRT"); public static int tempBloomCustomComposeRTOriginal = Shader.PropertyToID("_BeautifyTempBloomCustomComposeRT"); public static int tempBlurOneDirRT = Shader.PropertyToID("_BeautifyTempBlurOneDir0"); public static int tempBlurOneDirRTOriginal = Shader.PropertyToID("_BeautifyTempBlurOneDir0"); public static int tempBlurDownscaling = Shader.PropertyToID("_BeautifyTempBlurDownscaling"); public static int bloom = Shader.PropertyToID("_Bloom"); public static int bloomWeights = Shader.PropertyToID("_BloomWeights"); public static int bloomWeights2 = Shader.PropertyToID("_BloomWeights2"); public static int bloomDepthThreshold = Shader.PropertyToID("_BloomDepthThreshold"); public static int bloomNearThreshold = Shader.PropertyToID("_BloomNearThreshold"); public static int bloomTex = Shader.PropertyToID("_BloomTex"); public static int bloomTex1 = Shader.PropertyToID("_BloomTex1"); public static int bloomTex2 = Shader.PropertyToID("_BloomTex2"); public static int bloomTex3 = Shader.PropertyToID("_BloomTex3"); public static int bloomTex4 = Shader.PropertyToID("_BloomTex4"); public static int bloomTint = Shader.PropertyToID("_BloomTint"); public static int bloomTint0 = Shader.PropertyToID("_BloomTint0"); public static int bloomTint1 = Shader.PropertyToID("_BloomTint1"); public static int bloomTint2 = Shader.PropertyToID("_BloomTint2"); public static int bloomTint3 = Shader.PropertyToID("_BloomTint3"); public static int bloomTint4 = Shader.PropertyToID("_BloomTint4"); public static int bloomTint5 = Shader.PropertyToID("_BloomTint5"); public static int bloomSpread = Shader.PropertyToID("_BloomSpread"); public static int bloomExclusionZBias = Shader.PropertyToID("_BloomLayerZBias"); public static int dirt = Shader.PropertyToID("_Dirt"); public static int dirtTex = Shader.PropertyToID("_OverlayTex"); public static int screenLum = Shader.PropertyToID("_ScreenLum"); public static int afData = Shader.PropertyToID("_AFData"); public static int afDepthThreshold = Shader.PropertyToID("_AFDepthThreshold"); public static int afNearThreshold = Shader.PropertyToID("_AFNearThreshold"); public static int afTintColor = Shader.PropertyToID("_AFTint"); public static int afCombineTex = Shader.PropertyToID("_CombineTex"); public static int sfSunData = Shader.PropertyToID("_SunData"); public static int sfSunPos = Shader.PropertyToID("_SunPos"); public static int sfSunDir = Shader.PropertyToID("_SunDir"); public static int sfSunTintColor = Shader.PropertyToID("_SunTint"); public static int sfOcclusionThreshold = Shader.PropertyToID("_SunOcclusionThreshold"); public static int sfCoronaRays1 = Shader.PropertyToID("_SunCoronaRays1"); public static int sfCoronaRays2 = Shader.PropertyToID("_SunCoronaRays2"); public static int sfGhosts1 = Shader.PropertyToID("_SunGhosts1"); public static int sfGhosts2 = Shader.PropertyToID("_SunGhosts2"); public static int sfGhosts3 = Shader.PropertyToID("_SunGhosts3"); public static int sfGhosts4 = Shader.PropertyToID("_SunGhosts4"); public static int sfHalo = Shader.PropertyToID("_SunHalo"); public static int sfRT = Shader.PropertyToID("_BeautifyTempSF0"); public static int sfFlareTex = Shader.PropertyToID("_FlareTex"); public static int sfAspectRatio = Shader.PropertyToID("_SunFlaresAspectRatio"); public static int sfOcclusionTex = Shader.PropertyToID("_OcclusionTex"); public static int dofRT = Shader.PropertyToID("_DoFTex"); public static int dofTempBlurDoFAlphaRT = Shader.PropertyToID("_BeautifyTempBlurAlphaDoF"); public static int dofTempBlurDoFTemp1RT = Shader.PropertyToID("_BeautifyTempBlurPass1DoF"); public static int dofTempBlurDoFTemp2RT = Shader.PropertyToID("_BeautifyTempBlurPass2DoF"); public static int dofBokehData = Shader.PropertyToID("_BokehData"); public static int dofBokehData2 = Shader.PropertyToID("_BokehData2"); public static int dofBokehData3 = Shader.PropertyToID("_BokehData3"); public static int dofBokehRT = Shader.PropertyToID("_DofBokeh"); public static int vignette = Shader.PropertyToID("_Vignetting"); public static int vignetteData = Shader.PropertyToID("_VignettingData"); public static int vignetteData2 = Shader.PropertyToID("_VignettingData2"); public static int vignetteMask = Shader.PropertyToID("_VignettingMask"); public static int purkinje = Shader.PropertyToID("_Purkinje"); public static int eaLumSrc = Shader.PropertyToID("_EALumSrc"); public static int eaHist = Shader.PropertyToID("_EAHist"); public static int eaParams = Shader.PropertyToID("_EyeAdaptation"); public static int eaParams2 = Shader.PropertyToID("_EyeAdaptation2"); public static int eaMinCameraDistance = Shader.PropertyToID("_EyeAdaptationMinCameraDistance"); public static int eaMask = Shader.PropertyToID("_EAMask"); public static int outline = Shader.PropertyToID("_Outline"); public static int outlineData = Shader.PropertyToID("_OutlineData"); public static int outlineRT = Shader.PropertyToID("_OutlineRT"); public static int blurRT = Shader.PropertyToID("_BlurTex"); public static int blurMaskedRT = Shader.PropertyToID("_BlurMaskedTex"); public static int blurMask = Shader.PropertyToID("_BlurMask"); public static int blurData = Shader.PropertyToID("_BlurData"); // xy = center, z = width/radius, w = falloff public static int blurData2 = Shader.PropertyToID("_BlurData2"); // x = style, y = show mask public static int nightVision = Shader.PropertyToID("_NightVision"); public static int nightVisionDepth = Shader.PropertyToID("_NightVisionDepth"); public static int chromaticAberrationData = Shader.PropertyToID("_ChromaticAberrationData"); public static int chromaticTempTex = Shader.PropertyToID("_ChromaticTex"); public static int lutPreview = Shader.PropertyToID("_LUTPreview"); public static int frameColor = Shader.PropertyToID("_Frame"); public static int frameMask = Shader.PropertyToID("_FrameMask"); public static int frameData = Shader.PropertyToID("_FrameData"); public static int CustomDepthAlphaCutoff = Shader.PropertyToID("_Cutoff"); public static int CustomDepthAlphaTestCutoff = Shader.PropertyToID("_OutlineCutOff"); public static int CustomDepthBaseMap = Shader.PropertyToID("_BaseMap"); public static int edgeAntialiasing = Shader.PropertyToID("_AntialiasData"); public static int miniViewTex = Shader.PropertyToID("_MiniViewTex"); public static int miniViewRect = Shader.PropertyToID("_MiniViewRect"); public static int miniViewBlend = Shader.PropertyToID("_MiniViewBlend"); public static int filmGrainData = Shader.PropertyToID("_FilmGrainData"); public static int filmArtifactsData = Shader.PropertyToID("_FilmArtifactsData"); public const string SKW_SHARPEN = "BEAUTIFY_SHARPEN"; public const string SKW_SHARPEN_EXCLUSION_MASK = "BEAUTIFY_EXCLUSION_MASK_SHARPEN"; public const string SKW_TONEMAP_ACES = "BEAUTIFY_ACES_TONEMAP"; public const string SKW_TONEMAP_ACES_FITTED = "BEAUTIFY_ACES_FITTED_TONEMAP"; public const string SKW_TONEMAP_AGX = "BEAUTIFY_AGX_TONEMAP"; public const string SKW_LUT = "BEAUTIFY_LUT"; public const string SKW_LUT3D = "BEAUTIFY_3DLUT"; public const string SKW_BLOOM = "BEAUTIFY_BLOOM"; public const string SKW_BLOOM_USE_DEPTH = "BEAUTIFY_BLOOM_USE_DEPTH"; public const string SKW_BLOOM_USE_LAYER = "BEAUTIFY_BLOOM_USE_LAYER"; public const string SKW_BLOOM_USE_LAYER_INCLUSION = "BEAUTIFY_BLOOM_USE_LAYER_INCLUSION"; public const string SKW_BLOOM_PROP_THRESHOLDING = "BEAUTIFY_BLOOM_PROP_THRESHOLDING"; public const string SKW_DIRT = "BEAUTIFY_DIRT"; public const string SKW_ANAMORPHIC_FLARES_USE_DEPTH = "BEAUTIFY_ANAMORPHIC_FLARES_USE_DEPTH"; public const string SKW_ANAMORPHIC_FLARES_USE_LAYER = "BEAUTIFY_ANAMORPHIC_FLARES_USE_LAYER"; public const string SKW_ANAMORPHIC_FLARES_USE_LAYER_INCLUSION = "BEAUTIFY_ANAMORPHIC_FLARES_USE_LAYER_INCLUSION"; public const string SKW_ANAMORPHIC_PROP_THRESHOLDING = "BEAUTIFY_ANAMORPHIC_PROP_THRESHOLDING"; public const string SKW_EA_USE_DEPTH = "BEAUTIFY_EA_USE_DEPTH"; public const string SKW_EA_USE_MASK = "BEAUTIFY_EA_USE_MASK"; public const string SKW_DEPTH_OF_FIELD = "BEAUTIFY_DEPTH_OF_FIELD"; public const string SKW_DEPTH_OF_FIELD_TRANSPARENT = "BEAUTIFY_DOF_TRANSPARENT"; public const string SKW_VIGNETTING = "BEAUTIFY_VIGNETTING"; public const string SKW_VIGNETTING_MASK = "BEAUTIFY_VIGNET_MASK"; public const string SKW_PURKINJE = "BEAUTIFY_PURKINJE"; public const string SKW_EYE_ADAPTATION = "BEAUTIFY_EYE_ADAPTATION"; public const string SKW_OUTLINE = "BEAUTIFY_OUTLINE"; public const string SKW_OUTLINE_DEPTH_FADE = "BEAUTIFY_DEPTH_FADE"; public const string SKW_TURBO = "BEAUTIFY_TURBO"; public const string SKW_COLOR_TWEAKS = "BEAUTIFY_COLOR_TWEAKS"; public const string SKW_NIGHT_VISION = "BEAUTIFY_NIGHT_VISION"; public const string SKW_THERMAL_VISION = "BEAUTIFY_THERMAL_VISION"; public const string SKW_DITHER = "BEAUTIFY_DITHER"; public const string SKW_CHROMATIC_ABERRATION = "BEAUTIFY_CABERRATION"; public const string SKW_FRAME = "BEAUTIFY_FRAME"; public const string SKW_FILM_GRAIN = "BEAUTIFY_FILM_GRAIN"; public const string SKW_SUN_FLARES_USE_GHOSTS = "BEAUTIFY_SF_USE_GHOSTS"; public const string SKW_SUN_FLARES_OCCLUSION_INIT = "BEAUTIFY_SF_OCCLUSION_INIT"; public const string SKW_SUN_FLARES_OCCLUSION_SIMPLE = "BEAUTIFY_SF_OCCLUSION_SIMPLE"; public const string SKW_SUN_FLARES_OCCLUSION_SMOOTH = "BEAUTIFY_SF_OCCLUSION_SMOOTH"; public const string SKW_CUSTOM_DEPTH_ALPHA_TEST = "DEPTH_PREPASS_ALPHA_TEST"; public const string SKW_EDGE_ANTIALIASING = "BEAUTIFY_EDGE_AA"; public const string SKW_EDGE_ANTIALIASING_DOF = "BEAUTIFY_EDGE_AA_DOF"; public const string SKW_OUTLINE_CUSTOM_DEPTH = "BEAUTIFY_OUTLINE_CUSTOM_DEPTH"; public const string SKW_OUTLINE_OBJECT_ID = "BEAUTIFY_OUTLINE_OBJECT_ID"; public const string SKW_OUTLINE_MIN_SEPARATION = "BEAUTIFY_OUTLINE_MIN_SEPARATION"; public const string SKW_OUTLINE_OUTER_ONLY = "BEAUTIFY_OUTLINE_OUTER_ONLY"; } public class BeautifyRendererFeature : ScriptableRendererFeature { class PassData { public Camera camera; public CommandBuffer cmd; #if UNITY_2023_3_OR_NEWER public TextureHandle colorTexture; #endif } class BeautifyRenderPass : ScriptableRenderPass { enum Pass { CopyExact = 0, Compare = 1, Beautify = 2, BloomLuminance = 3, BloomDebug = 4, BlurHoriz = 5, BlurVert = 6, BloomCompose = 7, BloomResample = 8, BloomResampleAndCombine = 9, BloomLuminanceAntiflicker = 10, AnamorphicFlaresResample = 11, AnamorphicFlaresResampleAndCombine = 12, ComputeScreenLum = 13, DownsampleScreenLum = 14, BlendScreenLum = 15, SimpleBlendLum = 16, AnamorphicFlaresLuminance = 17, AnamorphicFlaresLuminanceAntiflicker = 18, SunFlares = 19, SunFlaresAdditive = 20, DoFCoC = 21, DoFCoCDebug = 22, DoFBlur = 23, DoFBlurWithoutBokeh = 24, DoFBlurHorizontally = 25, DoFBlurVertically = 26, CopyBilinear = 27, BloomExclusionLayerDebug = 28, DoFDebugTransparent = 29, ChromaticAberration = 30, OutlineDetect = 31, OutlineBlurH = 32, OutlineBlurV = 33, OutlineBlend = 34, BlurMask = 35, DoFBokeh = 36, DoFAdditive = 37, DoFBlurBokeh = 38, AnamorphicFlaresExclusionLayerDebug = 39, CopyWithMiniView = 40, SunFlaresOcclusionTest = 41 } struct BloomMipData { public int rtDown, rtUp, width, height; public int rtDownOriginal, rtUpOriginal; } const int PYRAMID_COUNT_BLOOM = 5; const int PYRAMID_COUNT_BLOOM_TURBO = 3; const int PYRAMID_COUNT_EA = 9; readonly PassData passData = new PassData(); static readonly List keywords = new List(); static string[] keywordsArray; bool setup; static Beautify beautify; static Material bMat; static ScriptableRenderer renderer; #if UNITY_2022_2_OR_NEWER static RTHandle source; #else static RenderTargetIdentifier source; #endif static CameraData cameraData; static RenderTextureDescriptor sourceDesc, sourceDescHP; static bool supportsFPTextures; static BloomMipData[] rt, rtAF; static int[] rtEA; static Texture2D dirtTexture, flareTex; class PerCamData { public RenderTexture rtEAacum, rtEAHist; public RTHandle rtSunFlaresOcclusion; public float sunFlareCurrentIntensity; public Vector4 sunLastScrPos; public float sunLastRot; public float sunFlareTime; public float dofPrevDistance = -1; public float dofLastAutofocusDistance; public Vector4 dofLastBokehData; public float dofFadeIntensity = 1f; } readonly static Dictionary perCamData = new Dictionary(); static PerCamData camData; static bool requiresSunFlaresOcclusionRTInit; static bool requiresLuminanceComputation; static bool usesBloomAndFlares, usesDepthOfField, usesVignetting, usesSeparateOutline; static bool usesSharpenExclusionMask; static int sharpenExclusionLayerMask; static Matrix4x4 matrix4x4identity = Matrix4x4.identity; static bool supportsR8Format, supportsARGBHalfFormat; static RenderTexture rtCapture; static bool usesDirectWriteToCamera; public bool Setup (Shader shader, ScriptableRenderer renderer, RenderingData renderingData, RenderPassEvent renderingPassEvent, bool ignorePostProcessingOption) { // Configures where the render pass should be injected. beautify = VolumeManager.instance.stack.GetComponent(); bool isActive = true; if (beautify != null) { isActive = beautify.IsActive(); usesDirectWriteToCamera = beautify.directWrite.value; canUseDepthTexture = !beautify.ignoreDepthTexture.value; #if UNITY_EDITOR if (renderingData.cameraData.camera.cameraType == CameraType.SceneView) { usesDirectWriteToCamera = false; } #endif #if UNITY_2023_3_OR_NEWER if (usingRenderGraph && canUseDepthTexture && beautify.outline.value && beautify.outlineCustomize.value && (beautify.outlineStageParameter.value != OutlineStage.BeforeBloom || beautify.bloomIntensity.value <= 0)) { usesDirectWriteToCamera = false; // seprate outline can't use direct write to camera in render graph } #endif #if !UNITY_2022_3_OR_NEWER if (usesDirectWriteToCamera) { renderingPassEvent = RenderPassEvent.AfterRenderingPostProcessing; renderingPassEvent++; if (ignorePostProcessingOption) { renderingPassEvent = RenderPassEvent.AfterRendering + 3; // queue after FinalBlit is present } } #endif } renderPassEvent = renderingPassEvent; cameraData = renderingData.cameraData; BeautifyRenderPass.renderer = renderer; if (setup && cameraData.camera != null && bMat != null) return isActive; setup = true; CheckSceneSettings(); BeautifySettings.UnloadBeautify(); // reset any cached profile supportsFPTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf); supportsR8Format = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.R8); if (bMat == null) { if (shader == null) { Debug.LogWarning("Could not load Beautify shader. Please make sure BeautifyCore.shader is present."); } else { bMat = CoreUtils.CreateEngineMaterial(shader); bMat.SetTexture(ShaderParams.blueNoiseTex, Resources.Load("Textures/blueNoise")); } } // Initialize bloom buffers descriptors if (rt == null || rt.Length != PYRAMID_COUNT_BLOOM + 1) { rt = new BloomMipData[PYRAMID_COUNT_BLOOM + 1]; } for (int k = 0; k < rt.Length; k++) { rt[k].rtDown = rt[k].rtDownOriginal = Shader.PropertyToID("_BeautifyBloomDownMip" + k); rt[k].rtUp = rt[k].rtUpOriginal = Shader.PropertyToID("_BeautifyBloomUpMip" + k); } // Initialize anamorphic flare buffers descriptors if (rtAF == null || rtAF.Length != PYRAMID_COUNT_BLOOM + 1) { rtAF = new BloomMipData[PYRAMID_COUNT_BLOOM + 1]; } for (int k = 0; k < rtAF.Length; k++) { rtAF[k].rtDown = rtAF[k].rtDownOriginal = Shader.PropertyToID("_BeautifyAFDownMip" + k); rtAF[k].rtUp = rtAF[k].rtUpOriginal = Shader.PropertyToID("_BeautifyAFUpMip" + k); } // Initialize eye adaptation buffers descriptors if (rtEA == null || rtEA.Length != PYRAMID_COUNT_EA) { rtEA = new int[PYRAMID_COUNT_EA]; } for (int k = 0; k < rtEA.Length; k++) { rtEA[k] = Shader.PropertyToID("_BeautifyEAMip" + k); } return isActive; } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Configure (CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { if (bMat == null) return; if (beautify == null) { beautify = VolumeManager.instance.stack.GetComponent(); } if (beautify == null || !beautify.IsActive()) return; sourceDesc = cameraTextureDescriptor; sourceDesc.msaaSamples = 1; sourceDesc.depthBufferBits = 0; if (beautify.downsampling.value) { UniversalRenderPipelineAsset pipe = (UniversalRenderPipelineAsset)GraphicsSettings.currentRenderPipeline; float downsamplingMultiplier = 1f / beautify.downsamplingMultiplier.value; if (downsamplingMultiplier < 1f) { DownsamplingMode mode = beautify.downsamplingMode.value; if (mode == DownsamplingMode.BeautifyEffectsOnly) { sourceDesc.width = (int)(sourceDesc.width * downsamplingMultiplier); sourceDesc.height = (int)(sourceDesc.height * downsamplingMultiplier); if (pipe.renderScale != 1f) { pipe.renderScale = 1f; } } else { if (pipe.renderScale != downsamplingMultiplier) { pipe.renderScale = downsamplingMultiplier; beautify.downsamplingMultiplier.value = 1f / pipe.renderScale; } } } else { if (pipe.renderScale != 1f) { pipe.renderScale = 1f; } } } sourceDescHP = sourceDesc; if (supportsFPTextures) { sourceDescHP.colorFormat = RenderTextureFormat.ARGBHalf; } if (!beautify.ignoreDepthTexture.value) { ConfigureInput(ScriptableRenderPassInput.Depth); } } #if UNITY_2022_1_OR_NEWER public void SetupRenderTargets(ScriptableRenderer renderer) { BeautifyRenderPass.renderer = renderer; #if UNITY_2022_2_OR_NEWER #pragma warning disable CS0618 source = renderer.cameraColorTargetHandle; #pragma warning restore CS0618 #else source = renderer.cameraColorTarget; #endif } #else public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData renderingData) { source = renderer.cameraColorTarget; } #endif #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) { if (bMat == null) { Debug.LogError("Beautify material not initialized."); return; } Camera cam = cameraData.camera; if (beautify == null || cam == null || !beautify.IsActive()) return; #if !UNITY_2022_1_OR_NEWER if (!usesDirectWriteToCamera) { source = renderer.cameraColorTarget; } #endif var cmd = CommandBufferPool.Get("Beautify"); passData.camera = cam; passData.cmd = cmd; ExecutePass(passData); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } #if UNITY_2023_3_OR_NEWER public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { using (var builder = renderGraph.AddUnsafePass("Beautify Pass RG", out var passData)) { passData.camera = frameData.Get().camera; UniversalResourceData resourceData = frameData.Get(); passData.colorTexture = resourceData.activeColorTexture; builder.UseTexture(resourceData.activeColorTexture, AccessFlags.ReadWrite); if (!beautify.ignoreDepthTexture.value) { builder.UseTexture(resourceData.activeDepthTexture, AccessFlags.Read); ConfigureInput(ScriptableRenderPassInput.Depth); } if (usesDirectWriteToCamera) { if (resourceData.isActiveTargetBackBuffer) { usesDirectWriteToCamera = false; } else { var cameraData = frameData.Get(); var descriptor = cameraData.cameraTargetDescriptor; descriptor.msaaSamples = 1; descriptor.depthBufferBits = 0; directWriteTextureHandle = UniversalRenderer.CreateRenderGraphTexture(renderGraph, descriptor, "BlitMaterialRefTex_Beautify", false); resourceData.cameraColor = directWriteTextureHandle; builder.UseTexture(directWriteTextureHandle, AccessFlags.WriteAll); } } builder.SetRenderFunc((PassData passData, UnsafeGraphContext context) => { CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); passData.cmd = cmd; source = passData.colorTexture; if (bMat == null) return; if (beautify == null) { beautify = VolumeManager.instance.stack.GetComponent(); } if (beautify == null || !beautify.IsActive()) return; if (source.rt != null) { sourceDesc = source.rt.descriptor; } sourceDesc.msaaSamples = 1; sourceDesc.depthBufferBits = 0; if (beautify.downsampling.value) { UniversalRenderPipelineAsset pipe = (UniversalRenderPipelineAsset)GraphicsSettings.currentRenderPipeline; float downsamplingMultiplier = 1f / beautify.downsamplingMultiplier.value; if (downsamplingMultiplier < 1f) { DownsamplingMode mode = beautify.downsamplingMode.value; if (mode == DownsamplingMode.BeautifyEffectsOnly) { sourceDesc.width = (int)(sourceDesc.width * downsamplingMultiplier); sourceDesc.height = (int)(sourceDesc.height * downsamplingMultiplier); if (pipe.renderScale != 1f) { pipe.renderScale = 1f; } } else { if (pipe.renderScale != downsamplingMultiplier) { pipe.renderScale = downsamplingMultiplier; beautify.downsamplingMultiplier.value = 1f / pipe.renderScale; } } } else { if (pipe.renderScale != 1f) { pipe.renderScale = 1f; } } } sourceDescHP = sourceDesc; if (supportsFPTextures) { sourceDescHP.colorFormat = RenderTextureFormat.ARGBHalf; } ExecutePass(passData); }); } } #endif static void ExecutePass (PassData passData) { Camera cam = passData.camera; CommandBuffer cmd = passData.cmd; #if UNITY_EDITOR if (requestScreenCapture && cam != null && cam.cameraType == captureCameraType) { requestScreenCapture = false; if (rtCapture != null) { rtCapture.Release(); } rtCapture = new RenderTexture(sourceDesc); FullScreenBlit(cmd, source, rtCapture, bMat, (int)Pass.CopyExact); cmd.SetGlobalTexture(ShaderParams.lutPreview, rtCapture); } else { if (cam.cameraType == CameraType.SceneView && beautify.hideInSceneView.value && !requestScreenCapture) return; } #else if (cam.cameraType == CameraType.SceneView && beautify.hideInSceneView.value) return; #endif RestoreRTBufferIds(); bMat.SetFloat(ShaderParams.flipY, beautify.flipY.value ? -1 : 1); // workaround for 2D renderer bug with camera stacking if (requiresLuminanceComputation || usesBloomAndFlares || usesDepthOfField) { if (!perCamData.TryGetValue(cam, out camData)) { camData = new PerCamData(); perCamData[cam] = camData; } if (camData.rtSunFlaresOcclusion == null) { camData.rtSunFlaresOcclusion = RTHandles.Alloc(2, 2, colorFormat: UnityEngine.Experimental.Rendering.GraphicsFormat.R16G16B16A16_SFloat); requiresSunFlaresOcclusionRTInit = true; } else { requiresSunFlaresOcclusionRTInit = false; } } if (usesSeparateOutline && beautify.outlineStageParameter.value == OutlineStage.BeforeBloom) { DoSeparateOutline(cmd); } bool dofAffectsBloom = usesDepthOfField && usesBloomAndFlares && beautify.depthOfFieldAffectsBloom.value; if (dofAffectsBloom) { DoDoF(cmd); } if (usesBloomAndFlares) { DoBloomAndFlares(cmd, dofAffectsBloom); } if (usesSeparateOutline && beautify.outlineStageParameter.value == OutlineStage.AfterBloom) { DoSeparateOutline(cmd); } if (requiresLuminanceComputation) { DoEyeAdaptation(cmd); } if (usesDepthOfField && !dofAffectsBloom) { DoDoF(cmd); } if (usesVignetting) { DoVignette(); } bool usesChromaticAberrationAsPost = beautify.chromaticAberrationIntensity.value > 0 && (beautify.depthOfField.value || beautify.chromaticAberrationSeparatePass.value); bool usesFinalBlur = beautify.blurIntensity.value > 0; int blurComposePass = usesFinalBlur && beautify.blurKeepSourceOnTop.value ? (int)Pass.CopyWithMiniView : (int)Pass.CopyBilinear; if (usesDirectWriteToCamera) { // direct output to camera if (beautify.debugOutput.value == DebugOutput.DepthOfFieldCoC) { if (beautify.depthOfField.value) { // we ignore input contents FullScreenBlitToCamera(cmd, source, BuiltinRenderTextureType.CameraTarget, bMat, (int)Pass.DoFCoCDebug); } } else if (beautify.debugOutput.value == DebugOutput.BloomAndFlares) { if (beautify.bloomIntensity.value > 0 || beautify.anamorphicFlaresIntensity.value > 0 || beautify.sunFlaresIntensity.value > 0 || beautify.lensDirtIntensity.value > 0) { // we ignore input contents FullScreenBlitToCamera(cmd, source, BuiltinRenderTextureType.CameraTarget, bMat, (int)Pass.BloomDebug); } } else if (beautify.debugOutput.value == DebugOutput.BloomExclusionPass) { if (beautify.bloomIntensity.value > 0 && beautify.bloomExcludeLayers.value) { // we ignore input contents FullScreenBlitToCamera(cmd, source, BuiltinRenderTextureType.CameraTarget, bMat, (int)Pass.BloomExclusionLayerDebug); } } else if (beautify.debugOutput.value == DebugOutput.AnamorphicFlaresExclusionPass) { if (beautify.anamorphicFlaresIntensity.value > 0 && beautify.anamorphicFlaresExcludeLayers.value) { // we ignore input contents FullScreenBlitToCamera(cmd, source, BuiltinRenderTextureType.CameraTarget, bMat, (int)Pass.AnamorphicFlaresExclusionLayerDebug); } } else if (beautify.debugOutput.value == DebugOutput.DepthOfFieldTransparentPass) { if (beautify.depthOfField.value && (beautify.depthOfFieldTransparentSupport.value || beautify.depthOfFieldAlphaTestSupport.value)) { // we ignore input contents FullScreenBlitToCamera(cmd, source, BuiltinRenderTextureType.CameraTarget, bMat, (int)Pass.DoFDebugTransparent); } } else if (beautify.compareMode.value) { cmd.GetTemporaryRT(ShaderParams.compareTex, sourceDesc, FilterMode.Point); if (usesChromaticAberrationAsPost) { // chromatic aberration added as a post-pass due to depth of field cmd.GetTemporaryRT(ShaderParams.chromaticTempTex, sourceDesc, FilterMode.Point); FullScreenBlit(cmd, source, ShaderParams.chromaticTempTex, bMat, (int)Pass.Beautify); FullScreenBlit(cmd, ShaderParams.chromaticTempTex, ShaderParams.compareTex, bMat, (int)Pass.ChromaticAberration); cmd.ReleaseTemporaryRT(ShaderParams.chromaticTempTex); } else { FullScreenBlit(cmd, source, ShaderParams.compareTex, bMat, (int)Pass.Beautify); } if (usesFinalBlur) { // final blur int blurSource = ApplyFinalBlur(cmd, ShaderParams.compareTex); FullScreenBlit(cmd, blurSource, ShaderParams.compareTex, bMat, blurComposePass); } FullScreenBlitToCamera(cmd, source, BuiltinRenderTextureType.CameraTarget, bMat, (int)Pass.Compare); cmd.ReleaseTemporaryRT(ShaderParams.compareTex); } else { RenderTargetIdentifier preBlurDest = BuiltinRenderTextureType.CameraTarget; if (usesFinalBlur) { cmd.GetTemporaryRT(ShaderParams.inputTex, sourceDesc, FilterMode.Point); preBlurDest = ShaderParams.inputTex; } if (usesChromaticAberrationAsPost) { // chromatic aberration added as a post-pass due to depth of field cmd.GetTemporaryRT(ShaderParams.chromaticTempTex, sourceDesc, FilterMode.Point); FullScreenBlit(cmd, source, ShaderParams.chromaticTempTex, bMat, (int)Pass.Beautify); FullScreenBlitToCamera(cmd, ShaderParams.chromaticTempTex, preBlurDest, bMat, (int)Pass.ChromaticAberration); cmd.ReleaseTemporaryRT(ShaderParams.chromaticTempTex); } else { FullScreenBlitToCamera(cmd, source, preBlurDest, bMat, (int)Pass.Beautify); } if (usesFinalBlur) { // final blur int blurSource = ApplyFinalBlur(cmd, preBlurDest); FullScreenBlitToCamera(cmd, blurSource, BuiltinRenderTextureType.CameraTarget, bMat, blurComposePass); cmd.ReleaseTemporaryRT(ShaderParams.inputTex); } } } else { // non direct to camera bool useBilinearFiltering = beautify.downsampling.value && beautify.downsamplingMultiplier.value > 1f && beautify.downsamplingBilinear.value; int copyPass = useBilinearFiltering ? (int)Pass.CopyBilinear : (int)Pass.CopyExact; cmd.GetTemporaryRT(ShaderParams.inputTex, sourceDesc, (!beautify.downsampling.value || (beautify.downsamplingMultiplier.value > 1f && !beautify.downsamplingBilinear.value)) ? FilterMode.Point : FilterMode.Bilinear); if (beautify.debugOutput.value == DebugOutput.DepthOfFieldCoC) { if (beautify.depthOfField.value) { // we ignore input contents FullScreenBlit(cmd, ShaderParams.inputTex, source, bMat, (int)Pass.DoFCoCDebug); } } else if (beautify.debugOutput.value == DebugOutput.BloomAndFlares) { if (beautify.bloomIntensity.value > 0 || beautify.anamorphicFlaresIntensity.value > 0 || beautify.sunFlaresIntensity.value > 0 || beautify.lensDirtIntensity.value > 0) { // we ignore input contents FullScreenBlit(cmd, ShaderParams.inputTex, source, bMat, (int)Pass.BloomDebug); } } else if (beautify.debugOutput.value == DebugOutput.BloomExclusionPass) { if (beautify.bloomIntensity.value > 0 && beautify.bloomExcludeLayers.value) { // we ignore input contents FullScreenBlit(cmd, ShaderParams.inputTex, source, bMat, (int)Pass.BloomExclusionLayerDebug); } } else if (beautify.debugOutput.value == DebugOutput.AnamorphicFlaresExclusionPass) { if (beautify.anamorphicFlaresIntensity.value > 0 && beautify.anamorphicFlaresExcludeLayers.value) { // we ignore input contents FullScreenBlit(cmd, ShaderParams.inputTex, source, bMat, (int)Pass.AnamorphicFlaresExclusionLayerDebug); } } else if (beautify.debugOutput.value == DebugOutput.DepthOfFieldTransparentPass) { if (beautify.depthOfField.value && (beautify.depthOfFieldTransparentSupport.value || beautify.depthOfFieldAlphaTestSupport.value)) { // we ignore input contents FullScreenBlit(cmd, ShaderParams.inputTex, source, bMat, (int)Pass.DoFDebugTransparent); } } else if (beautify.compareMode.value) { cmd.GetTemporaryRT(ShaderParams.compareTex, sourceDesc, FilterMode.Point); if (usesChromaticAberrationAsPost) { // chromatic aberration added as a post-pass due to depth of field FullScreenBlit(cmd, source, ShaderParams.inputTex, bMat, (int)Pass.Beautify); FullScreenBlit(cmd, ShaderParams.inputTex, ShaderParams.compareTex, bMat, (int)Pass.ChromaticAberration); } else { FullScreenBlit(cmd, source, ShaderParams.compareTex, bMat, (int)Pass.Beautify); } if (usesFinalBlur) { // final blur int blurSource = ApplyFinalBlur(cmd, ShaderParams.compareTex); FullScreenBlit(cmd, blurSource, ShaderParams.compareTex, bMat, blurComposePass); } FullScreenBlit(cmd, source, ShaderParams.inputTex, bMat, copyPass); FullScreenBlit(cmd, ShaderParams.inputTex, source, bMat, (int)Pass.Compare); cmd.ReleaseTemporaryRT(ShaderParams.compareTex); } else { if (usesChromaticAberrationAsPost) { // chromatic aberration added as a post-pass due to depth of field FullScreenBlit(cmd, source, ShaderParams.inputTex, bMat, (int)Pass.Beautify); FullScreenBlit(cmd, ShaderParams.inputTex, source, bMat, (int)Pass.ChromaticAberration); } else { FullScreenBlit(cmd, source, ShaderParams.inputTex, bMat, copyPass); FullScreenBlit(cmd, ShaderParams.inputTex, source, bMat, (int)Pass.Beautify); } if (usesFinalBlur) { // final blur int blurSource = ApplyFinalBlur(cmd, source); FullScreenBlit(cmd, blurSource, source, bMat, blurComposePass); } cmd.ReleaseTemporaryRT(ShaderParams.miniViewTex); } cmd.ReleaseTemporaryRT(ShaderParams.inputTex); } } static Mesh _fullScreenMesh; static Mesh fullscreenMesh { get { if (_fullScreenMesh != null) { return _fullScreenMesh; } Mesh val = new Mesh(); _fullScreenMesh = val; _fullScreenMesh.SetVertices(new List { new Vector3 (-1f, -1f, 0f), new Vector3 (-1f, 1f, 0f), new Vector3 (1f, -1f, 0f), new Vector3 (1f, 1f, 0f) }); _fullScreenMesh.SetUVs(0, new List { new Vector2 (0f, 0f), new Vector2 (0f, 1f), new Vector2 (1f, 0f), new Vector2 (1f, 1f) }); _fullScreenMesh.SetIndices(new int[6] { 0, 1, 2, 2, 1, 3 }, (MeshTopology)0, 0, false); _fullScreenMesh.UploadMeshData(true); return _fullScreenMesh; } } static void FullScreenBlit (CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, int passIndex) { destination = new RenderTargetIdentifier(destination, 0, CubemapFace.Unknown, -1); cmd.SetRenderTarget(destination); cmd.SetGlobalTexture(ShaderParams.mainTex, source); cmd.DrawMesh(fullscreenMesh, matrix4x4identity, material, 0, passIndex); } static void FullScreenBlitToCamera (CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, int passIndex) { #if UNITY_2022_3_OR_NEWER // if destination is camera, make use of swap buffers if (destination == BuiltinRenderTextureType.CameraTarget) { #if UNITY_2023_3_OR_NEWER if (usingRenderGraph) { RenderTargetIdentifier dest = directWriteTextureHandle; dest = new RenderTargetIdentifier(dest, 0, CubemapFace.Unknown, -1); cmd.SetRenderTarget(dest); cmd.SetGlobalTexture(ShaderParams.mainTex, source); cmd.DrawMesh(fullscreenMesh, matrix4x4identity, material, 0, passIndex); } else #endif #if !UNITY_6000_3_OR_NEWER { #pragma warning disable 0618 RenderTargetIdentifier dest = renderer.GetCameraColorFrontBuffer(cmd); #pragma warning restore 0618 dest = new RenderTargetIdentifier(dest, 0, CubemapFace.Unknown, -1); cmd.SetRenderTarget(dest); cmd.SetGlobalTexture(ShaderParams.mainTex, source); cmd.DrawMesh(fullscreenMesh, matrix4x4identity, material, 0, passIndex); renderer.SwapColorBuffer(cmd); } #endif return; } #endif FullScreenBlit(cmd, source, destination, material, passIndex); } public void Cleanup () { UniversalRenderPipelineAsset pipe = (UniversalRenderPipelineAsset)GraphicsSettings.currentRenderPipeline; if (beautify != null && pipe != null && beautify.downsampling.value) { pipe.renderScale = 1f; } CoreUtils.Destroy(bMat); foreach (PerCamData data in perCamData.Values) { if (data.rtSunFlaresOcclusion != null) { data.rtSunFlaresOcclusion.Release(); } } #if UNITY_EDITOR if (rtCapture != null) { rtCapture.Release(); } #endif } static void RestoreRTBufferIds () { // Restore temorary rt ids for (int k = 0; k < rt.Length; k++) { rt[k].rtDown = rt[k].rtDownOriginal; rt[k].rtUp = rt[k].rtUpOriginal; } for (int k = 0; k < rtAF.Length; k++) { rtAF[k].rtDown = rtAF[k].rtDownOriginal; rtAF[k].rtUp = rtAF[k].rtUpOriginal; } ShaderParams.tempBlurOneDirRT = ShaderParams.tempBlurOneDirRTOriginal; ShaderParams.tempBloomCustomComposeRT = ShaderParams.tempBloomCustomComposeRTOriginal; } static int ApplyFinalBlur (CommandBuffer cmd, RenderTargetIdentifier source) { if (beautify.blurKeepSourceOnTop.value) { Vector4 rect = beautify.blurSourceRect.value; RenderTextureDescriptor miniViewDesc = sourceDesc; miniViewDesc.width = (int)(miniViewDesc.width * rect.z); if (miniViewDesc.width < 1) miniViewDesc.width = 1; miniViewDesc.height = (int)(miniViewDesc.height * rect.w); if (miniViewDesc.height < 1) miniViewDesc.height = 1; cmd.GetTemporaryRT(ShaderParams.miniViewTex, miniViewDesc, FilterMode.Bilinear); FullScreenBlit(cmd, source, ShaderParams.miniViewTex, bMat, (int)Pass.CopyBilinear); bMat.SetVector(ShaderParams.miniViewRect, rect); float fparam = (1.00001f - beautify.blurSourceEdgeBlendWidth.value) * 0.5f; float wparam = beautify.blurSourceEdgeBlendStrength.value; bMat.SetVector(ShaderParams.miniViewBlend, new Vector4(fparam, wparam, fparam, wparam)); } int size; RenderTextureDescriptor rtBlurDesc = sourceDescHP; float blurIntensity = beautify.blurIntensity.value; if (blurIntensity < 1f) { size = (int)Mathf.Lerp(rtBlurDesc.width, 512, blurIntensity); } else { size = (int)(512 / blurIntensity); } float aspectRatio = (float)sourceDesc.height / sourceDesc.width; rtBlurDesc.width = size; rtBlurDesc.height = Mathf.Max(1, (int)(size * aspectRatio)); cmd.GetTemporaryRT(ShaderParams.blurRT, rtBlurDesc, FilterMode.Bilinear); float ratio = (float)sourceDesc.width / size; float blurScale = blurIntensity > 1f ? 1f : blurIntensity; cmd.GetTemporaryRT(ShaderParams.tempBlurDownscaling, rtBlurDesc, FilterMode.Bilinear); cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale * ratio); FullScreenBlit(cmd, source, ShaderParams.tempBlurDownscaling, bMat, (int)Pass.BlurHoriz); cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale); FullScreenBlit(cmd, ShaderParams.tempBlurDownscaling, ShaderParams.blurRT, bMat, (int)Pass.BlurVert); cmd.ReleaseTemporaryRT(ShaderParams.tempBlurDownscaling); BlurThis(cmd, rtBlurDesc, ShaderParams.blurRT, rtBlurDesc.width, rtBlurDesc.height, bMat, blurScale); if (!beautify.turboMode.value) { BlurThis(cmd, rtBlurDesc, ShaderParams.blurRT, rtBlurDesc.width, rtBlurDesc.height, bMat, blurScale); BlurThis(cmd, rtBlurDesc, ShaderParams.blurRT, rtBlurDesc.width, rtBlurDesc.height, bMat, blurScale); } Beautify.CreativeBlurStyle style = beautify.blurStyle.value; bool hasMask = beautify.blurMask.value != null; bool useMask = hasMask || style != Beautify.CreativeBlurStyle.ScreenBlur || beautify.blurDesaturation.value > 0; if (useMask) { float styleVal = (float)style; float width = style == Beautify.CreativeBlurStyle.TiltShift ? beautify.blurTiltShiftWidth.value : beautify.blurRadialBlurRadius.value; float falloff = style == Beautify.CreativeBlurStyle.TiltShift ? beautify.blurTiltShiftFalloff.value : beautify.blurRadialBlurFalloff.value; Vector4 blurData = new Vector4(beautify.blurCenter.value.x, beautify.blurCenter.value.y, width, falloff); cmd.SetGlobalVector(ShaderParams.blurData, blurData); Vector4 blurData2 = new Vector4(styleVal, beautify.blurShowMask.value ? 1f : 0f, beautify.blurDesaturation.value, hasMask ? 1f : 0f); cmd.SetGlobalVector(ShaderParams.blurData2, blurData2); cmd.GetTemporaryRT(ShaderParams.blurMaskedRT, sourceDesc); FullScreenBlit(cmd, source, ShaderParams.blurMaskedRT, bMat, (int)Pass.BlurMask); return ShaderParams.blurMaskedRT; } else { return ShaderParams.blurRT; } } static void DoBloomAndFlares (CommandBuffer cmd, bool dofAffectsBloom) { Camera cam = cameraData.camera; bool sunFlareEnabled = false; if (beautify.sunFlaresIntensity.value > 0) { CheckSun(); sunFlareEnabled = sceneSettings != null && sceneSettings.sun != null; } RenderTargetIdentifier source = dofAffectsBloom ? ShaderParams.dofRT : BeautifyRenderPass.source; if (beautify.lensDirtIntensity.value > 0 || beautify.bloomIntensity.value > 0 || beautify.anamorphicFlaresIntensity.value > 0 || sunFlareEnabled) { int mipCount = beautify.turboMode.value ? PYRAMID_COUNT_BLOOM_TURBO : PYRAMID_COUNT_BLOOM; float aspectRatio = (float)sourceDesc.height / sourceDesc.width; int rtBloom = -1; int downsamping = beautify.turboMode.value ? 4 : 2; int lensDirtSpread = beautify.turboMode.value ? 2 : beautify.lensDirtSpread.value; if (beautify.bloomIntensity.value > 0 || (beautify.lensDirtIntensity.value > 0 && beautify.anamorphicFlaresIntensity.value <= 0)) { int size = (int)(Mathf.Lerp(512, sourceDesc.width, beautify.bloomResolution.value / 10f) / 4f) * 4; RenderTextureDescriptor bloomDesc = sourceDescHP; for (int k = 0; k <= mipCount; k++) { rt[k].width = size; rt[k].height = Mathf.Max(1, (int)(size * aspectRatio)); bloomDesc.width = rt[k].width; bloomDesc.height = rt[k].height; cmd.ReleaseTemporaryRT(rt[k].rtDown); cmd.GetTemporaryRT(rt[k].rtDown, bloomDesc, FilterMode.Bilinear); cmd.ReleaseTemporaryRT(rt[k].rtUp); cmd.GetTemporaryRT(rt[k].rtUp, bloomDesc, FilterMode.Bilinear); size /= downsamping; } rtBloom = rt[0].rtDown; if (beautify.bloomAntiflicker.value) { FullScreenBlit(cmd, source, rtBloom, bMat, (int)Pass.BloomLuminanceAntiflicker); } else { FullScreenBlit(cmd, source, rtBloom, bMat, (int)Pass.BloomLuminance); } // Blitting down... if (beautify.bloomQuickerBlur.value) { for (int k = 0; k < mipCount; k++) { BlurThisDownsampling(cmd, bloomDesc, rt[k].rtDown, rt[k + 1].rtDown, rt[k + 1].width, rt[k + 1].height, bMat); } } else { for (int k = 0; k < mipCount; k++) { FullScreenBlit(cmd, rt[k].rtDown, rt[k + 1].rtDown, bMat, (int)Pass.BloomResample); BlurThis(cmd, bloomDesc, rt[k + 1].rtDown, rt[k + 1].width, rt[k + 1].height, bMat); } } if (beautify.bloomIntensity.value > 0 || beautify.lensDirtIntensity.value > 0) { // Blitting up... rtBloom = rt[mipCount].rtDown; for (int k = mipCount; k > 0; k--) { cmd.SetGlobalTexture(ShaderParams.bloomTex, rt[k - 1].rtDown); FullScreenBlit(cmd, rtBloom, rt[k - 1].rtUp, bMat, (int)Pass.BloomResampleAndCombine); rtBloom = rt[k - 1].rtUp; } if (beautify.bloomCustomize.value) { cmd.SetGlobalTexture(ShaderParams.bloomTex4, mipCount < 4 ? rt[3].rtUp : rt[4].rtUp); cmd.SetGlobalTexture(ShaderParams.bloomTex3, rt[3].rtUp); cmd.SetGlobalTexture(ShaderParams.bloomTex2, rt[2].rtUp); cmd.SetGlobalTexture(ShaderParams.bloomTex1, rt[1].rtUp); cmd.SetGlobalTexture(ShaderParams.bloomTex, rt[0].rtUp); bloomDesc.width = rt[0].width; bloomDesc.height = rt[0].height; cmd.ReleaseTemporaryRT(ShaderParams.tempBloomCustomComposeRT); cmd.GetTemporaryRT(ShaderParams.tempBloomCustomComposeRT, bloomDesc, FilterMode.Bilinear); rtBloom = ShaderParams.tempBloomCustomComposeRT; FullScreenBlit(cmd, rt[mipCount].rtUp, rtBloom, bMat, (int)Pass.BloomCompose); } } } // anamorphic flares if (beautify.anamorphicFlaresIntensity.value > 0) { int sizeAF = (int)(Mathf.Lerp(512, sourceDescHP.width, beautify.anamorphicFlaresResolution.value / 10f) / 4f) * 4; RenderTextureDescriptor afDesc = sourceDescHP; float spread = (1920 / 1080f) * beautify.anamorphicFlaresSpread.value * sizeAF / 512f; for (int origSize = sizeAF, k = 0; k <= mipCount; k++) { int w = Mathf.Max(1, (int)(sizeAF / spread)); if (beautify.anamorphicFlaresVertical.value) { rtAF[k].width = origSize; rtAF[k].height = w; } else { rtAF[k].width = w; rtAF[k].height = origSize; } afDesc.width = rtAF[k].width; afDesc.height = rtAF[k].height; cmd.ReleaseTemporaryRT(rtAF[k].rtDown); cmd.GetTemporaryRT(rtAF[k].rtDown, afDesc, FilterMode.Bilinear); cmd.ReleaseTemporaryRT(rtAF[k].rtUp); cmd.GetTemporaryRT(rtAF[k].rtUp, afDesc, FilterMode.Bilinear); sizeAF /= downsamping; } if (beautify.anamorphicFlaresAntiflicker.value) { FullScreenBlit(cmd, source, rtAF[0].rtDown, bMat, (int)Pass.AnamorphicFlaresLuminanceAntiflicker); } else { FullScreenBlit(cmd, source, rtAF[0].rtDown, bMat, (int)Pass.AnamorphicFlaresLuminance); } BlurThisOneDirection(cmd, afDesc, ref rtAF[0].rtDown, rtAF[0].width, rtAF[0].height, beautify.anamorphicFlaresVertical.value); if (beautify.anamorphicFlaresQuickerBlur.value) { for (int k = 0; k < mipCount; k++) { BlurThisOneDirectionDownscaling(cmd, afDesc, rtAF[k].rtDown, rtAF[k + 1].rtDown, rtAF[k + 1].width, rtAF[k + 1].height, beautify.anamorphicFlaresVertical.value); } } else { for (int k = 0; k < mipCount; k++) { FullScreenBlit(cmd, rtAF[k].rtDown, rtAF[k + 1].rtDown, bMat, (int)Pass.BloomResample); BlurThisOneDirection(cmd, afDesc, ref rtAF[k + 1].rtDown, rtAF[k + 1].width, rtAF[k + 1].height, beautify.anamorphicFlaresVertical.value); } } int last = rtAF[mipCount].rtDown; for (int k = mipCount; k > 0; k--) { cmd.SetGlobalTexture(ShaderParams.bloomTex, rtAF[k].rtDown); if (k == 1) { FullScreenBlit(cmd, last, rtAF[k - 1].rtUp, bMat, (int)Pass.AnamorphicFlaresResample); // applies intensity in last stage } else { FullScreenBlit(cmd, last, rtAF[k - 1].rtUp, bMat, (int)Pass.BloomResampleAndCombine); } last = rtAF[k - 1].rtUp; } if (beautify.bloomIntensity.value > 0) { if (beautify.lensDirtIntensity.value > 0) { BlendOneOne(cmd, rtAF[lensDirtSpread].rtUp, ref rt[lensDirtSpread].rtUp, ref rt[lensDirtSpread].rtDown); } BlendOneOne(cmd, last, ref rtBloom, ref rt[0].rtDown); } else { rtBloom = last; } } if (sunFlareEnabled) { // check if Sun is visible Vector3 sunDirection = sceneSettings.sun.transform.forward; Vector3 sunWorldPosition = cam.transform.position - sunDirection * 1000f; float flareIntensity = 0; Vector3 sunScrPos = cam.WorldToViewportPoint(sunWorldPosition); bool sunVisible = sunScrPos.z > 0 && sunScrPos.x >= -0.1f && sunScrPos.x < 1.1f && sunScrPos.y >= -0.1f && sunScrPos.y < 1.1f; if (sunVisible) { if (beautify.sunFlaresUseLayerMask.value) { Ray ray = new Ray(cam.transform.position, -sunDirection); if (Physics.Raycast(ray, cam.farClipPlane, beautify.sunFlaresLayerMask.value)) { sunVisible = false; } } if (sunVisible) { Vector2 dd = sunScrPos - new Vector3(0.5f, 0.5f, 0.5f); flareIntensity = beautify.sunFlaresIntensity.value * Mathf.Clamp01((0.7f - Mathf.Max(Mathf.Abs(dd.x), Mathf.Abs(dd.y))) / 0.7f); } } if (beautify.bloomIntensity.value <= 0 && beautify.anamorphicFlaresIntensity.value <= 0) { // ensure _Bloom.x is 1 into the shader for sun flares to be visible if no bloom nor anamorphic flares are enabled bMat.SetVector(ShaderParams.bloom, Vector4.one); } else { flareIntensity /= (beautify.bloomIntensity.value + 0.0001f); } camData.sunFlareCurrentIntensity = Mathf.Lerp(camData.sunFlareCurrentIntensity, flareIntensity, Application.isPlaying ? beautify.sunFlaresAttenSpeed.value * Time.deltaTime : 1f); if (camData.sunFlareCurrentIntensity > 0) { if (flareIntensity > 0) { camData.sunLastScrPos = sunScrPos; if (canUseDepthTexture) { if (beautify.sunFlaresDepthOcclusionMode.value == SunFlaresDepthOcclusionMode.Smooth) { if (requiresSunFlaresOcclusionRTInit || !Application.isPlaying) { bMat.EnableKeyword(ShaderParams.SKW_SUN_FLARES_OCCLUSION_INIT); } else { bMat.DisableKeyword(ShaderParams.SKW_SUN_FLARES_OCCLUSION_INIT); } FullScreenBlit(cmd, source, camData.rtSunFlaresOcclusion, bMat, (int)Pass.SunFlaresOcclusionTest); } } } bMat.SetTexture(ShaderParams.sfOcclusionTex, camData.rtSunFlaresOcclusion); Color sunTintColor = beautify.sunFlaresTint.value; sunTintColor.r *= camData.sunFlareCurrentIntensity; sunTintColor.g *= camData.sunFlareCurrentIntensity; sunTintColor.b *= camData.sunFlareCurrentIntensity; sunTintColor.a = beautify.sunFlaresAttenSpeed.value; bMat.SetColor(ShaderParams.sfSunTintColor, sunTintColor); camData.sunLastScrPos.z = 0.5f + camData.sunFlareTime * beautify.sunFlaresSolarWindSpeed.value; Vector2 sfDist = new Vector2(0.5f - camData.sunLastScrPos.y, camData.sunLastScrPos.x - 0.5f); if (!beautify.sunFlaresRotationDeadZone.value || sfDist.sqrMagnitude > 0.00025f) { camData.sunLastRot = Mathf.Atan2(sfDist.x, sfDist.y); } camData.sunLastScrPos.w = camData.sunLastRot; camData.sunFlareTime += Time.unscaledDeltaTime; bMat.SetVector(ShaderParams.sfSunPos, camData.sunLastScrPos); bMat.SetVector(ShaderParams.sfSunDir, sunDirection); RenderTextureDescriptor sfDesc = sourceDesc; sfDesc.width /= beautify.sunFlaresDownsampling.value; sfDesc.height /= beautify.sunFlaresDownsampling.value; bMat.SetFloat(ShaderParams.sfAspectRatio, (float)sourceDesc.height / sourceDesc.width); cmd.GetTemporaryRT(ShaderParams.sfRT, sfDesc, FilterMode.Bilinear); if (rtBloom >= 0) { FullScreenBlit(cmd, rtBloom, ShaderParams.sfRT, bMat, (int)Pass.SunFlaresAdditive); } else { FullScreenBlit(cmd, source, ShaderParams.sfRT, bMat, (int)Pass.SunFlares); } if (beautify.lensDirtIntensity.value > 0 && beautify.bloomIntensity.value > 0) { BlendOneOne(cmd, ShaderParams.sfRT, ref rt[lensDirtSpread].rtUp, ref rt[lensDirtSpread].rtDown); } rtBloom = ShaderParams.sfRT; } } if (rtBloom >= 0) { cmd.SetGlobalTexture(ShaderParams.bloomTex, rtBloom); } else { bMat.DisableKeyword(ShaderParams.SKW_BLOOM); } if (beautify.lensDirtIntensity.value > 0) { int rtID = (beautify.anamorphicFlaresIntensity.value > 0 && beautify.bloomIntensity.value <= 0) ? rtAF[lensDirtSpread].rtUp : rt[lensDirtSpread].rtUp; cmd.SetGlobalTexture(ShaderParams.screenLum, rtID); } } } static void BlendOneOne (CommandBuffer cmd, int source, ref int destination, ref int tempBuffer) { cmd.SetGlobalTexture(ShaderParams.afCombineTex, destination); // _BloomTex used as temporary rt for combining FullScreenBlit(cmd, source, tempBuffer, bMat, (int)Pass.AnamorphicFlaresResampleAndCombine); // swap buffers int tmp = destination; destination = tempBuffer; tempBuffer = tmp; } static void BlurThis (CommandBuffer cmd, RenderTextureDescriptor desc, int rt, int width, int height, Material blurMat, float blurScale = 1f) { desc.width = width; desc.height = height; cmd.GetTemporaryRT(ShaderParams.tempBlurRT, desc, FilterMode.Bilinear); cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale); FullScreenBlit(cmd, rt, ShaderParams.tempBlurRT, blurMat, (int)Pass.BlurHoriz); FullScreenBlit(cmd, ShaderParams.tempBlurRT, rt, blurMat, (int)Pass.BlurVert); cmd.ReleaseTemporaryRT(ShaderParams.tempBlurRT); } static void BlurThisDownsampling (CommandBuffer cmd, RenderTextureDescriptor desc, int rtSource, int rt, int width, int height, Material blurMat, float blurScale = 1f) { desc.width = width; desc.height = height; cmd.GetTemporaryRT(ShaderParams.tempBlurRT, desc, FilterMode.Bilinear); cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale * 4f); FullScreenBlit(cmd, rtSource, ShaderParams.tempBlurRT, blurMat, (int)Pass.BlurHoriz); cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale); FullScreenBlit(cmd, ShaderParams.tempBlurRT, rt, blurMat, (int)Pass.BlurVert); cmd.ReleaseTemporaryRT(ShaderParams.tempBlurRT); } static void BlurThisOneDirection (CommandBuffer cmd, RenderTextureDescriptor desc, ref int rt, int width, int height, bool vertical, float blurScale = 1f) { desc.width = width; desc.height = height; cmd.ReleaseTemporaryRT(ShaderParams.tempBlurOneDirRT); cmd.GetTemporaryRT(ShaderParams.tempBlurOneDirRT, desc, FilterMode.Bilinear); cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale); FullScreenBlit(cmd, rt, ShaderParams.tempBlurOneDirRT, bMat, vertical ? (int)Pass.BlurVert : (int)Pass.BlurHoriz); int aux = rt; rt = ShaderParams.tempBlurOneDirRT; ShaderParams.tempBlurOneDirRT = aux; } static void BlurThisOneDirectionDownscaling (CommandBuffer cmd, RenderTextureDescriptor desc, int rtSource, int rt, int width, int height, bool vertical, float blurScale = 1f) { cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale * 2f); FullScreenBlit(cmd, rtSource, rt, bMat, vertical ? (int)Pass.BlurVert : (int)Pass.BlurHoriz); } static void DoDoF (CommandBuffer cmd) { Camera cam = cameraData.camera; if (cam.cameraType != CameraType.Game) { bMat.DisableKeyword(ShaderParams.SKW_DEPTH_OF_FIELD); bMat.DisableKeyword(ShaderParams.SKW_DEPTH_OF_FIELD_TRANSPARENT); return; } UpdateDepthOfFieldData(cmd); // Skip expensive DoF rendering if completely faded out (performance optimization) // The UpdateDepthOfFieldData call above still runs to track fade state for re-enabling if (camData.dofFadeIntensity <= 0.001f) { bMat.DisableKeyword(ShaderParams.SKW_DEPTH_OF_FIELD); bMat.DisableKeyword(ShaderParams.SKW_DEPTH_OF_FIELD_TRANSPARENT); return; } BeautifySettings.dofTransparentLayerMask = beautify.depthOfFieldTransparentLayerMask.value; BeautifySettings.dofTransparentDoubleSided = beautify.depthOfFieldTransparentDoubleSided.value; int width = cam.pixelWidth / beautify.depthOfFieldDownsampling.value; int height = cam.pixelHeight / beautify.depthOfFieldDownsampling.value; RenderTextureDescriptor dofDesc = sourceDescHP; dofDesc.width = width; dofDesc.height = height; dofDesc.colorFormat = RenderTextureFormat.ARGBHalf; cmd.GetTemporaryRT(ShaderParams.dofRT, dofDesc, FilterMode.Bilinear); FullScreenBlit(cmd, source, ShaderParams.dofRT, bMat, (int)Pass.DoFCoC); if (beautify.depthOfFieldForegroundBlur.value && beautify.depthOfFieldForegroundBlurHQ.value) { BlurThisAlpha(cmd, dofDesc, ShaderParams.dofRT, beautify.depthOfFieldForegroundBlurHQSpread.value); } if (beautify.depthOfFieldBokehComposition.value == Beautify.DoFBokehComposition.Integrated || !beautify.depthOfFieldBokeh.value) { Pass pass = beautify.depthOfFieldBokeh.value ? Pass.DoFBlur : Pass.DoFBlurWithoutBokeh; BlurThisDoF(cmd, dofDesc, ShaderParams.dofRT, (int)pass); } else { BlurThisDoF(cmd, dofDesc, ShaderParams.dofRT, (int)Pass.DoFBlurWithoutBokeh); // separate & blend bokeh cmd.GetTemporaryRT(ShaderParams.dofBokehRT, dofDesc, FilterMode.Bilinear); FullScreenBlit(cmd, source, ShaderParams.dofBokehRT, bMat, (int)Pass.DoFBokeh); BlurThisDoF(cmd, dofDesc, ShaderParams.dofBokehRT, (int)Pass.DoFBlurBokeh); FullScreenBlit(cmd, ShaderParams.dofBokehRT, ShaderParams.dofRT, bMat, (int)Pass.DoFAdditive); cmd.ReleaseTemporaryRT(ShaderParams.dofBokehRT); } cmd.SetGlobalTexture(ShaderParams.dofRT, ShaderParams.dofRT); } static void BlurThisDoF (CommandBuffer cmd, RenderTextureDescriptor dofDesc, int rt, int renderPass) { cmd.GetTemporaryRT(ShaderParams.dofTempBlurDoFTemp1RT, dofDesc, beautify.depthOfFieldFilterMode.value); cmd.GetTemporaryRT(ShaderParams.dofTempBlurDoFTemp2RT, dofDesc, beautify.depthOfFieldFilterMode.value); UpdateDepthOfFieldBlurData(cmd, new Vector2(0.44721f, -0.89443f)); FullScreenBlit(cmd, rt, ShaderParams.dofTempBlurDoFTemp1RT, bMat, renderPass); UpdateDepthOfFieldBlurData(cmd, new Vector2(-1f, 0f)); FullScreenBlit(cmd, ShaderParams.dofTempBlurDoFTemp1RT, ShaderParams.dofTempBlurDoFTemp2RT, bMat, renderPass); UpdateDepthOfFieldBlurData(cmd, new Vector2(0.44721f, 0.89443f)); FullScreenBlit(cmd, ShaderParams.dofTempBlurDoFTemp2RT, rt, bMat, renderPass); cmd.ReleaseTemporaryRT(ShaderParams.dofTempBlurDoFTemp2RT); cmd.ReleaseTemporaryRT(ShaderParams.dofTempBlurDoFTemp1RT); } static void BlurThisAlpha (CommandBuffer cmd, RenderTextureDescriptor dofDesc, int rt, float blurScale = 1f) { cmd.GetTemporaryRT(ShaderParams.dofTempBlurDoFAlphaRT, dofDesc, FilterMode.Bilinear); cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale); FullScreenBlit(cmd, rt, ShaderParams.dofTempBlurDoFAlphaRT, bMat, (int)Pass.DoFBlurHorizontally); FullScreenBlit(cmd, ShaderParams.dofTempBlurDoFAlphaRT, rt, bMat, (int)Pass.DoFBlurVertically); cmd.ReleaseTemporaryRT(ShaderParams.dofTempBlurDoFAlphaRT); } static void UpdateDepthOfFieldBlurData (CommandBuffer cmd, Vector2 blurDir) { float downsamplingRatio = 1f / (float)beautify.depthOfFieldDownsampling.value; blurDir *= downsamplingRatio; camData.dofLastBokehData.z = blurDir.x; camData.dofLastBokehData.w = blurDir.y; cmd.SetGlobalVector(ShaderParams.dofBokehData, camData.dofLastBokehData); } static void DoVignette () { float outerRing = 1f - beautify.vignettingOuterRing.value; float innerRing = 1f - beautify.vignettingInnerRing.value; bool vignettingEnabled = outerRing < 1 || innerRing < 1f || beautify.vignettingFade.value > 0 || beautify.vignettingBlink.value > 0; if (vignettingEnabled) { Color vignettingColorAdjusted = beautify.vignettingColor.value; float vb = 1f - beautify.vignettingBlink.value * 2f; if (vb < 0) vb = 0; vignettingColorAdjusted.r *= vb; vignettingColorAdjusted.g *= vb; vignettingColorAdjusted.b *= vb; bMat.SetColor(ShaderParams.vignette, vignettingColorAdjusted); Camera cam = cameraData.camera; float vignetteAspect; float vignetteData2 = 1f; if (beautify.vignettingCircularShape.value && beautify.vignettingBlink.value <= 0) { if (beautify.vignettingCircularShapeFitMode.value == VignetteFitMode.FitToWidth) { vignetteAspect = 1.0f / cam.aspect; } else { vignetteAspect = 1f; vignetteData2 = cam.aspect; } } else { vignetteAspect = beautify.vignettingAspectRatio.value + 1.001f / (1.001f - beautify.vignettingBlink.value) - 1f; } Vector4 vignetteData = new Vector4(beautify.vignettingCenter.value.x, beautify.vignettingCenter.value.y, vignetteAspect, outerRing); if (beautify.vignettingBlinkStyle.value == BlinkStyle.Human) { vignetteData.y -= beautify.vignettingBlink.value * 0.5f; } bMat.SetVector(ShaderParams.vignetteData, vignetteData); bMat.SetFloat(ShaderParams.vignetteData2, vignetteData2); } } static void DoEyeAdaptation (CommandBuffer cmd) { int rtEALength = rtEA.Length; int sizeEA = (int)Mathf.Pow(2, rtEALength); RenderTextureDescriptor eaDesc = sourceDescHP; for (int k = 0; k < rtEALength; k++) { eaDesc.width = eaDesc.height = sizeEA; cmd.GetTemporaryRT(rtEA[k], eaDesc, FilterMode.Bilinear); sizeEA /= 2; } FullScreenBlit(cmd, source, rtEA[0], bMat, (int)Pass.CopyBilinear); int lumRT = rtEALength - 1; for (int k = 0; k < lumRT; k++) { FullScreenBlit(cmd, rtEA[k], rtEA[k + 1], bMat, k == 0 ? (int)Pass.ComputeScreenLum : (int)Pass.DownsampleScreenLum); } cmd.SetGlobalTexture(ShaderParams.eaLumSrc, rtEA[lumRT]); bool firstBlend = false; if (camData.rtEAacum == null) { RenderTextureDescriptor rtEASmallDesc = sourceDescHP; rtEASmallDesc.width = rtEASmallDesc.height = 2; rtEASmallDesc.colorFormat = RenderTextureFormat.ARGBFloat; camData.rtEAacum = new RenderTexture(rtEASmallDesc); camData.rtEAacum.Create(); camData.rtEAHist = new RenderTexture(rtEASmallDesc); camData.rtEAHist.Create(); firstBlend = true; } if (firstBlend || Time.timeSinceLevelLoad < 0.5f) { FullScreenBlit(cmd, rtEA[lumRT], camData.rtEAacum, bMat, (int)Pass.CopyExact); FullScreenBlit(cmd, camData.rtEAacum, camData.rtEAHist, bMat, (int)Pass.CopyExact); } else { FullScreenBlit(cmd, rtEA[lumRT], camData.rtEAacum, bMat, (int)Pass.BlendScreenLum); FullScreenBlit(cmd, camData.rtEAacum, camData.rtEAHist, bMat, (int)Pass.SimpleBlendLum); } cmd.SetGlobalTexture(ShaderParams.eaHist, camData.rtEAHist); } static void DoSeparateOutline (CommandBuffer cmd) { RenderTextureDescriptor rtOutlineDescriptor = sourceDesc; rtOutlineDescriptor.colorFormat = supportsR8Format ? RenderTextureFormat.R8 : sourceDesc.colorFormat; cmd.GetTemporaryRT(ShaderParams.outlineRT, rtOutlineDescriptor); FullScreenBlit(cmd, source, ShaderParams.outlineRT, bMat, (int)Pass.OutlineDetect); int passCount = beautify.outlineBlurPassCount.value; float spread = beautify.outlineSpread.value; bool downscale = beautify.outlineBlurDownscale.value; for (int k = 1; k <= passCount; k++) { BlurThisOutline(cmd, rtOutlineDescriptor, spread, downscale ? k : 1); } FullScreenBlit(cmd, ShaderParams.outlineRT, source, bMat, (int)Pass.OutlineBlend); cmd.ReleaseTemporaryRT(ShaderParams.outlineRT); } static void BlurThisOutline (CommandBuffer cmd, RenderTextureDescriptor desc, float blurScale, int downscale) { desc.width = desc.width / downscale; desc.height = desc.height / downscale; cmd.GetTemporaryRT(ShaderParams.tempBlurRT, desc, FilterMode.Bilinear); cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale); FullScreenBlit(cmd, ShaderParams.outlineRT, ShaderParams.tempBlurRT, bMat, (int)Pass.OutlineBlurH); float ratio = (float)desc.height / desc.width; cmd.SetGlobalFloat(ShaderParams.blurScale, blurScale * ratio); FullScreenBlit(cmd, ShaderParams.tempBlurRT, ShaderParams.outlineRT, bMat, (int)Pass.OutlineBlurV); cmd.ReleaseTemporaryRT(ShaderParams.tempBlurRT); } static Vector3 camPrevPos; static Quaternion camPrevRotation; static float currSens; static bool canUseDepthTexture; public void UpdateMaterialProperties (Camera cam) { if (bMat == null) return; keywords.Clear(); // Compute motion sensibility float sharpenIntensity = beautify.sharpenIntensity.value; bool usesSharpen = sharpenIntensity > 0; sharpenExclusionLayerMask = beautify.sharpenExclusionLayerMask.value; // If exclusion mask is set to everything, disable sharpen if (sharpenExclusionLayerMask == -1) { usesSharpen = false; sharpenExclusionLayerMask = 0; } BeautifySettings.sharpenExclusionMask = sharpenExclusionLayerMask; usesSharpenExclusionMask = usesSharpen && sharpenExclusionLayerMask != 0; if (usesSharpen) { float tempSharpen = sharpenIntensity; float sensibility = beautify.sharpenMotionSensibility.value; if (sensibility > 0) { // Motion sensibility v2 Vector3 pos = cam.transform.position; Quaternion q = cam.transform.rotation; float dt = Time.deltaTime; if (pos != camPrevPos || q.x != camPrevRotation.x || q.y != camPrevRotation.y || q.z != camPrevRotation.z || q.w != camPrevRotation.w) { currSens = Mathf.Lerp(currSens, sharpenIntensity * sensibility, 30f * sensibility * dt); camPrevPos = pos; camPrevRotation = q; } else { currSens -= 30f * beautify.sharpenMotionRestoreSpeed.value * dt; } currSens = Mathf.Clamp(currSens, 0, sharpenIntensity); tempSharpen = sharpenIntensity - currSens; } bMat.SetVector(ShaderParams.sharpen, new Vector4(tempSharpen, canUseDepthTexture ? beautify.sharpenDepthThreshold.value + 0.000001f : 1f, beautify.sharpenClamp.value, beautify.sharpenRelaxation.value)); if (usesSharpenExclusionMask) { keywords.Add(ShaderParams.SKW_SHARPEN_EXCLUSION_MASK); } else { keywords.Add(ShaderParams.SKW_SHARPEN); } } bool isOrtho = cam.orthographic; bool linearColorSpace = QualitySettings.activeColorSpace == ColorSpace.Linear; bMat.SetVector(ShaderParams.colorParams, new Vector4(beautify.sepia.value, beautify.daltonize.value, (beautify.sharpenMinMaxDepth.value.x + beautify.sharpenMinMaxDepth.value.y) * 0.5f, Mathf.Abs(beautify.sharpenMinMaxDepth.value.y - beautify.sharpenMinMaxDepth.value.x) * 0.5f + (isOrtho ? 1000.0f : 0f))); float contrast = linearColorSpace ? 1.0f + (beautify.contrast.value - 1.0f) / 2.2f : beautify.contrast.value; bMat.SetVector(ShaderParams.colorBoost, new Vector4(beautify.brightness.value, contrast, beautify.saturate.value, beautify.downsamplingMultiplier.value > 1f ? 0 : beautify.ditherIntensity.value)); bMat.SetColor(ShaderParams.tintColor, beautify.tintColor.value); bMat.SetVector(ShaderParams.colorTemp, new Vector4(beautify.colorTemp.value, beautify.colorTempBlend.value, 0)); if (beautify.compareMode.value) { float angle, panningValue; switch (beautify.compareStyle.value) { case CompareStyle.FreeAngle: angle = beautify.compareLineAngle.value; panningValue = -10; break; case CompareStyle.SameSide: angle = Mathf.PI * 0.5f; panningValue = beautify.comparePanning.value; break; default: angle = Mathf.PI * 0.5f; panningValue = -20f + beautify.comparePanning.value * 2f; break; } bMat.SetVector(ShaderParams.compareParams, new Vector4(Mathf.Cos(angle), Mathf.Sin(angle), panningValue, beautify.compareLineWidth.value)); } bMat.SetVector(ShaderParams.fxColor, new Color(beautify.tonemapExposurePre.value, beautify.tonemapBrightnessPost.value, beautify.tonemapMaxInputBrightness.value, beautify.lutIntensity.value)); // bloom related usesBloomAndFlares = false; BeautifySettings.bloomExcludeMask = 0; BeautifySettings.anamorphicFlaresExcludeMask = 0; bool sunFlareEnabled = false; if (beautify.sunFlaresIntensity.value > 0) { CheckSun(); sunFlareEnabled = sceneSettings != null && sceneSettings.sun != null; } if (beautify.lensDirtIntensity.value > 0 || beautify.bloomIntensity.value > 0 || beautify.anamorphicFlaresIntensity.value > 0 || sunFlareEnabled) { BeautifySettings.bloomExcludeMask = beautify.bloomIntensity.value > 0 && beautify.bloomExcludeLayers.value ? (int)beautify.bloomExclusionLayerMask.value : 0; float bloomWeightsSum = 0.00001f + beautify.bloomWeight0.value + beautify.bloomWeight1.value + beautify.bloomWeight2.value + beautify.bloomWeight3.value + beautify.bloomWeight4.value + beautify.bloomWeight5.value; bMat.SetVector(ShaderParams.bloomWeights2, new Vector4(beautify.bloomWeight4.value / bloomWeightsSum + beautify.bloomBoost4.value, beautify.bloomWeight5.value / bloomWeightsSum + beautify.bloomBoost5.value, beautify.bloomMaxBrightness.value, bloomWeightsSum)); if (beautify.bloomCustomize.value) { bMat.SetColor(ShaderParams.bloomTint0, beautify.bloomTint0.value); bMat.SetColor(ShaderParams.bloomTint1, beautify.bloomTint1.value); bMat.SetColor(ShaderParams.bloomTint2, beautify.bloomTint2.value); bMat.SetColor(ShaderParams.bloomTint3, beautify.bloomTint3.value); bMat.SetColor(ShaderParams.bloomTint4, beautify.bloomTint4.value); bMat.SetColor(ShaderParams.bloomTint5, beautify.bloomTint5.value); } bMat.SetColor(ShaderParams.bloomTint, beautify.bloomTint.value); float spread = Mathf.Lerp(0.05f, 0.95f, beautify.bloomSpread.value); bMat.SetFloat(ShaderParams.bloomSpread, spread); UpdateMaterialBloomIntensityAndThreshold(); if (beautify.bloomIntensity.value > 0 || (beautify.lensDirtIntensity.value > 0 && beautify.anamorphicFlaresIntensity.value <= 0)) { bMat.SetVector(ShaderParams.bloomWeights, new Vector4(beautify.bloomWeight0.value / bloomWeightsSum + beautify.bloomBoost0.value, beautify.bloomWeight1.value / bloomWeightsSum + beautify.bloomBoost1.value, beautify.bloomWeight2.value / bloomWeightsSum + beautify.bloomBoost2.value, beautify.bloomWeight3.value / bloomWeightsSum + beautify.bloomBoost3.value)); if (canUseDepthTexture) { if (beautify.bloomDepthAtten.value > 0 || beautify.bloomNearAtten.value > 0) { keywords.Add(ShaderParams.SKW_BLOOM_USE_DEPTH); bMat.SetFloat(ShaderParams.bloomDepthThreshold, beautify.bloomDepthAtten.value); bMat.SetFloat(ShaderParams.bloomNearThreshold, (beautify.bloomNearAtten.value / cam.farClipPlane) + 0.00001f); } if (BeautifySettings.bloomExcludeMask != 0) { if (beautify.bloomLayersFilterMethod.value == BloomLayersFilterMethod.ExcludeSelectedLayers) { keywords.Add(ShaderParams.SKW_BLOOM_USE_LAYER); } else { keywords.Add(ShaderParams.SKW_BLOOM_USE_LAYER_INCLUSION); } } } if (beautify.bloomConservativeThreshold.value) { keywords.Add(ShaderParams.SKW_BLOOM_PROP_THRESHOLDING); } } keywords.Add(ShaderParams.SKW_BLOOM); usesBloomAndFlares = true; if (beautify.lensDirtIntensity.value > 0) { Vector4 dirtData = new Vector4(1.0f, beautify.lensDirtIntensity.value * beautify.lensDirtIntensity.value, beautify.lensDirtThreshold.value, Mathf.Max(beautify.bloomIntensity.value, 1f)); bMat.SetVector(ShaderParams.dirt, dirtData); Texture tex = beautify.lensDirtTexture.value; if (tex == null) { if (dirtTexture == null) { dirtTexture = Resources.Load("Textures/lensDirt") as Texture2D; } tex = dirtTexture; } if (tex != null) { bMat.SetTexture(ShaderParams.dirtTex, tex); keywords.Add(ShaderParams.SKW_DIRT); } } } // anamorphic flares related if (beautify.anamorphicFlaresIntensity.value > 0) { usesBloomAndFlares = true; if (canUseDepthTexture) { if (beautify.anamorphicFlaresDepthAtten.value > 0 || beautify.anamorphicFlaresNearAtten.value > 0) { keywords.Add(ShaderParams.SKW_ANAMORPHIC_FLARES_USE_DEPTH); bMat.SetFloat(ShaderParams.afDepthThreshold, beautify.anamorphicFlaresDepthAtten.value); bMat.SetFloat(ShaderParams.afNearThreshold, (beautify.anamorphicFlaresNearAtten.value / cam.farClipPlane) + 0.00001f); } BeautifySettings.anamorphicFlaresExcludeMask = beautify.anamorphicFlaresExcludeLayers.value ? (int)beautify.anamorphicFlaresExclusionLayerMask.value : 0; if (BeautifySettings.anamorphicFlaresExcludeMask != 0) { if (beautify.anamorphicFlaresLayersFilterMethod.value == BloomLayersFilterMethod.ExcludeSelectedLayers) { keywords.Add(ShaderParams.SKW_ANAMORPHIC_FLARES_USE_LAYER); } else { keywords.Add(ShaderParams.SKW_ANAMORPHIC_FLARES_USE_LAYER_INCLUSION); } } } if (beautify.anamorphicFlaresConservativeThreshold.value) { keywords.Add(ShaderParams.SKW_ANAMORPHIC_PROP_THRESHOLDING); } bMat.SetColor(ShaderParams.afTintColor, beautify.anamorphicFlaresTint.value); } // sun flares related if (sunFlareEnabled) { usesBloomAndFlares = true; bMat.SetVector(ShaderParams.sfSunData, new Vector4(beautify.sunFlaresSunIntensity.value, beautify.sunFlaresSunDiskSize.value, beautify.sunFlaresSunRayDiffractionIntensity.value, beautify.sunFlaresSunRayDiffractionThreshold.value)); bMat.SetVector(ShaderParams.sfCoronaRays1, new Vector4(beautify.sunFlaresCoronaRays1Length.value, Mathf.Max(beautify.sunFlaresCoronaRays1Streaks.value / 2f, 1), Mathf.Max(beautify.sunFlaresCoronaRays1Spread.value, 0.0001f), beautify.sunFlaresCoronaRays1AngleOffset.value)); bMat.SetVector(ShaderParams.sfCoronaRays2, new Vector4(beautify.sunFlaresCoronaRays2Length.value, Mathf.Max(beautify.sunFlaresCoronaRays2Streaks.value / 2f, 1), Mathf.Max(beautify.sunFlaresCoronaRays2Spread.value, 0.0001f), beautify.sunFlaresCoronaRays2AngleOffset.value)); if (canUseDepthTexture) { SunFlaresDepthOcclusionMode occlusionMode = beautify.sunFlaresDepthOcclusionMode.value; if (occlusionMode == SunFlaresDepthOcclusionMode.Simple) { keywords.Add(ShaderParams.SKW_SUN_FLARES_OCCLUSION_SIMPLE); } else if (occlusionMode == SunFlaresDepthOcclusionMode.Smooth) { keywords.Add(ShaderParams.SKW_SUN_FLARES_OCCLUSION_SMOOTH); bMat.SetFloat(ShaderParams.sfOcclusionThreshold, beautify.sunFlaresDepthOcclusionThreshold.value); } } #if UNITY_2020_3_OR_NEWER #if ENABLE_VR && ENABLE_XR_MODULE if (!cameraData.xrRendering) #endif { keywords.Add(ShaderParams.SKW_SUN_FLARES_USE_GHOSTS); bMat.SetVector(ShaderParams.sfGhosts1, new Vector4(0, beautify.sunFlaresGhosts1Size.value, beautify.sunFlaresGhosts1Offset.value, beautify.sunFlaresGhosts1Brightness.value)); bMat.SetVector(ShaderParams.sfGhosts2, new Vector4(0, beautify.sunFlaresGhosts2Size.value, beautify.sunFlaresGhosts2Offset.value, beautify.sunFlaresGhosts2Brightness.value)); bMat.SetVector(ShaderParams.sfGhosts3, new Vector4(0, beautify.sunFlaresGhosts3Size.value, beautify.sunFlaresGhosts3Offset.value, beautify.sunFlaresGhosts3Brightness.value)); bMat.SetVector(ShaderParams.sfGhosts4, new Vector4(0, beautify.sunFlaresGhosts4Size.value, beautify.sunFlaresGhosts4Offset.value, beautify.sunFlaresGhosts4Brightness.value)); bMat.SetVector(ShaderParams.sfHalo, new Vector4(beautify.sunFlaresHaloOffset.value, beautify.sunFlaresHaloAmplitude.value, beautify.sunFlaresHaloIntensity.value * 100f, 0)); } #else if (sourceDesc.vrUsage == VRTextureUsage.None) { keywords.Add(ShaderParams.SKW_SUN_FLARES_USE_GHOSTS); bMat.SetVector(ShaderParams.sfGhosts1, new Vector4(0, beautify.sunFlaresGhosts1Size.value, beautify.sunFlaresGhosts1Offset.value, beautify.sunFlaresGhosts1Brightness.value)); bMat.SetVector(ShaderParams.sfGhosts2, new Vector4(0, beautify.sunFlaresGhosts2Size.value, beautify.sunFlaresGhosts2Offset.value, beautify.sunFlaresGhosts2Brightness.value)); bMat.SetVector(ShaderParams.sfGhosts3, new Vector4(0, beautify.sunFlaresGhosts3Size.value, beautify.sunFlaresGhosts3Offset.value, beautify.sunFlaresGhosts3Brightness.value)); bMat.SetVector(ShaderParams.sfGhosts4, new Vector4(0, beautify.sunFlaresGhosts4Size.value, beautify.sunFlaresGhosts4Offset.value, beautify.sunFlaresGhosts4Brightness.value)); bMat.SetVector(ShaderParams.sfHalo, new Vector4(beautify.sunFlaresHaloOffset.value, beautify.sunFlaresHaloAmplitude.value, beautify.sunFlaresHaloIntensity.value * 100f, 0)); } #endif if (flareTex == null) { flareTex = Resources.Load("Textures/flareNoise") as Texture2D; } bMat.SetTexture(ShaderParams.sfFlareTex, flareTex); } // DoF usesDepthOfField = false; BeautifySettings.dofTransparentSupport = false; BeautifySettings.dofAlphaTestSupport = false; if (canUseDepthTexture && beautify.depthOfField.value) { usesDepthOfField = true; bool transparentSupport = beautify.depthOfFieldTransparentSupport.value && beautify.depthOfFieldTransparentLayerMask.value > 0; bool alphaTestSupport = beautify.depthOfFieldAlphaTestSupport.value && beautify.depthOfFieldAlphaTestLayerMask.value > 0; if (transparentSupport || alphaTestSupport) { keywords.Add(ShaderParams.SKW_DEPTH_OF_FIELD_TRANSPARENT); BeautifySettings.dofTransparentSupport = transparentSupport; if (alphaTestSupport) { BeautifySettings.dofAlphaTestSupport = true; BeautifySettings.dofAlphaTestLayerMask = beautify.depthOfFieldAlphaTestLayerMask.value; BeautifySettings.dofAlphaTestDoubleSided = beautify.depthOfFieldAlphaTestDoubleSided.value; } } else { keywords.Add(ShaderParams.SKW_DEPTH_OF_FIELD); } } // Vignette usesVignetting = false; float innerRing = 1f - beautify.vignettingInnerRing.value; float outerRing = 1f - beautify.vignettingOuterRing.value; usesVignetting = outerRing < 1 || innerRing < 1f || beautify.vignettingFade.value > 0 || beautify.vignettingBlink.value > 0; if (innerRing >= outerRing) { innerRing = outerRing - 0.0001f; } if (usesVignetting) { if (beautify.vignettingMask.value != null) { bMat.SetTexture(ShaderParams.vignetteMask, beautify.vignettingMask.value); keywords.Add(ShaderParams.SKW_VIGNETTING_MASK); } else { keywords.Add(ShaderParams.SKW_VIGNETTING); } } // Frame if (beautify.frame.value) { keywords.Add(ShaderParams.SKW_FRAME); Color frameColorAdjusted = beautify.frameColor.value; if (beautify.frameMask.value != null) { bMat.SetTexture(ShaderParams.frameMask, beautify.frameMask.value); } else { bMat.SetTexture(ShaderParams.frameMask, Texture2D.whiteTexture); } if (beautify.frameStyle.value == FrameStyle.Border) { bMat.SetColor(ShaderParams.frameColor, frameColorAdjusted); bMat.SetVector(ShaderParams.frameData, new Vector4(beautify.frameThickness.value, beautify.frameSharpness.value, 0, 0)); } else { bMat.SetColor(ShaderParams.frameColor, Color.black); bMat.SetVector(ShaderParams.frameData, new Vector4(0.5f - beautify.frameBandHorizontalSize.value, 1f / (0.0001f + beautify.frameBandHorizontalSmoothness.value), 0.5f - beautify.frameBandVerticalSize.value, 1f / (0.0001f + beautify.frameBandVerticalSmoothness.value))); } } // Purkinje and vignetting data bool usesPurkinje = beautify.purkinje.value; if (usesPurkinje || usesVignetting) { float vd = beautify.vignettingFade.value + beautify.vignettingBlink.value * 0.5f; if (beautify.vignettingBlink.value > 0.99f) vd = 1f; Vector4 purkinjeData = new Vector4(beautify.purkinjeAmount.value, beautify.purkinjeLuminanceThreshold.value, vd, innerRing); bMat.SetVector(ShaderParams.purkinje, purkinjeData); if (beautify.purkinje.value) { keywords.Add(ShaderParams.SKW_PURKINJE); } } // Eye adaptation bool usesEyeAdaptation = beautify.eyeAdaptation.value; requiresLuminanceComputation = Application.isPlaying && (usesEyeAdaptation || usesPurkinje); if (requiresLuminanceComputation) { Vector4 eaData = new Vector4(beautify.eyeAdaptationMinExposure.value, beautify.eyeAdaptationMaxExposure.value, beautify.eyeAdaptationSpeedToDark.value, beautify.eyeAdaptationSpeedToLight.value); bMat.SetVector(ShaderParams.eaParams, eaData); if (usesEyeAdaptation) { bMat.SetVector(ShaderParams.eaParams2, new Vector4(beautify.eyeAdaptationCenterWeight.value, beautify.eyeAdaptationMinCameraDistance.value, beautify.eyeAdaptationMiddleGray.value, 0f)); keywords.Add(ShaderParams.SKW_EYE_ADAPTATION); if (beautify.eyeAdaptationMinCameraDistance.value > 0) { keywords.Add(ShaderParams.SKW_EA_USE_DEPTH); } else if (beautify.eyeAdaptationMeteringMode.value == EyeAdaptationMeteringMode.Mask) { Texture eaMask = beautify.eyeAdaptationMask.value; if (eaMask != null) { bMat.SetTexture(ShaderParams.eaMask, eaMask); keywords.Add(ShaderParams.SKW_EA_USE_MASK); } } } } // Outline usesSeparateOutline = false; BeautifySettings.outlineDepthPrepass = false; BeautifySettings.outlineDepthPrepassUseOptimizedShader = false; BeautifySettings.outlineUseObjectId = false; if (canUseDepthTexture) { bool useOutlinePerObjectId = beautify.outlineTechnique.value == OutlineTechnique.PerObjectId; if (useOutlinePerObjectId) { beautify.outlineCustomize.Override(true); beautify.outlineUsesOptimizedShader.Override(true); } if (beautify.outline.value) { usesSeparateOutline = beautify.outlineCustomize.value; float outlineDistanceFade = 1; if (usesSeparateOutline) { bool useOptimizedShader = beautify.outlineUsesOptimizedShader.value; BeautifySettings.outlineUseObjectId = useOutlinePerObjectId; if (beautify.outlineLayerMask.value != -1 || useOutlinePerObjectId) { BeautifySettings.outlineDepthPrepass = true; BeautifySettings.outlineDepthPrepassUseOptimizedShader = useOptimizedShader; BeautifySettings.outlineLayerMask = beautify.outlineLayerMask.value; #if UNITY_2022_3_OR_NEWER BeautifySettings.outlineLayerCutOff = beautify.outlineLayerCutOff.value; #endif if (useOutlinePerObjectId) { keywords.Add(ShaderParams.SKW_OUTLINE_OBJECT_ID); } else { keywords.Add(ShaderParams.SKW_OUTLINE_CUSTOM_DEPTH); } } outlineDistanceFade = beautify.outlineDistanceFade.value / cam.farClipPlane; if (outlineDistanceFade > 0) { keywords.Add(ShaderParams.SKW_OUTLINE_DEPTH_FADE); } } else { keywords.Add(ShaderParams.SKW_OUTLINE); } float outlineZParam; if (useOutlinePerObjectId) { outlineZParam = beautify.outlineMinSeparation.value; if (outlineZParam > 1f) { keywords.Add(ShaderParams.SKW_OUTLINE_MIN_SEPARATION); } if (beautify.outlineOuterOnly.value) { keywords.Add(ShaderParams.SKW_OUTLINE_OUTER_ONLY); } } else { outlineZParam = beautify.outlineMinDepthThreshold.value; } bMat.SetVector(ShaderParams.outlineData, new Vector4(beautify.outlineIntensityMultiplier.value, outlineDistanceFade, outlineZParam, beautify.outlineSaturationDiffThreshold.value)); Color color = beautify.outlineColor.value; color.a = 1f - beautify.outlineThreshold.value; bMat.SetColor(ShaderParams.outline, color); } else { // edge AA related - only apply if outline is not used float aaStrength = beautify.antialiasStrength.value; if (aaStrength > 0) { bMat.SetVector(ShaderParams.edgeAntialiasing, new Vector4(aaStrength, beautify.antialiasDepthThreshold.value, beautify.antialiasDepthAttenuation.value * 10f, beautify.antialiasSpread.value)); if (usesDepthOfField) { keywords.Add(ShaderParams.SKW_EDGE_ANTIALIASING_DOF); } else { keywords.Add(ShaderParams.SKW_EDGE_ANTIALIASING); } } } } // Color tweaks if (beautify.sepia.value > 0 || beautify.daltonize.value > 0 || beautify.colorTempBlend.value > 0) { keywords.Add(ShaderParams.SKW_COLOR_TWEAKS); } // ACES Tonemapping if (beautify.tonemap.value == TonemapOperator.ACES) { keywords.Add(ShaderParams.SKW_TONEMAP_ACES); } else if (beautify.tonemap.value == TonemapOperator.ACESFitted) { keywords.Add(ShaderParams.SKW_TONEMAP_ACES_FITTED); } else if (beautify.tonemap.value == TonemapOperator.AGX) { bMat.SetFloat(ShaderParams.tonemapAGXGamma, linearColorSpace ? beautify.tonemapAGXGamma.value : beautify.tonemapAGXGamma.value * 0.5f); keywords.Add(ShaderParams.SKW_TONEMAP_AGX); } // LUT or Nightvision Texture lutTex = beautify.lutTexture.value; bool hasLut = beautify.lut.value && beautify.lutIntensity.value > 0 && lutTex != null; bool hasLut3D = hasLut && lutTex is Texture3D; if (hasLut || hasLut3D) { if (hasLut3D) { bMat.SetTexture(ShaderParams.lut3DTexture, lutTex); float x = 1f / lutTex.width; float y = lutTex.width - 1f; bMat.SetVector(ShaderParams.lut3DParams, new Vector4(x * 0.5f, x * y, 0, 0)); keywords.Add(ShaderParams.SKW_LUT3D); } else { bMat.SetTexture(ShaderParams.lutTex, beautify.lutTexture.value); keywords.Add(ShaderParams.SKW_LUT); } } else if (beautify.nightVision.value) { keywords.Add(ShaderParams.SKW_NIGHT_VISION); Color nightVisionAdjusted = beautify.nightVisionColor.value; if (linearColorSpace) { nightVisionAdjusted.a *= 5.0f * nightVisionAdjusted.a; } else { nightVisionAdjusted.a *= 3.0f * nightVisionAdjusted.a; } nightVisionAdjusted.r *= nightVisionAdjusted.a; nightVisionAdjusted.g *= nightVisionAdjusted.a; nightVisionAdjusted.b *= nightVisionAdjusted.a; bMat.SetColor(ShaderParams.nightVision, nightVisionAdjusted); bMat.SetVector(ShaderParams.nightVisionDepth, new Vector4(beautify.nightVisionDepth.value, beautify.nightVisionDepthFallOff.value, 0, 0)); } else if (beautify.thermalVision.value) { keywords.Add(ShaderParams.SKW_THERMAL_VISION); bMat.SetColor(ShaderParams.nightVision, new Color(0, 0, beautify.thermalVisionDistortionAmount.value / 10000f, beautify.thermalVisionScanLines.value ? 0.4f : -1)); } // Best performance mode if (beautify.turboMode.value) { keywords.Add(ShaderParams.SKW_TURBO); } // Chromatic Aberration if (beautify.chromaticAberrationIntensity.value > 0f) { bMat.SetVector(ShaderParams.chromaticAberrationData, new Vector4(beautify.chromaticAberrationIntensity.value, beautify.chromaticAberrationSmoothing.value, beautify.chromaticAberrationShift.value, 0)); if (!beautify.depthOfField.value) { keywords.Add(ShaderParams.SKW_CHROMATIC_ABERRATION); } } // Final blur mask if (beautify.blurIntensity.value > 0 && beautify.blurMask.value != null) { bMat.SetTexture(ShaderParams.blurMask, beautify.blurMask.value); } // Film grain if (beautify.filmGrainEnabled.value) { keywords.Add(ShaderParams.SKW_FILM_GRAIN); // Make film grain resolution independent by scaling inversely with screen resolution float resolutionScale = 1920f / cam.pixelWidth; // Use 1920 as reference resolution float adjustedResolution = beautify.filmGrainResolution.value * resolutionScale; bMat.SetVector(ShaderParams.filmGrainData, new Vector4( beautify.filmGrainIntensity.value, beautify.filmGrainLumaAttenuation.value, adjustedResolution, 0 )); float dirtSpotsIntensity = beautify.filmGrainDirtSpotsIntensity.value; float filmScrachesAmount = 1f - beautify.filmGrainScratchesAmount.value * 0.05f; float filmScrachesIntensity = beautify.filmGrainScratchesIntensity.value; bMat.SetVector(ShaderParams.filmArtifactsData, new Vector4( dirtSpotsIntensity > 0 ? 1f - beautify.filmGrainDirtSpotsAmount.value * 0.1f : 0, dirtSpotsIntensity, filmScrachesIntensity > 0 ? filmScrachesAmount : 0, filmScrachesIntensity )); } else // Dither if (beautify.ditherIntensity.value > 0f) { keywords.Add(ShaderParams.SKW_DITHER); } int keywordsCount = keywords.Count; if (keywordsArray == null || keywordsArray.Length < keywordsCount) { keywordsArray = new string[keywordsCount]; } int keywordsArrayLength = keywordsArray.Length; for (int k = 0; k < keywordsArrayLength; k++) { if (k < keywordsCount) { keywordsArray[k] = keywords[k]; } else { keywordsArray[k] = ""; } } bMat.shaderKeywords = keywordsArray; } static void UpdateMaterialBloomIntensityAndThreshold () { float bloomThreshold = beautify.bloomThreshold.value; float anamorphicThreshold = beautify.anamorphicFlaresThreshold.value; if (QualitySettings.activeColorSpace == ColorSpace.Linear) { bloomThreshold *= bloomThreshold; anamorphicThreshold *= anamorphicThreshold; } float anamorphicFlaresIntensity = beautify.turboMode.value ? beautify.anamorphicFlaresIntensity.value * 2f : beautify.anamorphicFlaresIntensity.value; float bloomIntensity = beautify.turboMode.value ? beautify.bloomIntensity.value * 2f : beautify.bloomIntensity.value; if (anamorphicFlaresIntensity > 0) { float intensity = anamorphicFlaresIntensity / (bloomIntensity + 0.0001f); bMat.SetVector(ShaderParams.afData, new Vector4(intensity, anamorphicThreshold, 0, beautify.anamorphicFlaresMaxBrightness.value)); } Vector4 b4 = new Vector4(bloomIntensity + (anamorphicFlaresIntensity > 0 ? 0.0001f : 0f), 0, 0, bloomThreshold); bMat.SetVector(ShaderParams.bloom, b4); } static void UpdateDepthOfFieldData (CommandBuffer cmd) { // TODO: get focal length from camera FOV: FOV = 2 arctan (x/2f) x = diagonal of film (0.024mm) if (!CheckSceneSettings()) return; Camera cam = cameraData.camera; float d = beautify.depthOfFieldDistance.value; Transform target = sceneSettings.depthOfFieldTarget; if (sceneSettings.OnCameraBeforeAutofocus != null) { sceneSettings.OnCameraBeforeAutofocus(cam, ref target); } switch ((int)beautify.depthOfFieldFocusMode.value) { case (int)DoFFocusMode.AutoFocus: UpdateDoFAutofocusDistance(cam); d = camData.dofLastAutofocusDistance; break; case (int)DoFFocusMode.FollowTarget: if (target != null) { Vector3 spos = cam.WorldToViewportPoint(target.position); bool isTargetVisible = spos.z >= 0 && spos.x >= 0 && spos.x <= 1 && spos.y >= 0 && spos.y <= 1; if (!isTargetVisible) { switch (beautify.depthOfFieldTargetFallback.value) { case DoFTargetFallback.SwitchToAutofocus: UpdateDoFAutofocusDistance(cam); d = camData.dofLastAutofocusDistance; break; case DoFTargetFallback.FixedDistanceFocus: d = beautify.depthOfFieldTargetFallbackFixedDistance.value; break; case DoFTargetFallback.DisableEffect: // Fade out gracefully float fadeOutSpeed = 1f / beautify.depthOfFieldFallbackFadeDuration.value; camData.dofFadeIntensity = Mathf.Max(0f, camData.dofFadeIntensity - fadeOutSpeed * Time.unscaledDeltaTime); d = camData.dofPrevDistance; // Keep current distance while fading break; default: d = camData.dofPrevDistance; break; } } else { d = Vector3.Distance(cam.transform.position, target.position); d = Mathf.Clamp(d, beautify.depthOfFieldAutofocusMinDistance.value, beautify.depthOfFieldAutofocusMaxDistance.value); // Fade back in when using DisableEffect fallback if (beautify.depthOfFieldTargetFallback.value == DoFTargetFallback.DisableEffect && camData.dofFadeIntensity < 1f) { float fadeInSpeed = 1f / beautify.depthOfFieldFallbackFadeDuration.value; camData.dofFadeIntensity = Mathf.Min(1f, camData.dofFadeIntensity + fadeInSpeed * Time.unscaledDeltaTime); } else { camData.dofFadeIntensity = 1f; } } } else { // No target assigned - handle as if target not visible if (beautify.depthOfFieldTargetFallback.value == DoFTargetFallback.DisableEffect) { float fadeOutSpeed = 1f / beautify.depthOfFieldFallbackFadeDuration.value; camData.dofFadeIntensity = Mathf.Max(0f, camData.dofFadeIntensity - fadeOutSpeed * Time.unscaledDeltaTime); } } break; case (int)DoFFocusMode.FollowPosition: Vector3 focusPos = sceneSettings.depthOfFieldFocusPositionEnabled ? sceneSettings.depthOfFieldFocusPosition : beautify.depthOfFieldFocusPosition.value; Vector3 screenPos = cam.WorldToViewportPoint(focusPos); bool isPosVisible = screenPos.z >= 0 && screenPos.x >= 0 && screenPos.x <= 1 && screenPos.y >= 0 && screenPos.y <= 1; if (!isPosVisible) { switch (beautify.depthOfFieldPositionFallback.value) { case DoFTargetFallback.SwitchToAutofocus: UpdateDoFAutofocusDistance(cam); d = camData.dofLastAutofocusDistance; break; case DoFTargetFallback.FixedDistanceFocus: d = beautify.depthOfFieldTargetFallbackFixedDistance.value; break; case DoFTargetFallback.DisableEffect: // Fade out gracefully float fadeOutSpeed = 1f / beautify.depthOfFieldFallbackFadeDuration.value; camData.dofFadeIntensity = Mathf.Max(0f, camData.dofFadeIntensity - fadeOutSpeed * Time.unscaledDeltaTime); d = camData.dofPrevDistance; // Keep current distance while fading break; default: d = camData.dofPrevDistance; break; } } else { d = Vector3.Distance(cam.transform.position, focusPos); d = Mathf.Clamp(d, beautify.depthOfFieldAutofocusMinDistance.value, beautify.depthOfFieldAutofocusMaxDistance.value); // Fade back in when using DisableEffect fallback if (beautify.depthOfFieldPositionFallback.value == DoFTargetFallback.DisableEffect && camData.dofFadeIntensity < 1f) { float fadeInSpeed = 1f / beautify.depthOfFieldFallbackFadeDuration.value; camData.dofFadeIntensity = Mathf.Min(1f, camData.dofFadeIntensity + fadeInSpeed * Time.unscaledDeltaTime); } else { camData.dofFadeIntensity = 1f; } } break; } if (sceneSettings.OnBeforeFocus != null) { d = sceneSettings.OnBeforeFocus(d); } if (sceneSettings.OnCameraBeforeFocus != null) { sceneSettings.OnCameraBeforeFocus(cam, ref d); } float t; if (camData.dofPrevDistance < 0 || !Application.isPlaying) { t = 1; } else { t = beautify.depthOfFieldFocusSpeed.value * Time.unscaledDeltaTime * 30f; } camData.dofPrevDistance = Mathf.Lerp(camData.dofPrevDistance, d, t); float dofCoc; if (beautify.depthOfFieldCameraSettings.value == Beautify.DoFCameraSettings.Real) { float focalLength, fStop, imageSensorHeight; if (beautify.depthOfFieldUsePhysicalCamera.value && cam.usePhysicalProperties) { // Use physical camera properties focalLength = cam.focalLength; #if UNITY_2022_1_OR_NEWER fStop = cam.aperture; #else fStop = beautify.depthOfFieldFStop.value; #endif imageSensorHeight = cam.sensorSize.y; } else { // Use Beautify settings focalLength = beautify.depthOfFieldFocalLengthReal.value; fStop = beautify.depthOfFieldFStop.value; imageSensorHeight = beautify.depthOfFieldImageSensorHeight.value; } float aperture = focalLength / fStop; dofCoc = aperture * (focalLength / Mathf.Max(camData.dofPrevDistance * 1000f - focalLength, 0.001f)) * (1f / imageSensorHeight) * cam.pixelHeight; } else { // focal length in meters; aperture in mm dofCoc = beautify.depthOfFieldAperture.value * (beautify.depthOfFieldFocalLength.value / Mathf.Max(camData.dofPrevDistance - beautify.depthOfFieldFocalLength.value, 0.001f)) * (1f / 0.024f); } float cocMultiplier = beautify.depthOfFieldResolutionInvariant.value ? cam.pixelWidth / 1920f : 1f; // Apply fade intensity for graceful disable transition dofCoc *= camData.dofFadeIntensity; camData.dofLastBokehData = new Vector4(camData.dofPrevDistance, dofCoc * cocMultiplier, 0, 0); cmd.SetGlobalVector(ShaderParams.dofBokehData, camData.dofLastBokehData); bMat.SetVector(ShaderParams.dofBokehData2, new Vector4(beautify.depthOfFieldForegroundBlur.value ? beautify.depthOfFieldForegroundDistance.value : cam.farClipPlane, beautify.depthOfFieldMaxSamples.value, beautify.depthOfFieldBokehThreshold.value, beautify.depthOfFieldBokehIntensity.value * beautify.depthOfFieldBokehIntensity.value)); bMat.SetVector(ShaderParams.dofBokehData3, new Vector4(beautify.depthOfFieldMaxBrightness.value, beautify.depthOfFieldMaxDistance.value * (cam.farClipPlane + 1f), beautify.depthOfFieldMaxBlurRadius.value, 0)); } static void UpdateDoFAutofocusDistance (Camera cam) { Vector3 p = beautify.depthOfFieldAutofocusViewportPoint.value; p.z = 10f; Ray r = cam.ViewportPointToRay(p); if (Physics.Raycast(r, out RaycastHit hit, cam.farClipPlane, beautify.depthOfFieldAutofocusLayerMask.value)) { // we don't use hit.distance as ray origin has a small shift from camera float distance = Vector3.Distance(cam.transform.position, hit.point); distance += beautify.depthOfFieldAutofocusDistanceShift.value; camData.dofLastAutofocusDistance = distance; } else { camData.dofLastAutofocusDistance = cam.farClipPlane; } camData.dofLastAutofocusDistance = Mathf.Clamp(camData.dofLastAutofocusDistance, beautify.depthOfFieldAutofocusMinDistance.value, beautify.depthOfFieldAutofocusMaxDistance.value); BeautifySettings.depthOfFieldCurrentFocalPointDistance = camData.dofLastAutofocusDistance; } // Scene dependant settings static BeautifySettings sceneSettings; static void CheckSun () { if (!CheckSceneSettings()) return; // Fetch a valid Sun reference if (sceneSettings.sun == null) { if (RenderSettings.sun != null) { sceneSettings.sun = RenderSettings.sun.transform; } } if (sceneSettings.sun == null) { #if UNITY_2023_1_OR_NEWER Light[] lights = FindObjectsByType(FindObjectsSortMode.None); #else Light[] lights = FindObjectsOfType(); #endif for (int k = 0; k < lights.Length; k++) { Light light = lights[k]; if (light.type == LightType.Directional && light.isActiveAndEnabled) { sceneSettings.sun = light.transform; break; } } } } static bool CheckSceneSettings () { sceneSettings = BeautifySettings.instance; return sceneSettings != null; } } class BeautifySharpenExclusionMaskPass : ScriptableRenderPass { static readonly List m_ShaderTagIdList = new List(); const string sharpenExclusionMaskRT = "_SharpenExclusionMask"; static int sharpenExclusionMaskId = Shader.PropertyToID(sharpenExclusionMaskRT); RTHandle maskRT; static bool canUse16Bit; public BeautifySharpenExclusionMaskPass () { RenderTargetIdentifier rti = new RenderTargetIdentifier(sharpenExclusionMaskRT, 0, CubemapFace.Unknown, -1); maskRT = RTHandles.Alloc(rti, name: sharpenExclusionMaskRT); renderPassEvent = RenderPassEvent.AfterRenderingOpaques; m_ShaderTagIdList.Clear(); m_ShaderTagIdList.Add(new ShaderTagId("SRPDefaultUnlit")); m_ShaderTagIdList.Add(new ShaderTagId("UniversalForward")); m_ShaderTagIdList.Add(new ShaderTagId("LightweightForward")); m_ShaderTagIdList.Add(new ShaderTagId("Universal2D")); canUse16Bit = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGB565); } #if UNITY_2022_2_OR_NEWER RTHandle depthRT; #else RenderTargetIdentifier depthRT; #endif #if UNITY_2022_1_OR_NEWER public void SetupRenderTargets(ScriptableRenderer renderer) { #if UNITY_2022_2_OR_NEWER #pragma warning disable CS0618 depthRT = renderer.cameraDepthTargetHandle; #pragma warning restore CS0618 #else depthRT = renderer.cameraDepthTarget; #endif } #else public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData renderingData) { depthRT = renderingData.cameraData.renderer.cameraDepthTarget; } #endif #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Configure (CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { RenderTextureDescriptor maskDesc = cameraTextureDescriptor; maskDesc.colorFormat = canUse16Bit ? RenderTextureFormat.RGB565 : RenderTextureFormat.ARGB32; maskDesc.depthBufferBits = 0; cmd.GetTemporaryRT(sharpenExclusionMaskId, maskDesc, FilterMode.Point); cmd.SetGlobalTexture(sharpenExclusionMaskRT, sharpenExclusionMaskId); ConfigureTarget(maskRT, depthRT); ConfigureClear(ClearFlag.Color, Color.black); } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) { SortingCriteria sortingCriteria = SortingCriteria.None; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, sortingCriteria); var filter = new FilteringSettings(RenderQueueRange.all) { layerMask = BeautifySettings.sharpenExclusionMask }; #if UNITY_2023_1_OR_NEWER CommandBuffer cmd = CommandBufferPool.Get("Beautify Sharpen Exclusion Mask"); RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); RendererList list = context.CreateRendererList(ref listParams); cmd.DrawRendererList(list); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); #else context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filter); #endif } #if UNITY_2023_3_OR_NEWER class PassData { public TextureHandle depthTexture; public RendererListHandle rendererListHandle; public UniversalCameraData cameraData; public int targetWidth; public int targetHeight; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { using (var builder = renderGraph.AddUnsafePass("Beautify Sharpen Exclusion Mask Pass", out var passData)) { builder.AllowPassCulling(false); UniversalResourceData resourceData = frameData.Get(); UniversalRenderingData renderingData = frameData.Get(); UniversalLightData lightData = frameData.Get(); UniversalCameraData cameraData = frameData.Get(); passData.depthTexture = resourceData.activeDepthTexture; passData.cameraData = cameraData; UnityEngine.Rendering.RenderGraphModule.TextureDesc activeDepthDesc = renderGraph.GetTextureDesc(resourceData.activeDepthTexture); passData.targetWidth = activeDepthDesc.width; passData.targetHeight = activeDepthDesc.height; SortingCriteria sortingCriteria = SortingCriteria.None; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, renderingData, cameraData, lightData, sortingCriteria); var filter = new FilteringSettings(RenderQueueRange.all) { layerMask = BeautifySettings.sharpenExclusionMask }; RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); passData.rendererListHandle = renderGraph.CreateRendererList(listParams); builder.UseRendererList(passData.rendererListHandle); builder.UseTexture(resourceData.activeDepthTexture, AccessFlags.Read); builder.SetRenderFunc((PassData passData, UnsafeGraphContext context) => { CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); RenderTextureDescriptor maskDesc = passData.cameraData.cameraTargetDescriptor; maskDesc.width = passData.targetWidth; maskDesc.height = passData.targetHeight; maskDesc.colorFormat = canUse16Bit ? RenderTextureFormat.RGB565 : RenderTextureFormat.ARGB32; maskDesc.depthBufferBits = 0; cmd.GetTemporaryRT(sharpenExclusionMaskId, maskDesc, FilterMode.Point); cmd.SetGlobalTexture(sharpenExclusionMaskRT, sharpenExclusionMaskId); RenderTargetIdentifier rti = new RenderTargetIdentifier(sharpenExclusionMaskId, 0, CubemapFace.Unknown, -1); cmd.SetRenderTarget(rti, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, passData.depthTexture, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store); cmd.ClearRenderTarget(false, true, Color.black); cmd.DrawRendererList(passData.rendererListHandle); }); } } #else public override void FrameCleanup (CommandBuffer cmd) { if (cmd == null) return; cmd.ReleaseTemporaryRT(sharpenExclusionMaskId); } #endif } class BeautifyBloomLumMaskPass : ScriptableRenderPass { static readonly List m_ShaderTagIdList = new List(); const string bloomSourceDepthRT = "_BloomSourceDepth"; static int bloomSourceDepthId = Shader.PropertyToID(bloomSourceDepthRT); RTHandle maskRT; public BeautifyBloomLumMaskPass () { RenderTargetIdentifier rti = new RenderTargetIdentifier(bloomSourceDepthRT, 0, CubemapFace.Unknown, -1); maskRT = RTHandles.Alloc(rti, name: bloomSourceDepthRT); renderPassEvent = RenderPassEvent.AfterRenderingOpaques; m_ShaderTagIdList.Clear(); m_ShaderTagIdList.Add(new ShaderTagId("SRPDefaultUnlit")); m_ShaderTagIdList.Add(new ShaderTagId("UniversalForward")); m_ShaderTagIdList.Add(new ShaderTagId("LightweightForward")); } #if UNITY_2022_2_OR_NEWER RTHandle depthRT; #else RenderTargetIdentifier depthRT; #endif #if UNITY_2022_1_OR_NEWER public void SetupRenderTargets(ScriptableRenderer renderer) { #if UNITY_2022_2_OR_NEWER #pragma warning disable CS0618 depthRT = renderer.cameraDepthTargetHandle; #pragma warning restore CS0618 #else depthRT = renderer.cameraDepthTarget; #endif } #else public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData renderingData) { depthRT = renderingData.cameraData.renderer.cameraDepthTarget; } #endif #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Configure (CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { RenderTextureDescriptor depthDesc = cameraTextureDescriptor; depthDesc.colorFormat = RenderTextureFormat.ARGB32; depthDesc.depthBufferBits = 0; cmd.GetTemporaryRT(bloomSourceDepthId, depthDesc, FilterMode.Point); cmd.SetGlobalTexture(bloomSourceDepthRT, bloomSourceDepthId); if (BeautifySettings.anamorphicFlaresExcludeMask == BeautifySettings.bloomExcludeMask) { cmd.SetGlobalTexture(BeautifyAnamorphicFlaresLumMaskPass.afSourceDepthRT, bloomSourceDepthId); } ConfigureTarget(maskRT, depthRT); ConfigureClear(ClearFlag.Color, Color.black); } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) { SortingCriteria sortingCriteria = SortingCriteria.None; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, sortingCriteria); var filter = new FilteringSettings(RenderQueueRange.all) { layerMask = BeautifySettings.bloomExcludeMask }; #if UNITY_2023_1_OR_NEWER CommandBuffer cmd = CommandBufferPool.Get("Beautify Luma Mask"); RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); RendererList list = context.CreateRendererList(ref listParams); cmd.DrawRendererList(list); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); #else context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filter); #endif } #if UNITY_2023_3_OR_NEWER class PassData { public TextureHandle depthTexture; public RendererListHandle rendererListHandle; public UniversalCameraData cameraData; public int targetWidth; public int targetHeight; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { using (var builder = renderGraph.AddUnsafePass("Beautify Bloom Luminance Mask Pass", out var passData)) { builder.AllowPassCulling(false); UniversalResourceData resourceData = frameData.Get(); UniversalRenderingData renderingData = frameData.Get(); UniversalLightData lightData = frameData.Get(); UniversalCameraData cameraData = frameData.Get(); passData.depthTexture = resourceData.activeDepthTexture; passData.cameraData = cameraData; UnityEngine.Rendering.RenderGraphModule.TextureDesc activeColorDesc = renderGraph.GetTextureDesc(resourceData.activeColorTexture); passData.targetWidth = activeColorDesc.width; passData.targetHeight = activeColorDesc.height; SortingCriteria sortingCriteria = SortingCriteria.None; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, renderingData, cameraData, lightData, sortingCriteria); var filter = new FilteringSettings(RenderQueueRange.all) { layerMask = BeautifySettings.bloomExcludeMask }; RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); passData.rendererListHandle = renderGraph.CreateRendererList(listParams); builder.UseRendererList(passData.rendererListHandle); builder.UseTexture(resourceData.activeDepthTexture, AccessFlags.Read); builder.SetRenderFunc((PassData passData, UnsafeGraphContext context) => { CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); RenderTextureDescriptor depthDesc = passData.cameraData.cameraTargetDescriptor; depthDesc.width = passData.targetWidth; depthDesc.height = passData.targetHeight; depthDesc.colorFormat = RenderTextureFormat.ARGB32; depthDesc.depthBufferBits = 0; cmd.GetTemporaryRT(bloomSourceDepthId, depthDesc, FilterMode.Point); cmd.SetGlobalTexture(bloomSourceDepthRT, bloomSourceDepthId); if (BeautifySettings.anamorphicFlaresExcludeMask == BeautifySettings.bloomExcludeMask) { cmd.SetGlobalTexture(BeautifyAnamorphicFlaresLumMaskPass.afSourceDepthRT, bloomSourceDepthId); } RenderTargetIdentifier rti = new RenderTargetIdentifier(bloomSourceDepthId, 0, CubemapFace.Unknown, -1); cmd.SetRenderTarget(rti, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, passData.depthTexture, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store); cmd.ClearRenderTarget(false, true, Color.black); cmd.DrawRendererList(passData.rendererListHandle); }); } } #else public override void FrameCleanup (CommandBuffer cmd) { if (cmd == null) return; cmd.ReleaseTemporaryRT(bloomSourceDepthId); } #endif } class BeautifyAnamorphicFlaresLumMaskPass : ScriptableRenderPass { static readonly List m_ShaderTagIdList = new List(); public const string afSourceDepthRT = "_AFSourceDepth"; static int afSourceDepthId = Shader.PropertyToID(afSourceDepthRT); RTHandle maskRT; public BeautifyAnamorphicFlaresLumMaskPass () { RenderTargetIdentifier rti = new RenderTargetIdentifier(afSourceDepthRT, 0, CubemapFace.Unknown, -1); maskRT = RTHandles.Alloc(rti, name: afSourceDepthRT); renderPassEvent = RenderPassEvent.BeforeRenderingTransparents; m_ShaderTagIdList.Clear(); m_ShaderTagIdList.Add(new ShaderTagId("SRPDefaultUnlit")); m_ShaderTagIdList.Add(new ShaderTagId("UniversalForward")); m_ShaderTagIdList.Add(new ShaderTagId("LightweightForward")); } #if UNITY_2022_2_OR_NEWER RTHandle depthRT; #else RenderTargetIdentifier depthRT; #endif #if UNITY_2022_1_OR_NEWER public void SetupRenderTargets(ScriptableRenderer renderer) { #if UNITY_2022_2_OR_NEWER #pragma warning disable CS0618 depthRT = renderer.cameraDepthTargetHandle; #pragma warning restore CS0618 #else depthRT = renderer.cameraDepthTarget; #endif } #else public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData renderingData) { depthRT = renderingData.cameraData.renderer.cameraDepthTarget; } #endif #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Configure (CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { RenderTextureDescriptor depthDesc = cameraTextureDescriptor; depthDesc.colorFormat = RenderTextureFormat.ARGB32; depthDesc.depthBufferBits = 0; cmd.GetTemporaryRT(afSourceDepthId, depthDesc, FilterMode.Point); cmd.SetGlobalTexture(afSourceDepthRT, afSourceDepthId); ConfigureTarget(maskRT, depthRT); ConfigureClear(ClearFlag.Color, Color.black); } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) { SortingCriteria sortingCriteria = SortingCriteria.None; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, sortingCriteria); var filter = new FilteringSettings(RenderQueueRange.all) { layerMask = BeautifySettings.anamorphicFlaresExcludeMask }; #if UNITY_2023_1_OR_NEWER CommandBuffer cmd = CommandBufferPool.Get("AF Luma Mask"); RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); RendererList list = context.CreateRendererList(ref listParams); cmd.DrawRendererList(list); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); #else context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filter); #endif } #if UNITY_2023_3_OR_NEWER class PassData { public TextureHandle depthTexture; public RendererListHandle rendererListHandle; public UniversalCameraData cameraData; public int targetWidth; public int targetHeight; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { using (var builder = renderGraph.AddUnsafePass("Beautify AF Luminance Mask Pass", out var passData)) { builder.AllowPassCulling(false); UniversalResourceData resourceData = frameData.Get(); UniversalRenderingData renderingData = frameData.Get(); UniversalLightData lightData = frameData.Get(); UniversalCameraData cameraData = frameData.Get(); passData.depthTexture = resourceData.activeDepthTexture; builder.UseTexture(resourceData.activeDepthTexture, AccessFlags.Read); passData.cameraData = cameraData; UnityEngine.Rendering.RenderGraphModule.TextureDesc activeColorDesc = renderGraph.GetTextureDesc(resourceData.activeColorTexture); passData.targetWidth = activeColorDesc.width; passData.targetHeight = activeColorDesc.height; SortingCriteria sortingCriteria = SortingCriteria.None; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, renderingData, cameraData, lightData, sortingCriteria); var filter = new FilteringSettings(RenderQueueRange.all) { layerMask = BeautifySettings.anamorphicFlaresExcludeMask }; RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); passData.rendererListHandle = renderGraph.CreateRendererList(listParams); builder.UseRendererList(passData.rendererListHandle); builder.SetRenderFunc((PassData passData, UnsafeGraphContext context) => { CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); RenderTextureDescriptor depthDesc = passData.cameraData.cameraTargetDescriptor; depthDesc.width = passData.targetWidth; depthDesc.height = passData.targetHeight; depthDesc.colorFormat = RenderTextureFormat.ARGB32; depthDesc.depthBufferBits = 0; cmd.GetTemporaryRT(afSourceDepthId, depthDesc, FilterMode.Point); cmd.SetGlobalTexture(afSourceDepthRT, afSourceDepthId); RenderTargetIdentifier rti = new RenderTargetIdentifier(afSourceDepthId, 0, CubemapFace.Unknown, -1); cmd.SetRenderTarget(rti, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, passData.depthTexture, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store); cmd.ClearRenderTarget(false, true, Color.black); cmd.DrawRendererList(passData.rendererListHandle); }); } } #else public override void FrameCleanup (CommandBuffer cmd) { if (cmd == null) return; cmd.ReleaseTemporaryRT(afSourceDepthId); } #endif } internal class BeautifyDoFTransparentMaskPass : ScriptableRenderPass { static readonly List m_ShaderTagIdList = new List(); static readonly List cutOutRenderers = new List(); static readonly List userCutOutRenderers = new List(); static readonly List s_TempRootObjects = new List(64); static readonly List s_TempRenderers = new List(1024); const string dofTransparentDepthRT = "_DoFTransparentDepth"; static int dofTransparentDepthId = Shader.PropertyToID(dofTransparentDepthRT); static int m_CullPropertyId = Shader.PropertyToID("_Cull"); const string m_ProfilerTag = "CustomDepthPrePass"; const string m_DepthOnlyShader = "Hidden/Beautify2/DepthOnly"; RTHandle m_Depth; static Material depthOnlyMaterial, depthOnlyMaterialCutOff; static int currentAlphaCutoutLayerMask = -999; static Material[] depthOverrideMaterials; public BeautifyDoFTransparentMaskPass () { RenderTargetIdentifier rti = new RenderTargetIdentifier(dofTransparentDepthRT, 0, CubemapFace.Unknown, -1); m_Depth = RTHandles.Alloc(rti, name: dofTransparentDepthRT); renderPassEvent = RenderPassEvent.AfterRenderingOpaques; m_ShaderTagIdList.Clear(); m_ShaderTagIdList.Add(new ShaderTagId("SRPDefaultUnlit")); m_ShaderTagIdList.Add(new ShaderTagId("UniversalForward")); m_ShaderTagIdList.Add(new ShaderTagId("LightweightForward")); } static void FindAlphaClippingRenderers () { BeautifySettings._refreshAlphaClipRenderers = false; cutOutRenderers.Clear(); currentAlphaCutoutLayerMask = BeautifySettings.dofAlphaTestLayerMask; int sceneCount = SceneManager.sceneCount; for (int si = 0; si < sceneCount; si++) { Scene scene = SceneManager.GetSceneAt(si); if (!scene.isLoaded) continue; scene.GetRootGameObjects(s_TempRootObjects); int rootCount = s_TempRootObjects.Count; for (int ri = 0; ri < rootCount; ri++) { GameObject root = s_TempRootObjects[ri]; if (root == null) continue; root.GetComponentsInChildren(false, s_TempRenderers); int rrLength = s_TempRenderers.Count; for (int r = 0; r < rrLength; r++) { Renderer renderer = s_TempRenderers[r]; if (renderer != null && ((1 << renderer.gameObject.layer) & currentAlphaCutoutLayerMask) != 0) { cutOutRenderers.Add(renderer); } } } } int userCount = userCutOutRenderers.Count; for (int i = 0; i < userCount; i++) { Renderer mr = userCutOutRenderers[i]; if (mr != null && !cutOutRenderers.Contains(mr)) { cutOutRenderers.Add(mr); } } } public static void RegisterCutOutRenderers (List renderers) { if (renderers == null) return; int count = renderers.Count; for (int i = 0; i < count; i++) { Renderer r = renderers[i]; if (r == null) continue; if (!userCutOutRenderers.Contains(r)) userCutOutRenderers.Add(r); if (!cutOutRenderers.Contains(r)) cutOutRenderers.Add(r); } } public static void UnregisterCutOutRenderers (List renderers) { if (renderers == null) return; int count = renderers.Count; for (int i = 0; i < count; i++) { Renderer r = renderers[i]; if (r == null) continue; userCutOutRenderers.Remove(r); cutOutRenderers.Remove(r); } } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Configure (CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { RenderTextureDescriptor depthDesc = cameraTextureDescriptor; depthDesc.colorFormat = RenderTextureFormat.Depth; depthDesc.depthBufferBits = 24; depthDesc.msaaSamples = 1; cmd.GetTemporaryRT(dofTransparentDepthId, depthDesc, FilterMode.Point); cmd.SetGlobalTexture(dofTransparentDepthRT, dofTransparentDepthId); ConfigureTarget(m_Depth); ConfigureClear(ClearFlag.All, Color.black); } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) { CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); cmd.Clear(); if (BeautifySettings.dofAlphaTestSupport) { if (BeautifySettings.dofAlphaTestLayerMask != 0) { if (BeautifySettings.dofAlphaTestLayerMask != currentAlphaCutoutLayerMask || BeautifySettings._refreshAlphaClipRenderers) { FindAlphaClippingRenderers(); } if (depthOnlyMaterialCutOff == null) { Shader depthOnlyCutOff = Shader.Find(m_DepthOnlyShader); depthOnlyMaterialCutOff = new Material(depthOnlyCutOff); } int renderersCount = cutOutRenderers.Count; if (depthOverrideMaterials == null || depthOverrideMaterials.Length < renderersCount) { depthOverrideMaterials = new Material[renderersCount]; } for (int k = 0; k < renderersCount; k++) { Renderer renderer = cutOutRenderers[k]; if (renderer != null && renderer.isVisible) { Material mat = renderer.sharedMaterial; if (mat != null) { if (depthOverrideMaterials[k] == null) { depthOverrideMaterials[k] = Instantiate(depthOnlyMaterialCutOff); depthOverrideMaterials[k].EnableKeyword(ShaderParams.SKW_CUSTOM_DEPTH_ALPHA_TEST); } Material overrideMaterial = depthOverrideMaterials[k]; if (mat.HasProperty(ShaderParams.CustomDepthAlphaCutoff)) { overrideMaterial.SetFloat(ShaderParams.CustomDepthAlphaCutoff, mat.GetFloat(ShaderParams.CustomDepthAlphaCutoff)); } else { overrideMaterial.SetFloat(ShaderParams.CustomDepthAlphaCutoff, 0.5f); } if (mat.HasProperty(ShaderParams.CustomDepthBaseMap)) { overrideMaterial.SetTexture(ShaderParams.CustomDepthBaseMap, mat.GetTexture(ShaderParams.CustomDepthBaseMap)); } else if (mat.HasProperty(ShaderParams.mainTex)) { overrideMaterial.SetTexture(ShaderParams.CustomDepthBaseMap, mat.GetTexture(ShaderParams.mainTex)); } overrideMaterial.SetInt(m_CullPropertyId, BeautifySettings.dofAlphaTestDoubleSided ? (int)CullMode.Off : (int)CullMode.Back); cmd.DrawRenderer(renderer, overrideMaterial); } } } } } // Render transparent objects if (BeautifySettings.dofTransparentSupport) { if (depthOnlyMaterial == null) { depthOnlyMaterial = new Material(Shader.Find(m_DepthOnlyShader)); } depthOnlyMaterial.SetInt(m_CullPropertyId, BeautifySettings.dofTransparentDoubleSided ? (int)CullMode.Off : (int)CullMode.Back); SortingCriteria sortingCriteria = renderingData.cameraData.defaultOpaqueSortFlags; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, sortingCriteria); drawingSettings.perObjectData = PerObjectData.None; drawingSettings.overrideMaterial = depthOnlyMaterial; var filter = new FilteringSettings(RenderQueueRange.transparent) { layerMask = BeautifySettings.dofTransparentLayerMask }; #if UNITY_2023_1_OR_NEWER RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); RendererList list = context.CreateRendererList(ref listParams); cmd.DrawRendererList(list); #else context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filter); #endif } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } #if UNITY_2023_3_OR_NEWER class PassData { public UniversalCameraData cameraData; public RendererListHandle rendererListHandle; public int targetWidth; public int targetHeight; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { using (var builder = renderGraph.AddUnsafePass("Beautify DoF Transp Mask Pass RG", out var passData)) { builder.AllowPassCulling(false); UniversalResourceData resourceData = frameData.Get(); UniversalRenderingData renderingData = frameData.Get(); UniversalCameraData cameraData = frameData.Get(); UniversalLightData lightData = frameData.Get(); passData.cameraData = cameraData; TextureDesc activeColorDesc = renderGraph.GetTextureDesc(resourceData.activeColorTexture); passData.targetWidth = activeColorDesc.width; passData.targetHeight = activeColorDesc.height; if (BeautifySettings.dofTransparentSupport) { SortingCriteria sortingCriteria = cameraData.defaultOpaqueSortFlags; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, renderingData, cameraData, lightData, sortingCriteria); drawingSettings.perObjectData = PerObjectData.None; if (depthOnlyMaterial == null) { depthOnlyMaterial = new Material(Shader.Find(m_DepthOnlyShader)); } depthOnlyMaterial.SetInt(m_CullPropertyId, BeautifySettings.dofTransparentDoubleSided ? (int)CullMode.Off : (int)CullMode.Back); drawingSettings.overrideMaterial = depthOnlyMaterial; var filter = new FilteringSettings(RenderQueueRange.transparent) { layerMask = BeautifySettings.dofTransparentLayerMask }; RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); passData.rendererListHandle = renderGraph.CreateRendererList(listParams); builder.UseRendererList(passData.rendererListHandle); } builder.SetRenderFunc((PassData passData, UnsafeGraphContext context) => { CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); RenderTextureDescriptor depthDesc = passData.cameraData.cameraTargetDescriptor; depthDesc.colorFormat = RenderTextureFormat.Depth; depthDesc.depthBufferBits = 24; depthDesc.msaaSamples = 1; cmd.GetTemporaryRT(dofTransparentDepthId, depthDesc, FilterMode.Point); cmd.SetGlobalTexture(dofTransparentDepthRT, dofTransparentDepthId); RenderTargetIdentifier rti = new RenderTargetIdentifier(dofTransparentDepthId, 0, CubemapFace.Unknown, -1); cmd.SetRenderTarget(rti, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); cmd.ClearRenderTarget(true, true, Color.black); if (BeautifySettings.dofAlphaTestSupport) { if (BeautifySettings.dofAlphaTestLayerMask != 0) { if (BeautifySettings.dofAlphaTestLayerMask != currentAlphaCutoutLayerMask || BeautifySettings._refreshAlphaClipRenderers) { FindAlphaClippingRenderers(); } if (depthOnlyMaterialCutOff == null) { Shader depthOnlyCutOff = Shader.Find(m_DepthOnlyShader); depthOnlyMaterialCutOff = new Material(depthOnlyCutOff); } int renderersCount = cutOutRenderers.Count; if (depthOverrideMaterials == null || depthOverrideMaterials.Length < renderersCount) { depthOverrideMaterials = new Material[renderersCount]; } for (int k = 0; k < renderersCount; k++) { Renderer renderer = cutOutRenderers[k]; if (renderer != null && renderer.isVisible) { Material mat = renderer.sharedMaterial; if (mat != null) { if (depthOverrideMaterials[k] == null) { depthOverrideMaterials[k] = Instantiate(depthOnlyMaterialCutOff); depthOverrideMaterials[k].EnableKeyword(ShaderParams.SKW_CUSTOM_DEPTH_ALPHA_TEST); } Material overrideMaterial = depthOverrideMaterials[k]; if (mat.HasProperty(ShaderParams.CustomDepthAlphaCutoff)) { overrideMaterial.SetFloat(ShaderParams.CustomDepthAlphaCutoff, mat.GetFloat(ShaderParams.CustomDepthAlphaCutoff)); } else { overrideMaterial.SetFloat(ShaderParams.CustomDepthAlphaCutoff, 0.5f); } if (mat.HasProperty(ShaderParams.CustomDepthBaseMap)) { overrideMaterial.SetTexture(ShaderParams.CustomDepthBaseMap, mat.GetTexture(ShaderParams.CustomDepthBaseMap)); } else if (mat.HasProperty(ShaderParams.mainTex)) { overrideMaterial.SetTexture(ShaderParams.CustomDepthBaseMap, mat.GetTexture(ShaderParams.mainTex)); } overrideMaterial.SetInt(m_CullPropertyId, BeautifySettings.dofAlphaTestDoubleSided ? (int)CullMode.Off : (int)CullMode.Back); cmd.DrawRenderer(renderer, overrideMaterial); } } } } } // Render transparent objects if (BeautifySettings.dofTransparentSupport) { cmd.DrawRendererList(passData.rendererListHandle); } }); } } #else public override void FrameCleanup (CommandBuffer cmd) { if (cmd == null) return; cmd.ReleaseTemporaryRT(dofTransparentDepthId); } #endif } class BeautifyOutlineDepthPrepass : ScriptableRenderPass { static readonly List m_ShaderTagIdList = new List(); const string outlineObjectIdRT = "_OutlineObjectId"; const string outlineDepthRT = "_OutlineDepth"; static int outlineDepthId = Shader.PropertyToID(outlineDepthRT); static int m_CullPropertyId = Shader.PropertyToID("_Cull"); const string m_ProfilerTag = "CustomOutlineDepthPrePass"; const string m_DepthOnlyShader = "Hidden/Beautify2/DepthOnly"; const string m_DepthOnlyWithObjectIdShader = "Hidden/Beautify2/DepthOnlyWithObjectId"; const string m_DepthOnlyAlphaTestShader = "Hidden/Beautify2/DepthOnlyAlphaTest"; const string m_DepthOnlyWithObjectIdAlphaTestShader = "Hidden/Beautify2/DepthOnlyWithObjectIdAlphaTest"; static Material depthOnlyMaterial, depthOnlyMaterialWithObjectId; Shader depthOnlyShaderWithAlphaTest, depthOnlyShaderWithAlphaTestObjectId; RTHandle outlineDepthHandle; public BeautifyOutlineDepthPrepass () { renderPassEvent = RenderPassEvent.AfterRenderingOpaques; m_ShaderTagIdList.Clear(); m_ShaderTagIdList.Add(new ShaderTagId("SRPDefaultUnlit")); m_ShaderTagIdList.Add(new ShaderTagId("UniversalForward")); m_ShaderTagIdList.Add(new ShaderTagId("LightweightForward")); RenderTargetIdentifier rti = new RenderTargetIdentifier(outlineDepthRT, 0, CubemapFace.Unknown, -1); outlineDepthHandle = RTHandles.Alloc(rti, name: outlineDepthRT); } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Configure (CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { RenderTextureDescriptor depthDesc = cameraTextureDescriptor; depthDesc.colorFormat = BeautifySettings.outlineUseObjectId ? RenderTextureFormat.RFloat : RenderTextureFormat.Depth; depthDesc.depthBufferBits = 24; depthDesc.msaaSamples = 1; cmd.GetTemporaryRT(outlineDepthId, depthDesc, FilterMode.Point); if (BeautifySettings.outlineUseObjectId) { cmd.SetGlobalTexture(outlineObjectIdRT, outlineDepthId, RenderTextureSubElement.Color); cmd.SetGlobalTexture(outlineDepthRT, outlineDepthId, RenderTextureSubElement.Depth); } else { cmd.SetGlobalTexture(outlineDepthRT, outlineDepthId); } #if UNITY_2022_2_OR_NEWER ConfigureTarget(outlineDepthHandle); #else RenderTargetIdentifier rti = new RenderTargetIdentifier(outlineDepthId, 0, CubemapFace.Unknown, -1); ConfigureTarget(rti); #endif if (BeautifySettings.outlineUseObjectId) { ConfigureClear(ClearFlag.Depth | ClearFlag.Color, Color.black); } else { ConfigureClear(ClearFlag.Depth, Color.black); } } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) { if (!BeautifySettings.outlineDepthPrepass) return; SortingCriteria sortingCriteria = renderingData.cameraData.defaultOpaqueSortFlags; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, sortingCriteria); drawingSettings.perObjectData = PerObjectData.None; if (BeautifySettings.outlineDepthPrepassUseOptimizedShader) { #if UNITY_2022_3_OR_NEWER if (BeautifySettings.outlineLayerCutOff > 0) { Shader alphaTestShader = null; if (BeautifySettings.outlineUseObjectId) { if (depthOnlyShaderWithAlphaTestObjectId == null) { depthOnlyShaderWithAlphaTestObjectId = Shader.Find(m_DepthOnlyWithObjectIdAlphaTestShader); } alphaTestShader = depthOnlyShaderWithAlphaTestObjectId; } else { if (depthOnlyShaderWithAlphaTest == null) { depthOnlyShaderWithAlphaTest = Shader.Find(m_DepthOnlyAlphaTestShader); } alphaTestShader = depthOnlyShaderWithAlphaTest; } drawingSettings.overrideShader = alphaTestShader; Shader.SetGlobalFloat(ShaderParams.CustomDepthAlphaTestCutoff, BeautifySettings.outlineLayerCutOff); } else #endif { Material depthMaterial = null; if (BeautifySettings.outlineUseObjectId) { if (depthOnlyMaterialWithObjectId == null) { depthOnlyMaterialWithObjectId = new Material(Shader.Find(m_DepthOnlyWithObjectIdShader)); } depthMaterial = depthOnlyMaterialWithObjectId; } else { if (depthOnlyMaterial == null) { depthOnlyMaterial = new Material(Shader.Find(m_DepthOnlyShader)); } depthMaterial = depthOnlyMaterial; } depthMaterial.SetInt(m_CullPropertyId, (int)CullMode.Back); depthMaterial.DisableKeyword(ShaderParams.SKW_CUSTOM_DEPTH_ALPHA_TEST); drawingSettings.overrideMaterial = depthMaterial; } } var filter = new FilteringSettings(RenderQueueRange.opaque) { layerMask = BeautifySettings.outlineLayerMask }; #if UNITY_2023_1_OR_NEWER CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); cmd.Clear(); RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); RendererList list = context.CreateRendererList(ref listParams); cmd.DrawRendererList(list); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); #else context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filter); #endif } #if UNITY_2023_3_OR_NEWER class PassData { public UniversalCameraData cameraData; public RendererListHandle rendererListHandle; public int targetWidth; public int targetHeight; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { using (var builder = renderGraph.AddUnsafePass("Beautify Outline Depth Prepass RG", out var passData)) { builder.AllowPassCulling(false); UniversalResourceData resourceData = frameData.Get(); UniversalRenderingData renderingData = frameData.Get(); UniversalCameraData cameraData = frameData.Get(); UniversalLightData lightData = frameData.Get(); passData.cameraData = cameraData; TextureDesc activeColorDesc = renderGraph.GetTextureDesc(resourceData.activeColorTexture); passData.targetWidth = activeColorDesc.width; passData.targetHeight = activeColorDesc.height; SortingCriteria sortingCriteria = cameraData.defaultOpaqueSortFlags; var drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, renderingData, cameraData, lightData, sortingCriteria); drawingSettings.perObjectData = PerObjectData.None; if (BeautifySettings.outlineDepthPrepassUseOptimizedShader) { if (BeautifySettings.outlineLayerCutOff > 0) { Shader alphaTestShader = null; if (BeautifySettings.outlineUseObjectId) { if (depthOnlyShaderWithAlphaTestObjectId == null) { depthOnlyShaderWithAlphaTestObjectId = Shader.Find(m_DepthOnlyWithObjectIdAlphaTestShader); } alphaTestShader = depthOnlyShaderWithAlphaTestObjectId; } else { if (depthOnlyShaderWithAlphaTest == null) { depthOnlyShaderWithAlphaTest = Shader.Find(m_DepthOnlyAlphaTestShader); } alphaTestShader = depthOnlyShaderWithAlphaTest; } drawingSettings.overrideShader = alphaTestShader; Shader.SetGlobalFloat(ShaderParams.CustomDepthAlphaTestCutoff, BeautifySettings.outlineLayerCutOff); } else { Material depthMaterial = null; if (BeautifySettings.outlineUseObjectId) { if (depthOnlyMaterialWithObjectId == null) { depthOnlyMaterialWithObjectId = new Material(Shader.Find(m_DepthOnlyWithObjectIdShader)); } depthMaterial = depthOnlyMaterialWithObjectId; } else { if (depthOnlyMaterial == null) { depthOnlyMaterial = new Material(Shader.Find(m_DepthOnlyShader)); } depthMaterial = depthOnlyMaterial; } depthMaterial.SetInt(m_CullPropertyId, (int)CullMode.Back); depthMaterial.DisableKeyword(ShaderParams.SKW_CUSTOM_DEPTH_ALPHA_TEST); drawingSettings.overrideMaterial = depthMaterial; } } var filter = new FilteringSettings(RenderQueueRange.opaque) { layerMask = BeautifySettings.outlineLayerMask }; RendererListParams listParams = new RendererListParams(renderingData.cullResults, drawingSettings, filter); passData.rendererListHandle = renderGraph.CreateRendererList(listParams); builder.UseRendererList(passData.rendererListHandle); builder.SetRenderFunc((PassData passData, UnsafeGraphContext context) => { CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); RenderTextureDescriptor depthDesc = passData.cameraData.cameraTargetDescriptor; depthDesc.width = passData.targetWidth; depthDesc.height = passData.targetHeight; depthDesc.msaaSamples = 1; depthDesc.colorFormat = BeautifySettings.outlineUseObjectId ? RenderTextureFormat.RFloat : RenderTextureFormat.Depth; depthDesc.depthBufferBits = 24; cmd.GetTemporaryRT(outlineDepthId, depthDesc, FilterMode.Point); if (BeautifySettings.outlineUseObjectId) { cmd.SetGlobalTexture(outlineObjectIdRT, outlineDepthId, RenderTextureSubElement.Color); cmd.SetGlobalTexture(outlineDepthRT, outlineDepthId, RenderTextureSubElement.Depth); } else { cmd.SetGlobalTexture(outlineDepthRT, outlineDepthId); } RenderTargetIdentifier rti = new RenderTargetIdentifier(outlineDepthId, 0, CubemapFace.Unknown, -1); cmd.SetRenderTarget(rti, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); cmd.ClearRenderTarget(true, BeautifySettings.outlineUseObjectId, Color.black); cmd.DrawRendererList(passData.rendererListHandle); }); } } #endif } class BeautifyClearColorTarget : ScriptableRenderPass { const string m_ProfilerTag = "Beautify Clear Color Target"; public BeautifyClearColorTarget () { renderPassEvent = RenderPassEvent.BeforeRenderingOpaques; } #if UNITY_2023_3_OR_NEWER [Obsolete] #endif public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) { CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0)); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } #if UNITY_2023_3_OR_NEWER public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { using (var builder = renderGraph.AddUnsafePass(m_ProfilerTag, out var passData)) { UniversalResourceData resourceData = frameData.Get(); builder.UseTexture(resourceData.activeColorTexture, AccessFlags.ReadWrite); builder.SetRenderFunc((PassData passData, UnsafeGraphContext context) => { CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0)); }); } } #endif } [SerializeField, HideInInspector] Shader shader; BeautifyRenderPass m_BeautifyRenderPass; BeautifyDoFTransparentMaskPass m_BeautifyDoFTransparentMaskPass; BeautifyBloomLumMaskPass m_BeautifyBloomLumMaskPass; BeautifyAnamorphicFlaresLumMaskPass m_BeautifyAnamorphicFlaresLumMaskPass; BeautifySharpenExclusionMaskPass m_BeautifySharpenExclusionMaskPass; BeautifyClearColorTarget m_BeautifyClearColorTarget; BeautifyOutlineDepthPrepass m_BeautifyOutlineDepthPrepass; [Tooltip("Note: this option is ignored if Direct Write To Camera option in Beautify volume inspector is enabled.")] public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingTransparents; [Tooltip("Allows Beautify to be executed even if camera has Post Processing option disabled.")] public bool ignorePostProcessingOption; #if ENABLE_VR && ENABLE_XR_MODULE [Tooltip("Ensures color buffer is cleared before rendering in XR. This option solves an issue with OpenXR and occlusion mesh which causes color bleeding when bloom is enabled.")] public bool clearXRColorBuffer; #endif [Tooltip("Specify which cameras can render Beautify effects")] public LayerMask cameraLayerMask = -1; public BeautifyStripSettings stripSettings; [Tooltip("Do not compile ACES tonemapping shader feature, reducing build time.")] public bool stripBeautifyTonemappingACES; [Tooltip("Do not compile ACES Fitted tonemapping shader feature, reducing build time.")] public bool stripBeautifyTonemappingACESFitted; [Tooltip("Do not compile AGX tonemapping shader feature, reducing build time.")] public bool stripBeautifyTonemappingAGX; [Tooltip("Do not compile sharpen shader feature, reducing build time.")] public bool stripBeautifySharpen; [Tooltip("Do not compile sharpen exclusion mask shader feature, reducing build time.")] public bool stripBeautifySharpenExclusionMask = true; [Tooltip("Do not compile dithering shader feature, reducing build time.")] public bool stripBeautifyDithering; [Tooltip("Do not compile edge antialiasing shader feature, reducing build time.")] public bool stripBeautifyEdgeAA; [Tooltip("Do not compile LUT shader feature, reducing build time.")] public bool stripBeautifyLUT; [Tooltip("Do not compile LUT 3D shader feature, reducing build time.")] public bool stripBeautifyLUT3D = true; [Tooltip("Do not compile daltonize, sepia or white balance shader feature, reducing build time.")] public bool stripBeautifyColorTweaks; [Tooltip("Do not compile Bloom, Anamorphic & Sun Flares shader features, reducing build time.")] public bool stripBeautifyBloom; [Tooltip("Do not compile Lens Dirt shader feature, reducing build time.")] public bool stripBeautifyLensDirt; [Tooltip("Do not compile Chromatic Aberration shader feature, reducing build time.")] public bool stripBeautifyChromaticAberration; [Tooltip("Do not compile Depth Of Field shader feature, reducing build time.")] public bool stripBeautifyDoF; [Tooltip("Do not compile Depth Of Field transparency support shader feature, reducing build time.")] public bool stripBeautifyDoFTransparentSupport = true; [Tooltip("Do not compile Purkinje Shift shader feature, reducing build time.")] public bool stripBeautifyEyeAdaptation = true; [Tooltip("Do not compile Purkinje Shift shader feature, reducing build time.")] public bool stripBeautifyPurkinje = true; [Tooltip("Do not compile Vignetting shader features, reducing build time.")] public bool stripBeautifyVignetting; [Tooltip("Do not compile Vignetting Mask shader feature, reducing build time.")] public bool stripBeautifyVignettingMask = true; [Tooltip("Do not compile Outline shader feature, reducing build time.")] public bool stripBeautifyOutline = true; [Tooltip("Do not compile Night Vision shader feature, reducing build time.")] public bool stripBeautifyNightVision = true; [Tooltip("Do not compile Thermal Vision shader feature, reducing build time.")] public bool stripBeautifyThermalVision = true; [Tooltip("Do not compile Frame shader features, reducing build time.")] public bool stripBeautifyFrame = true; [Tooltip("Do not compile Film Grain shader feature, reducing build time.")] public bool stripBeautifyFilmGrain = true; [Tooltip("Do not compile Unity Post Processing's Film Grain shader feature, reducing build time.")] public bool stripUnityFilmGrain; [Tooltip("Do not compile Unity Post Processing's Dithering shader feature, reducing build time.")] public bool stripUnityDithering; [Tooltip("Do not compile Unity Post Processing's Tonemapping shader feature, reducing build time.")] public bool stripUnityTonemapping; [Tooltip("Do not compile Unity Post Processing's Bloom shader feature, reducing build time.")] public bool stripUnityBloom; [Tooltip("Do not compile Unity Post Processing's Chromatic Aberration shader feature, reducing build time.")] public bool stripUnityChromaticAberration; [Tooltip("Do not compile Unity Post Processing's Screen Distortion features, reducing build time.")] public bool stripUnityDistortion; [Tooltip("Do not compile Unity Post Processing's debug variants, reducing build time.")] public bool stripUnityDebugVariants; public static bool installed; public static bool ignoringPostProcessingOption; #if UNITY_2023_3_OR_NEWER public static bool usingRenderGraph; static TextureHandle directWriteTextureHandle; #endif #if UNITY_EDITOR public static CameraType captureCameraType = CameraType.SceneView; public static bool requestScreenCapture; #endif void OnDisable () { if (m_BeautifyRenderPass != null) { m_BeautifyRenderPass.Cleanup(); } installed = false; } public override void Create () { name = "Beautify"; m_BeautifyRenderPass = new BeautifyRenderPass(); m_BeautifyBloomLumMaskPass = new BeautifyBloomLumMaskPass(); m_BeautifyAnamorphicFlaresLumMaskPass = new BeautifyAnamorphicFlaresLumMaskPass(); m_BeautifySharpenExclusionMaskPass = new BeautifySharpenExclusionMaskPass(); m_BeautifyDoFTransparentMaskPass = new BeautifyDoFTransparentMaskPass(); m_BeautifyOutlineDepthPrepass = new BeautifyOutlineDepthPrepass(); #if ENABLE_VR && ENABLE_XR_MODULE m_BeautifyClearColorTarget = new BeautifyClearColorTarget(); #endif shader = Shader.Find("Hidden/Kronnect/Beautify"); #if UNITY_EDITOR SetStripShaderKeywords(); #endif } #if UNITY_2022_1_OR_NEWER #if UNITY_6000_2_OR_NEWER [System.Obsolete] #endif public override void SetupRenderPasses(ScriptableRenderer renderer, in RenderingData renderingData) { CameraData cameraData = renderingData.cameraData; Camera cam = cameraData.camera; if ((cameraLayerMask & (1 << cam.gameObject.layer)) == 0) return; if (cam.targetTexture != null && cam.targetTexture.format == RenderTextureFormat.Depth) return; // ignore depth pre-pass cams! m_BeautifyRenderPass.SetupRenderTargets(renderer); m_BeautifyBloomLumMaskPass.SetupRenderTargets(renderer); m_BeautifyAnamorphicFlaresLumMaskPass.SetupRenderTargets(renderer); m_BeautifySharpenExclusionMaskPass.SetupRenderTargets(renderer); } #endif public override void AddRenderPasses (ScriptableRenderer renderer, ref RenderingData renderingData) { installed = true; ignoringPostProcessingOption = ignorePostProcessingOption; #if UNITY_EDITOR // Check if shader compilation or preparation is happening in background if (UnityEditor.ShaderUtil.anythingCompiling) { return; } #endif #if UNITY_2023_3_OR_NEWER var renderGraphSettings = GraphicsSettings.GetRenderPipelineSettings(); usingRenderGraph = !renderGraphSettings.enableRenderCompatibilityMode; #endif if (ignorePostProcessingOption || renderingData.cameraData.postProcessEnabled) { CameraData cameraData = renderingData.cameraData; Camera cam = cameraData.camera; if ((cameraLayerMask & (1 << cam.gameObject.layer)) == 0) return; if (cam.targetTexture != null && cam.targetTexture.format == RenderTextureFormat.Depth) return; // ignore depth pre-pass cams! if (m_BeautifyRenderPass.Setup(shader, renderer, renderingData, renderPassEvent, ignorePostProcessingOption)) { m_BeautifyRenderPass.UpdateMaterialProperties(cam); if (BeautifySettings.bloomExcludeMask != 0) { renderer.EnqueuePass(m_BeautifyBloomLumMaskPass); } if (BeautifySettings.anamorphicFlaresExcludeMask != 0 && BeautifySettings.anamorphicFlaresExcludeMask != BeautifySettings.bloomExcludeMask) { renderer.EnqueuePass(m_BeautifyAnamorphicFlaresLumMaskPass); } if (BeautifySettings.sharpenExclusionMask != 0) { renderer.EnqueuePass(m_BeautifySharpenExclusionMaskPass); } if (BeautifySettings.dofTransparentSupport || BeautifySettings.dofAlphaTestSupport) { if (cam.cameraType == CameraType.Game) { renderer.EnqueuePass(m_BeautifyDoFTransparentMaskPass); } } if (BeautifySettings.outlineDepthPrepass) { renderer.EnqueuePass(m_BeautifyOutlineDepthPrepass); } renderer.EnqueuePass(m_BeautifyRenderPass); #if ENABLE_VR && ENABLE_XR_MODULE if (clearXRColorBuffer && renderingData.cameraData.xrRendering) { renderer.EnqueuePass(m_BeautifyClearColorTarget); } #endif } } } #if UNITY_EDITOR public const string PLAYER_PREF_KEYNAME = "BeautifyStripKeywordSet"; [System.NonSerialized] private BeautifyStripSettings m_InternalStripSettings; public BeautifyStripSettings settings { get { if (stripSettings != null) return stripSettings; if (m_InternalStripSettings == null) UpdateInternalStripSettings(); return m_InternalStripSettings; } } public void UpdateInternalStripSettings() { if (m_InternalStripSettings == null) m_InternalStripSettings = ScriptableObject.CreateInstance(); m_InternalStripSettings.stripBeautifyTonemappingACES = stripBeautifyTonemappingACES; m_InternalStripSettings.stripBeautifyTonemappingACESFitted = stripBeautifyTonemappingACESFitted; m_InternalStripSettings.stripBeautifyTonemappingAGX = stripBeautifyTonemappingAGX; m_InternalStripSettings.stripBeautifySharpen = stripBeautifySharpen; m_InternalStripSettings.stripBeautifySharpenExclusionMask = stripBeautifySharpenExclusionMask; m_InternalStripSettings.stripBeautifyDithering = stripBeautifyDithering; m_InternalStripSettings.stripBeautifyEdgeAA = stripBeautifyEdgeAA; m_InternalStripSettings.stripBeautifyLUT = stripBeautifyLUT; m_InternalStripSettings.stripBeautifyLUT3D = stripBeautifyLUT3D; m_InternalStripSettings.stripBeautifyColorTweaks = stripBeautifyColorTweaks; m_InternalStripSettings.stripBeautifyBloom = stripBeautifyBloom; m_InternalStripSettings.stripBeautifyLensDirt = stripBeautifyLensDirt; m_InternalStripSettings.stripBeautifyChromaticAberration = stripBeautifyChromaticAberration; m_InternalStripSettings.stripBeautifyDoF = stripBeautifyDoF; m_InternalStripSettings.stripBeautifyDoFTransparentSupport = stripBeautifyDoFTransparentSupport; m_InternalStripSettings.stripBeautifyEyeAdaptation = stripBeautifyEyeAdaptation; m_InternalStripSettings.stripBeautifyPurkinje = stripBeautifyPurkinje; m_InternalStripSettings.stripBeautifyVignetting = stripBeautifyVignetting; m_InternalStripSettings.stripBeautifyVignettingMask = stripBeautifyVignettingMask; m_InternalStripSettings.stripBeautifyOutline = stripBeautifyOutline; m_InternalStripSettings.stripBeautifyNightVision = stripBeautifyNightVision; m_InternalStripSettings.stripBeautifyThermalVision = stripBeautifyThermalVision; m_InternalStripSettings.stripBeautifyFrame = stripBeautifyFrame; m_InternalStripSettings.stripBeautifyFilmGrain = stripBeautifyFilmGrain; m_InternalStripSettings.stripUnityFilmGrain = stripUnityFilmGrain; m_InternalStripSettings.stripUnityDithering = stripUnityDithering; m_InternalStripSettings.stripUnityTonemapping = stripUnityTonemapping; m_InternalStripSettings.stripUnityBloom = stripUnityBloom; m_InternalStripSettings.stripUnityChromaticAberration = stripUnityChromaticAberration; m_InternalStripSettings.stripUnityDistortion = stripUnityDistortion; m_InternalStripSettings.stripUnityDebugVariants = stripUnityDebugVariants; } public void SyncInternalToLegacy() { if (m_InternalStripSettings == null) return; stripBeautifyTonemappingACES = m_InternalStripSettings.stripBeautifyTonemappingACES; stripBeautifyTonemappingACESFitted = m_InternalStripSettings.stripBeautifyTonemappingACESFitted; stripBeautifyTonemappingAGX = m_InternalStripSettings.stripBeautifyTonemappingAGX; stripBeautifySharpen = m_InternalStripSettings.stripBeautifySharpen; stripBeautifySharpenExclusionMask = m_InternalStripSettings.stripBeautifySharpenExclusionMask; stripBeautifyDithering = m_InternalStripSettings.stripBeautifyDithering; stripBeautifyEdgeAA = m_InternalStripSettings.stripBeautifyEdgeAA; stripBeautifyLUT = m_InternalStripSettings.stripBeautifyLUT; stripBeautifyLUT3D = m_InternalStripSettings.stripBeautifyLUT3D; stripBeautifyColorTweaks = m_InternalStripSettings.stripBeautifyColorTweaks; stripBeautifyBloom = m_InternalStripSettings.stripBeautifyBloom; stripBeautifyLensDirt = m_InternalStripSettings.stripBeautifyLensDirt; stripBeautifyChromaticAberration = m_InternalStripSettings.stripBeautifyChromaticAberration; stripBeautifyDoF = m_InternalStripSettings.stripBeautifyDoF; stripBeautifyDoFTransparentSupport = m_InternalStripSettings.stripBeautifyDoFTransparentSupport; stripBeautifyEyeAdaptation = m_InternalStripSettings.stripBeautifyEyeAdaptation; stripBeautifyPurkinje = m_InternalStripSettings.stripBeautifyPurkinje; stripBeautifyVignetting = m_InternalStripSettings.stripBeautifyVignetting; stripBeautifyVignettingMask = m_InternalStripSettings.stripBeautifyVignettingMask; stripBeautifyOutline = m_InternalStripSettings.stripBeautifyOutline; stripBeautifyNightVision = m_InternalStripSettings.stripBeautifyNightVision; stripBeautifyThermalVision = m_InternalStripSettings.stripBeautifyThermalVision; stripBeautifyFrame = m_InternalStripSettings.stripBeautifyFrame; stripBeautifyFilmGrain = m_InternalStripSettings.stripBeautifyFilmGrain; stripUnityFilmGrain = m_InternalStripSettings.stripUnityFilmGrain; stripUnityDithering = m_InternalStripSettings.stripUnityDithering; stripUnityTonemapping = m_InternalStripSettings.stripUnityTonemapping; stripUnityBloom = m_InternalStripSettings.stripUnityBloom; stripUnityChromaticAberration = m_InternalStripSettings.stripUnityChromaticAberration; stripUnityDistortion = m_InternalStripSettings.stripUnityDistortion; stripUnityDebugVariants = m_InternalStripSettings.stripUnityDebugVariants; } public void SetStripShaderKeywords () { if (Application.isPlaying) return; BeautifyStripSettings settings; if (stripSettings != null) { settings = stripSettings; } else { if (m_InternalStripSettings == null) UpdateInternalStripSettings(); settings = m_InternalStripSettings; } System.Text.StringBuilder sb = new System.Text.StringBuilder(); if (settings.stripBeautifyEdgeAA) { sb.Append(ShaderParams.SKW_EDGE_ANTIALIASING); sb.Append(ShaderParams.SKW_EDGE_ANTIALIASING_DOF); } if (settings.stripBeautifyBloom) { sb.Append(ShaderParams.SKW_BLOOM); sb.Append(ShaderParams.SKW_BLOOM_USE_DEPTH); sb.Append(ShaderParams.SKW_BLOOM_USE_LAYER); sb.Append(ShaderParams.SKW_BLOOM_USE_LAYER_INCLUSION); sb.Append(ShaderParams.SKW_BLOOM_PROP_THRESHOLDING); sb.Append(ShaderParams.SKW_ANAMORPHIC_FLARES_USE_DEPTH); sb.Append(ShaderParams.SKW_ANAMORPHIC_FLARES_USE_LAYER); sb.Append(ShaderParams.SKW_ANAMORPHIC_FLARES_USE_LAYER_INCLUSION); sb.Append(ShaderParams.SKW_ANAMORPHIC_PROP_THRESHOLDING); sb.Append(ShaderParams.SKW_SUN_FLARES_USE_GHOSTS); sb.Append(ShaderParams.SKW_SUN_FLARES_OCCLUSION_INIT); sb.Append(ShaderParams.SKW_SUN_FLARES_OCCLUSION_SIMPLE); sb.Append(ShaderParams.SKW_SUN_FLARES_OCCLUSION_SMOOTH); } if (settings.stripBeautifyDoF) { sb.Append(ShaderParams.SKW_DEPTH_OF_FIELD); sb.Append(ShaderParams.SKW_DEPTH_OF_FIELD_TRANSPARENT); sb.Append(ShaderParams.SKW_EDGE_ANTIALIASING_DOF); } else if (settings.stripBeautifyDoFTransparentSupport) { sb.Append(ShaderParams.SKW_DEPTH_OF_FIELD_TRANSPARENT); } if (settings.stripBeautifyLensDirt) { sb.Append(ShaderParams.SKW_DIRT); } if (settings.stripBeautifyLUT3D) { sb.Append(ShaderParams.SKW_LUT3D); } if (settings.stripBeautifyLUT) { sb.Append(ShaderParams.SKW_LUT); } if (settings.stripBeautifyOutline) { sb.Append(ShaderParams.SKW_OUTLINE); sb.Append(ShaderParams.SKW_OUTLINE_CUSTOM_DEPTH); sb.Append(ShaderParams.SKW_OUTLINE_OBJECT_ID); sb.Append(ShaderParams.SKW_OUTLINE_MIN_SEPARATION); sb.Append(ShaderParams.SKW_OUTLINE_OUTER_ONLY); sb.Append(ShaderParams.SKW_OUTLINE_DEPTH_FADE); } if (settings.stripBeautifyNightVision) { sb.Append(ShaderParams.SKW_NIGHT_VISION); } if (settings.stripBeautifyThermalVision) { sb.Append(ShaderParams.SKW_THERMAL_VISION); } if (settings.stripBeautifyColorTweaks) { sb.Append(ShaderParams.SKW_COLOR_TWEAKS); } if (settings.stripBeautifyPurkinje) { sb.Append(ShaderParams.SKW_PURKINJE); } if (settings.stripBeautifyTonemappingACES) { sb.Append(ShaderParams.SKW_TONEMAP_ACES); } if (settings.stripBeautifyTonemappingACESFitted) { sb.Append(ShaderParams.SKW_TONEMAP_ACES_FITTED); } if (settings.stripBeautifyTonemappingAGX) { sb.Append(ShaderParams.SKW_TONEMAP_AGX); } if (settings.stripBeautifyDithering) { sb.Append(ShaderParams.SKW_DITHER); } if (settings.stripBeautifySharpen) { sb.Append(ShaderParams.SKW_SHARPEN); sb.Append(ShaderParams.SKW_SHARPEN_EXCLUSION_MASK); } else if (settings.stripBeautifySharpenExclusionMask) { sb.Append(ShaderParams.SKW_SHARPEN_EXCLUSION_MASK); } if (settings.stripBeautifyEyeAdaptation) { sb.Append(ShaderParams.SKW_EYE_ADAPTATION); sb.Append(ShaderParams.SKW_EA_USE_DEPTH); sb.Append(ShaderParams.SKW_EA_USE_MASK); } if (settings.stripBeautifyChromaticAberration) { sb.Append(ShaderParams.SKW_CHROMATIC_ABERRATION); } if (settings.stripBeautifyVignetting) { sb.Append(ShaderParams.SKW_VIGNETTING); sb.Append(ShaderParams.SKW_VIGNETTING_MASK); } else if (settings.stripBeautifyVignettingMask) { sb.Append(ShaderParams.SKW_VIGNETTING_MASK); } if (settings.stripBeautifyFrame) { sb.Append(ShaderParams.SKW_FRAME); } if (settings.stripBeautifyFilmGrain) { sb.Append(ShaderParams.SKW_FILM_GRAIN); } if (settings.stripUnityBloom) { sb.Append("_BLOOM_LQ _BLOOM_HQ _BLOOM_LQ_DIRT _BLOOM_HQ_DIRT"); } if (settings.stripUnityChromaticAberration) { sb.Append("_CHROMATIC_ABERRATION"); } if (settings.stripUnityDistortion) { sb.Append("_DISTORTION"); } if (settings.stripUnityFilmGrain) { sb.Append("_FILM_GRAIN"); } if (settings.stripUnityDithering) { sb.Append("_DITHERING"); } if (settings.stripUnityTonemapping) { sb.Append("_TONEMAP_ACES _TONEMAP_NEUTRAL"); } if (settings.stripUnityDebugVariants) { sb.Append("DEBUG_DISPLAY"); } PlayerPrefs.SetString(PLAYER_PREF_KEYNAME, sb.ToString()); } public static void StripBeautifyFeatures () { var asset = UniversalRenderPipeline.asset; if (asset == null) return; try { if (asset.scriptableRenderer is not UniversalRenderer renderer) return; var rendererFeaturesField = typeof(ScriptableRenderer) .GetField("m_RendererFeatures", BindingFlags.NonPublic | BindingFlags.Instance); if (rendererFeaturesField == null) return; if (rendererFeaturesField.GetValue(renderer) is not List rendererFeatures) return; foreach (var feature in rendererFeatures) { if (feature is BeautifyRendererFeature beautifyFeature) { beautifyFeature.SetStripShaderKeywords(); return; } } } catch { } } #endif } }