#if ENVIRO_LWRP && ENVIRO_HD namespace UnityEngine.Rendering.LWRP { internal class EnviroDistanceBlurPass : UnityEngine.Rendering.Universal.ScriptableRenderPass { private Camera myCam; public Material blitMaterial = null; private Material blitThrough; private UnityEngine.Rendering.Universal.ScriptableRenderer renderer { get; set; } private UnityEngine.Rendering.Universal.RenderTargetHandle destination { get; set; } #region Blur Var /////////////////// Blur ////////////////////// private const int kMaxIterations = 16; private RenderTexture[] _blurBuffer1 = new RenderTexture[kMaxIterations]; private RenderTexture[] _blurBuffer2 = new RenderTexture[kMaxIterations]; private Texture2D distributionTexture; public float thresholdGamma { get { return Mathf.Max(0f, 0); } } public float thresholdLinear { get { return Mathf.GammaToLinearSpace(thresholdGamma); } } #endregion public void CustomBlit(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, Material mat) { cmd.SetGlobalTexture("_MainTex", source); cmd.SetRenderTarget(target, 0, CubemapFace.Unknown, -1); cmd.DrawMesh(UnityEngine.Rendering.Universal.RenderingUtils.fullscreenMesh, Matrix4x4.identity, mat); } public void CustomBlit(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, Material mat, int pass) { cmd.SetGlobalTexture("_MainTex", source); cmd.SetRenderTarget(target, 0, CubemapFace.Unknown, -1); cmd.DrawMesh(UnityEngine.Rendering.Universal.RenderingUtils.fullscreenMesh, Matrix4x4.identity, mat,0,pass); } public void CustomBlit(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target) { if(blitThrough == null) blitThrough = new Material(Shader.Find("Hidden/EnviroBlitThrough")); cmd.SetGlobalTexture("_MainTex", source); cmd.SetRenderTarget(target, 0, CubemapFace.Unknown, -1); cmd.DrawMesh(UnityEngine.Rendering.Universal.RenderingUtils.fullscreenMesh, Matrix4x4.identity, blitThrough); } public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { ConfigureTarget(renderer.cameraColorTarget); } /// /// Create the CopyColorPass /// public EnviroDistanceBlurPass(UnityEngine.Rendering.Universal.RenderPassEvent renderPassEvent, Material blitMaterial, Texture2D distributionTexture) { this.renderPassEvent = renderPassEvent; this.blitMaterial = blitMaterial; this.distributionTexture = distributionTexture; } public void Setup(Camera myCam, UnityEngine.Rendering.Universal.ScriptableRenderer renderer, UnityEngine.Rendering.Universal.RenderTargetHandle destination) { this.myCam = myCam; this.renderer = renderer; this.destination = destination; } private void UpdateMatrix(UnityEngine.Rendering.Universal.RenderingData renderingData, Material mat) { if (UnityEngine.XR.XRSettings.enabled) { // Both stereo eye inverse view matrices Matrix4x4 left_world_from_view = myCam.GetStereoViewMatrix(Camera.StereoscopicEye.Left).inverse; Matrix4x4 right_world_from_view = myCam.GetStereoViewMatrix(Camera.StereoscopicEye.Right).inverse; // Both stereo eye inverse projection matrices, plumbed through GetGPUProjectionMatrix to compensate for render texture Matrix4x4 left_screen_from_view = myCam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); Matrix4x4 right_screen_from_view = myCam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); Matrix4x4 left_view_from_screen = GL.GetGPUProjectionMatrix(left_screen_from_view, true).inverse; Matrix4x4 right_view_from_screen = GL.GetGPUProjectionMatrix(right_screen_from_view, true).inverse; // Negate [1,1] to reflect Unity's CBuffer state if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore && SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3) { left_view_from_screen[1, 1] *= -1; right_view_from_screen[1, 1] *= -1; } mat.SetMatrix("_LeftWorldFromView", left_world_from_view); mat.SetMatrix("_RightWorldFromView", right_world_from_view); mat.SetMatrix("_LeftViewFromScreen", left_view_from_screen); mat.SetMatrix("_RightViewFromScreen", right_view_from_screen); } else { Matrix4x4 left_world_from_view = renderingData.cameraData.GetViewMatrix().inverse; // Inverse projection matrices, plumbed through GetGPUProjectionMatrix to compensate for render texture Matrix4x4 screen_from_view = renderingData.cameraData.GetProjectionMatrix(); Matrix4x4 left_view_from_screen = GL.GetGPUProjectionMatrix(screen_from_view, true).inverse; // Negate [1,1] to reflect Unity's CBuffer state if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore && SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3) left_view_from_screen[1, 1] *= -1; // Store matrices mat.SetMatrix("_LeftWorldFromView", left_world_from_view); mat.SetMatrix("_LeftViewFromScreen", left_view_from_screen); } } /// public override void Execute(ScriptableRenderContext context, ref UnityEngine.Rendering.Universal.RenderingData renderingData) { CommandBuffer cmd = CommandBufferPool.Get("Distance Blur"); // source texture size var tw = renderingData.cameraData.cameraTargetDescriptor.width; var th = renderingData.cameraData.cameraTargetDescriptor.height; // halve the texture size for the low quality mode if (!EnviroSky.instance.distanceBlurSettings.highQuality) { tw /= 2; th /= 2; } if(blitMaterial == null) blitMaterial = new Material(Shader.Find("Hidden/EnviroDistanceBlur")); UpdateMatrix(renderingData,blitMaterial); blitMaterial.EnableKeyword("ENVIROURP"); blitMaterial.SetTexture("_DistTex", distributionTexture); blitMaterial.SetFloat("_Distance", EnviroSky.instance.blurDistance); blitMaterial.SetFloat("_Radius", EnviroSky.instance.distanceBlurSettings.radius); // determine the iteration count var logh = Mathf.Log(th, 2) + EnviroSky.instance.distanceBlurSettings.radius - 8; var logh_i = (int)logh; var iterations = Mathf.Clamp(logh_i, 1, kMaxIterations); // update the shader properties var lthresh = thresholdLinear; blitMaterial.SetFloat("_Threshold", lthresh); var knee = lthresh * 0.5f + 1e-5f; var curve = new Vector3(lthresh - knee, knee * 2, 0.25f / knee); blitMaterial.SetVector("_Curve", curve); var pfo = !EnviroSky.instance.distanceBlurSettings.highQuality && EnviroSky.instance.distanceBlurSettings.antiFlicker; blitMaterial.SetFloat("_PrefilterOffs", pfo ? -0.5f : 0.0f); blitMaterial.SetFloat("_SampleScale", 0.5f + logh - logh_i); blitMaterial.SetFloat("_Intensity", EnviroSky.instance.blurIntensity); blitMaterial.SetFloat("_SkyBlurring", EnviroSky.instance.blurSkyIntensity); float width = 1 / renderingData.cameraData.cameraTargetDescriptor.width; float height = 1 / renderingData.cameraData.cameraTargetDescriptor.height; blitMaterial.SetVector("_MainTex_TexelSize",new Vector4(width, height, renderingData.cameraData.cameraTargetDescriptor.width, renderingData.cameraData.cameraTargetDescriptor.height)); // prefilter pass RenderTextureDescriptor renderDescriptor = renderingData.cameraData.cameraTargetDescriptor; renderDescriptor.width = tw; renderDescriptor.height = th; //renderDescriptor.graphicsFormat = Experimental.Rendering.GraphicsFormat.R32G32B32A32_SFloat; renderDescriptor.depthBufferBits = 0; var prefiltered = RenderTexture.GetTemporary(renderDescriptor); var pass = EnviroSky.instance.distanceBlurSettings.antiFlicker ? 1 : 0; CustomBlit(cmd, renderer.cameraColorTarget, prefiltered, blitMaterial, pass); // construct a mip pyramid var last = prefiltered; for (var level = 0; level < iterations; level++) { RenderTextureDescriptor lastDescriptor = last.descriptor; lastDescriptor.width = lastDescriptor.width / 2; lastDescriptor.height = lastDescriptor.height / 2; _blurBuffer1[level] = RenderTexture.GetTemporary(lastDescriptor); pass = (level == 0) ? (EnviroSky.instance.distanceBlurSettings.antiFlicker ? 3 : 2) : 4; CustomBlit(cmd, last, _blurBuffer1[level], blitMaterial, pass); last = _blurBuffer1[level]; } // upsample and combine loop for (var level = iterations - 2; level >= 0; level--) { var basetex = _blurBuffer1[level]; blitMaterial.SetTexture("_BaseTex", basetex); RenderTextureDescriptor baseDescriptor = basetex.descriptor; _blurBuffer2[level] = RenderTexture.GetTemporary(baseDescriptor); pass = EnviroSky.instance.distanceBlurSettings.highQuality ? 6 : 5; CustomBlit(cmd, last, _blurBuffer2[level], blitMaterial, pass); last = _blurBuffer2[level]; } // finish process RenderTexture sourceRT = RenderTexture.GetTemporary(renderDescriptor); CustomBlit(cmd, renderer.cameraColorTarget, sourceRT); blitMaterial.SetTexture("_BaseTex", sourceRT); cmd.SetGlobalTexture("_BaseTex", sourceRT); pass = EnviroSky.instance.distanceBlurSettings.highQuality ? 8 : 7; CustomBlit(cmd, last, renderer.cameraColorTarget, blitMaterial, pass); // release the temporary buffers for (var i = 0; i < kMaxIterations; i++) { if (_blurBuffer1[i] != null) RenderTexture.ReleaseTemporary(_blurBuffer1[i]); if (_blurBuffer2[i] != null) RenderTexture.ReleaseTemporary(_blurBuffer2[i]); _blurBuffer1[i] = null; _blurBuffer2[i] = null; } RenderTexture.ReleaseTemporary(prefiltered); RenderTexture.ReleaseTemporary(sourceRT); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } /// public override void FrameCleanup(CommandBuffer cmd) { //if (destination == RenderTargetHandle.CameraTarget) // cmd.ReleaseTemporaryRT(m_TemporaryColorTexture.id); } } } #endif