internal bool Setup(ScreenSpaceAmbientOcclusionSettings featureSettings, ScriptableRenderer renderer) { this.renderPassEvent = featureSettings.AfterOpaque ? RenderPassEvent.AfterRenderingOpaques : RenderPassEvent.AfterRenderingGbuffer; m_Renderer = renderer; m_CurrentSettings = featureSettings; ScreenSpaceAmbientOcclusionSettings.DepthSource source = this.isRendererDeferred ? ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals : m_CurrentSettings.Source; switch (source) { case ScreenSpaceAmbientOcclusionSettings.DepthSource.Depth: ConfigureInput(ScriptableRenderPassInput.Depth); break; case ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals: ConfigureInput(ScriptableRenderPassInput.Normal); // need depthNormal prepass for forward-only geometry break; default: throw new ArgumentOutOfRangeException(); } return(material != null && m_CurrentSettings.Intensity > 0.0f && m_CurrentSettings.Radius > 0.0f && m_CurrentSettings.SampleCount > 0); }
/// <inheritdoc/> public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { RenderTextureDescriptor cameraTargetDescriptor = renderingData.cameraData.cameraTargetDescriptor; int downsampleDivider = m_CurrentSettings.Downsample ? 2 : 1; // Update SSAO parameters in the material Vector4 ssaoParams = new Vector4( m_CurrentSettings.Intensity, // Intensity m_CurrentSettings.Radius, // Radius 1.0f / downsampleDivider, // Downsampling m_CurrentSettings.SampleCount // Sample count ); m_Material.SetVector(s_SSAOParamsID, ssaoParams); #if ENABLE_VR && ENABLE_XR_MODULE int eyeCount = renderingData.cameraData.xr.enabled && renderingData.cameraData.xr.singlePassEnabled ? 2 : 1; #else int eyeCount = 1; #endif for (int eyeIndex = 0; eyeIndex < eyeCount; eyeIndex++) { Matrix4x4 view = renderingData.cameraData.GetViewMatrix(eyeIndex); Matrix4x4 proj = renderingData.cameraData.GetProjectionMatrix(eyeIndex); m_CameraViewProjections[eyeIndex] = proj * view; // camera view space without translation, used by SSAO.hlsl ReconstructViewPos() to calculate view vector. Matrix4x4 cview = view; cview.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); Matrix4x4 cviewProj = proj * cview; Matrix4x4 cviewProjInv = cviewProj.inverse; Vector4 topLeftCorner = cviewProjInv.MultiplyPoint(new Vector4(-1, 1, -1, 1)); Vector4 topRightCorner = cviewProjInv.MultiplyPoint(new Vector4(1, 1, -1, 1)); Vector4 bottomLeftCorner = cviewProjInv.MultiplyPoint(new Vector4(-1, -1, -1, 1)); Vector4 farCentre = cviewProjInv.MultiplyPoint(new Vector4(0, 0, 1, 1)); m_CameraTopLeftCorner[eyeIndex] = topLeftCorner; m_CameraXExtent[eyeIndex] = topRightCorner - topLeftCorner; m_CameraYExtent[eyeIndex] = bottomLeftCorner - topLeftCorner; m_CameraZExtent[eyeIndex] = farCentre; } m_Material.SetVector(s_ProjectionParams2ID, new Vector4(1.0f / renderingData.cameraData.camera.nearClipPlane, 0.0f, 0.0f, 0.0f)); m_Material.SetMatrixArray(s_CameraViewProjectionsID, m_CameraViewProjections); m_Material.SetVectorArray(s_CameraViewTopLeftCornerID, m_CameraTopLeftCorner); m_Material.SetVectorArray(s_CameraViewXExtentID, m_CameraXExtent); m_Material.SetVectorArray(s_CameraViewYExtentID, m_CameraYExtent); m_Material.SetVectorArray(s_CameraViewZExtentID, m_CameraZExtent); // Update keywords CoreUtils.SetKeyword(m_Material, k_OrthographicCameraKeyword, renderingData.cameraData.camera.orthographic); ScreenSpaceAmbientOcclusionSettings.DepthSource source = this.isRendererDeferred ? ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals : m_CurrentSettings.Source; if (source == ScreenSpaceAmbientOcclusionSettings.DepthSource.Depth) { switch (m_CurrentSettings.NormalSamples) { case ScreenSpaceAmbientOcclusionSettings.NormalQuality.Low: CoreUtils.SetKeyword(m_Material, k_NormalReconstructionLowKeyword, true); CoreUtils.SetKeyword(m_Material, k_NormalReconstructionMediumKeyword, false); CoreUtils.SetKeyword(m_Material, k_NormalReconstructionHighKeyword, false); break; case ScreenSpaceAmbientOcclusionSettings.NormalQuality.Medium: CoreUtils.SetKeyword(m_Material, k_NormalReconstructionLowKeyword, false); CoreUtils.SetKeyword(m_Material, k_NormalReconstructionMediumKeyword, true); CoreUtils.SetKeyword(m_Material, k_NormalReconstructionHighKeyword, false); break; case ScreenSpaceAmbientOcclusionSettings.NormalQuality.High: CoreUtils.SetKeyword(m_Material, k_NormalReconstructionLowKeyword, false); CoreUtils.SetKeyword(m_Material, k_NormalReconstructionMediumKeyword, false); CoreUtils.SetKeyword(m_Material, k_NormalReconstructionHighKeyword, true); break; default: throw new ArgumentOutOfRangeException(); } } switch (source) { case ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals: CoreUtils.SetKeyword(m_Material, k_SourceDepthKeyword, false); CoreUtils.SetKeyword(m_Material, k_SourceDepthNormalsKeyword, true); break; default: CoreUtils.SetKeyword(m_Material, k_SourceDepthKeyword, true); CoreUtils.SetKeyword(m_Material, k_SourceDepthNormalsKeyword, false); break; } // Set up the descriptors RenderTextureDescriptor descriptor = cameraTargetDescriptor; descriptor.msaaSamples = 1; descriptor.depthBufferBits = 0; m_AOPassDescriptor = descriptor; m_AOPassDescriptor.width /= downsampleDivider; m_AOPassDescriptor.height /= downsampleDivider; m_AOPassDescriptor.colorFormat = RenderTextureFormat.ARGB32; m_BlurPassesDescriptor = descriptor; m_BlurPassesDescriptor.colorFormat = RenderTextureFormat.ARGB32; m_FinalDescriptor = descriptor; m_FinalDescriptor.colorFormat = m_SupportsR8RenderTextureFormat ? RenderTextureFormat.R8 : RenderTextureFormat.ARGB32; // Get temporary render textures cmd.GetTemporaryRT(s_SSAOTexture1ID, m_AOPassDescriptor, FilterMode.Bilinear); cmd.GetTemporaryRT(s_SSAOTexture2ID, m_BlurPassesDescriptor, FilterMode.Bilinear); cmd.GetTemporaryRT(s_SSAOTexture3ID, m_BlurPassesDescriptor, FilterMode.Bilinear); cmd.GetTemporaryRT(s_SSAOTextureFinalID, m_FinalDescriptor, FilterMode.Bilinear); // Configure targets and clear color ConfigureTarget(m_CurrentSettings.AfterOpaque ? m_Renderer.cameraColorTarget : s_SSAOTexture2ID); ConfigureClear(ClearFlag.None, Color.white); }