public MyPipeline(bool dynamicBatching, bool instancing, int shadowMapSize, float shadowDistance, int shadowCascades, Vector3 shadowCascadeSplit, MyPostProcessingStack defaultStack, float renderScale) { GraphicsSettings.lightsUseLinearIntensity = true; if (SystemInfo.usesReversedZBuffer) { worldToShadowCascadeMatrices[4].m33 = 1f; } if (dynamicBatching) { drawFlags = DrawRendererFlags.EnableDynamicBatching; } if (instancing) { drawFlags = DrawRendererFlags.EnableInstancing; } this.shadowMapSize = shadowMapSize; this.shadowDistance = shadowDistance; this.shadowCascades = shadowCascades; this.shadowCascadeSplit = shadowCascadeSplit; this.defaultStack = defaultStack; this.renderScale = renderScale; }
public MyPipeline(bool dynamicBatching, bool instanceing, MyPostProcessingStack defaultStack, Texture2D ditherTexture, float ditherAnimationSpeed, int shadowMapSize, float shadowDistance, float shadowFadeRange, int shadowCascades, Vector3 shadowCascadeSplit, float renderScale, int msaaSamples, bool allowHDR) { GraphicsSettings.lightsUseLinearIntensity = true; if (SystemInfo.usesReversedZBuffer) { worldToShadowCascadeMatrices[4].m33 = 1f; } if (dynamicBatching) { drawFlags = DrawRendererFlags.EnableDynamicBatching; } if (instanceing) { drawFlags |= DrawRendererFlags.EnableInstancing; } this.ditherTexture = ditherTexture; if (ditherAnimationSpeed > 0f && Application.isPlaying) { ConfigureDitherAnimation(ditherAnimationSpeed); } this.shadowMapSize = shadowMapSize; this.shadowDistance = shadowDistance; globalShadowData.y = 1f / shadowFadeRange; this.shadowCascades = shadowCascades; this.shadowCascadeSplit = shadowCascadeSplit; this.defaultStack = defaultStack; this.renderScale = renderScale; this.allowHDR = allowHDR; QualitySettings.antiAliasing = msaaSamples; this.msaaSamples = Mathf.Max(QualitySettings.antiAliasing, 1); #if UNITY_EDITOR Lightmapping.SetDelegate(lightmappingLightsDelegate); #endif }
public MyPipeline(bool dynamicBatching, bool instancing, MyPostProcessingStack _defaultStack, Texture2D _ditherTexture, float _ditherAnimationSpeed, int _shadowMapSize, float _shadowDistance , float _shadowFadeRange, int _shadowCascades, Vector3 _shadowCascadeSplit, float _renderScale , int _msaaSamples, bool _allowHDR, bool _syncGameCamera) { //Unity 认为光的强度是在伽马空间中定义的,即使我们是在线性空间中工作。 GraphicsSettings.lightsUseLinearIntensity = true; //如果Z相反 阴影的z最远是1 if (SystemInfo.usesReversedZBuffer) { worldToShadowCascadeMatrices[4].m33 = 1f; } if (dynamicBatching) { drawFlags = DrawRendererFlags.EnableDynamicBatching; } ditherTexture = _ditherTexture; if (_ditherAnimationSpeed > 0f) { ConfigureDitherAnimation(_ditherAnimationSpeed); } if (instancing) { drawFlags |= DrawRendererFlags.EnableInstancing; } defaultStack = _defaultStack; shadowMapSize = _shadowMapSize; shadowDistance = _shadowDistance; globalShadowData.y = 1f / _shadowFadeRange; shadowCascades = _shadowCascades; shadowCascadeSplit = _shadowCascadeSplit; renderScale = _renderScale; //设置msaa 如果硬件不支持 则为自动回退为1 QualitySettings.antiAliasing = _msaaSamples; msaaSamples = Mathf.Max(QualitySettings.antiAliasing, 1); allowHDR = _allowHDR; #if UNITY_EDITOR if (SceneView.onSceneGUIDelegate != null) { SceneView.onSceneGUIDelegate -= OnSceneView; } if (_syncGameCamera) { SceneView.onSceneGUIDelegate += OnSceneView; } #endif #if UNITY_EDITOR Lightmapping.SetDelegate(lightmappingLightDelegate); #endif }
public MyPipeline(bool dynamicBatching, bool instancing, MyPostProcessingStack defaultStack, int shadowMapSize, float shadowDistance, int shadowCascades, Vector3 shadowCascadeSplit, float renderScale, int msaaSamples, bool allowHDR) { // Unity默认光强度是在Gamma空间中定义,即使我们工作在线性空间 // 我们需要指定Unity将光强度理解为线性空间中的值 GraphicsSettings.lightsUseLinearIntensity = true; if (SystemInfo.usesReversedZBuffer) { worldToShadowCascadeMatrices[4].m33 = 1f; } if (dynamicBatching) { // 开启动态批处理 drawFlags = DrawRendererFlags.EnableDynamicBatching; } if (instancing) { // 开启GPU实例化 // 如果同时开启动态批处理,Unity优先使用GPU实例化 drawFlags |= DrawRendererFlags.EnableInstancing; } this.defaultStack = defaultStack; this.shadowMapSize = shadowMapSize; this.shadowDistance = shadowDistance; this.shadowCascades = shadowCascades; this.shadowCascadeSplit = shadowCascadeSplit; this.renderScale = renderScale; // QualitySettings会处理平台或者硬件不支持的情况,所以把值赋过去再取回。如果不支持MSAA,取回的值是0 QualitySettings.antiAliasing = msaaSamples; this.msaaSamples = Mathf.Max(QualitySettings.antiAliasing, 1); this.allowHDR = allowHDR; }
/// <summary> /// 准备渲染时需要的数据 /// </summary> private void perpareData() { //当前相机是否需要后处理 var myPipelineCamera = m_camera.GetComponent <MyPipelineCamera>(); m_activeStack = myPipelineCamera ? myPipelineCamera.postProcessingStack : m_rpp.defaultStack; //根据是否开启HDR选用渲染纹理格式 m_format = m_rpp.allowHDR && m_camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default; //获取多重采样抗锯齿参数 //如果Msaa不被支持返回0 QualitySettings.antiAliasing = m_rpp.msaa; m_rpp.msaa = Mathf.Max(QualitySettings.antiAliasing, 1); m_renderSamples = m_camera.allowMSAA ? m_rpp.msaa : 1; //缩放分辨率 m_scaledRendering = (m_rpp.renderScale <1.0f || m_rpp.renderScale> 1.0f) && m_camera.cameraType == CameraType.Game; m_renderSize.x = m_camera.pixelWidth; m_renderSize.y = m_camera.pixelHeight; if (m_scaledRendering) { m_renderSize.x = (int)(m_renderSize.x * m_rpp.renderScale); m_renderSize.y = (int)(m_renderSize.y * m_rpp.renderScale); } //判断是否渲染到纹理 m_renderToTexture = m_scaledRendering || m_renderSamples > 1 || m_activeStack; //判断是否需要深度贴图 m_needsDepth = m_activeStack && m_activeStack.needsDepth; //如果开启多重采样,需要单独的一个Pass渲染深度 m_needsDirectDepth = m_needsDepth && m_renderSamples == 1; m_needsDepthOnlyPass = m_needsDepth && m_renderSamples > 1; }
public void Render(ScriptableRenderContext context, Camera camera) { if (!CullResults.GetCullingParameters(camera, out var cullingParameters)) { return; } cullingParameters.shadowDistance = Mathf.Min(shadowDistance, camera.farClipPlane); #if UNITY_EDITOR if (camera.cameraType == CameraType.SceneView) { //将UI几何体发射到“场景”视图中以进行渲染。 ScriptableRenderContext.EmitWorldGeometryForSceneView(camera); } else if (mainCamera == null && camera.cameraType == CameraType.Game && camera == Camera.main) { mainCamera = camera; } #endif //CullResults cull = CullResults.Cull(ref cullingParameters, context); CullResults.Cull(ref cullingParameters, context, ref cull); if (cull.visibleLights.Count > 0) { ConfigureLights(); if (mainLightExists) { RenderCascadedShadows(context); } else { cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword); cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword); } if (shadowTileCount > 0) { RenderShadows(context); } else { cameraBuffer.DisableShaderKeyword(shadowsHardKeyword); cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword); } } else { cameraBuffer.SetGlobalVector(lightIndicesOffsetAndCountID, Vector4.zero); cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword); cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword); cameraBuffer.DisableShaderKeyword(shadowsHardKeyword); cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword); } context.SetupCameraProperties(camera); var myPipelineCamera = camera.GetComponent <MyPipelineCamera>(); MyPostProcessingStack activeStack = myPipelineCamera ? myPipelineCamera.PostProcessingStack : defaultStack; bool scaledRendering = renderScale != 1f && camera.cameraType == CameraType.Game; int renderWidth = camera.pixelWidth; int renderHeight = camera.pixelHeight; if (scaledRendering) { renderWidth = (int)(renderWidth * renderScale); renderHeight = (int)(renderHeight * renderScale); } int renderSamples = camera.allowMSAA ? msaaSamples : 1; bool renderToTexture = scaledRendering || renderSamples > 1 || activeStack; bool needsDepth = activeStack && activeStack.NeedsDepth; //如果MSAA != 1 , 则 主贴图需要 24位深度 用来ZTestWrite画 bool needsDirectDepth = needsDepth && renderSamples == 1; //专门用DepthOnly 来画深度图 bool needsDepthOnlyPass = needsDepth && renderSamples > 1; RenderTextureFormat format = allowHDR && camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default; if (renderToTexture) { //需要深度进行处理的的时候 要单独的深度图 不让它进行MSAA //否则可以跟随主颜色进行MSAA cameraBuffer.GetTemporaryRT(cameraColorTextureID, renderWidth, renderHeight, needsDirectDepth ? 0 : 24 , FilterMode.Bilinear, format, RenderTextureReadWrite.Default, renderSamples); if (needsDepth) { cameraBuffer.GetTemporaryRT(cameraDepthTextureID, renderWidth, renderHeight, 24 , FilterMode.Point, RenderTextureFormat.Depth, RenderTextureReadWrite.Linear, 1); } if (needsDirectDepth) { cameraBuffer.SetRenderTarget(cameraColorTextureID, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, cameraDepthTextureID, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); } else { cameraBuffer.SetRenderTarget(cameraColorTextureID, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); } } CameraClearFlags clearFlags = camera.clearFlags; cameraBuffer.ClearRenderTarget((clearFlags & CameraClearFlags.Depth) != 0 , (clearFlags & CameraClearFlags.Color) != 0, camera.backgroundColor); cameraBuffer.BeginSample("Render Camera"); cameraBuffer.SetGlobalVectorArray(visibleLightColorsID, visibleLightColors); cameraBuffer.SetGlobalVectorArray(visibleLightDirectionsOrPositionsID, visibleLightDirectionsOrPositions); cameraBuffer.SetGlobalVectorArray(visibleLightAttenuationsID, visibleLightAttenuations); cameraBuffer.SetGlobalVectorArray(visibleLightSpotDirectionsID, visibleLightSpotDirections); cameraBuffer.SetGlobalVectorArray(visibleLightOcclusionMaskID, visibleLightOcclusionMasks); globalShadowData.z = 1f - cullingParameters.shadowDistance * globalShadowData.y; cameraBuffer.SetGlobalVector(globalShadowDataID, globalShadowData); context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); //这样就可以走SRP的SubShader 如果没有则都走 //Shader SubShader Tags{"RenderPipeline"="MySRPPipeline"} //Shader.globalRenderPipeline = "MySRPPipeline"; //我们必须通过提供相机和一个shader pass 作为draw setting的构造函数的参数。 //这个相机用来设置排序和裁剪层级(culling layers), //而shader pass 控制使用那个shader pass进行渲染。 //如果Pass未指定LightMode,Unity会自动将其设置为SRPDefaultUnlit var drawSettings = new DrawRendererSettings(camera, new ShaderPassName("SRPDefaultUnlit")) { flags = drawFlags, rendererConfiguration = RendererConfiguration.None }; if (cull.visibleLights.Count > 0) { drawSettings.rendererConfiguration = RendererConfiguration.PerObjectLightIndices8; } drawSettings.rendererConfiguration |= RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectLightProbeProxyVolume | RendererConfiguration.PerObjectShadowMask | RendererConfiguration.PerObjectOcclusionProbe | RendererConfiguration.PerObjectOcclusionProbeProxyVolume; drawSettings.sorting.flags = SortFlags.CommonOpaque; //因为 Unity 更喜欢将对象空间化地分组以减少overdraw var filterSettings = new FilterRenderersSettings(true) { renderQueueRange = RenderQueueRange.opaque }; context.DrawRenderers( cull.visibleRenderers, ref drawSettings, filterSettings); context.DrawSkybox(camera); if (activeStack) { if (needsDepth) { if (needsDepthOnlyPass) { var depthOnlyDrawSettings = new DrawRendererSettings( camera, new ShaderPassName("DepthOnly")) { flags = drawFlags, sorting = { flags = SortFlags.CommonOpaque } }; cameraBuffer.SetRenderTarget(cameraDepthTextureID, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); cameraBuffer.ClearRenderTarget(true, false, Color.clear); context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); context.DrawRenderers(cull.visibleRenderers, ref depthOnlyDrawSettings, filterSettings); } } activeStack.RenderAfterOpaque( postProcessingBuffer, cameraColorTextureID, cameraDepthTextureID , renderWidth, renderHeight, renderSamples, format); context.ExecuteCommandBuffer(postProcessingBuffer); postProcessingBuffer.Clear(); if (needsDirectDepth) { cameraBuffer.SetRenderTarget( cameraColorTextureID, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store , cameraDepthTextureID, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store); } else { cameraBuffer.SetRenderTarget(cameraColorTextureID, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store); } context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); } drawSettings.sorting.flags = SortFlags.CommonTransparent; filterSettings.renderQueueRange = RenderQueueRange.transparent; context.DrawRenderers( cull.visibleRenderers, ref drawSettings, filterSettings); DrawDefaultPipeline(context, camera); if (renderToTexture) { if (activeStack) { activeStack.RenderAfterTransparent(postProcessingBuffer, cameraColorTextureID, cameraDepthTextureID , renderWidth, renderHeight, renderSamples, format); context.ExecuteCommandBuffer(postProcessingBuffer); postProcessingBuffer.Clear(); } else { cameraBuffer.Blit(cameraColorTextureID, BuiltinRenderTextureType.CameraTarget); } cameraBuffer.ReleaseTemporaryRT(cameraColorTextureID); if (needsDepth) { cameraBuffer.ReleaseTemporaryRT(cameraDepthTextureID); } } cameraBuffer.EndSample("Render Camera"); context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); context.Submit(); if (shadowMap) { RenderTexture.ReleaseTemporary(shadowMap); shadowMap = null; } if (cascadedShadowMap) { RenderTexture.ReleaseTemporary(cascadedShadowMap); cascadedShadowMap = null; } }
void Render(ScriptableRenderContext context, Camera camera) { ScriptableCullingParameters cullingParameters; if (!CullResults.GetCullingParameters(camera, out cullingParameters)) { return; } cullingParameters.shadowDistance = Mathf.Min(shadowDistance, camera.farClipPlane); #if UNITY_EDITOR if (camera.cameraType == CameraType.SceneView) { ScriptableRenderContext.EmitWorldGeometryForSceneView(camera); } #endif CullResults.Cull(ref cullingParameters, context, ref cull); if (cull.visibleLights.Count > 0) { ConfigureLights(); if (mainLightExists) { RenderCascadedShadows(context); } else { cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword); cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword); } if (shadowTileCount > 0) { RenderShadows(context); } else { cameraBuffer.DisableShaderKeyword(shadowsHardKeyword); cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword); } } else { cameraBuffer.SetGlobalVector( lightIndecesOffsetAndCountId, Vector4.zero ); cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword); cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword); cameraBuffer.DisableShaderKeyword(shadowsHardKeyword); cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword); } ConfigureLights(); context.SetupCameraProperties(camera); var myPipelineCamera = camera.GetComponent <MyPipelineCamera>(); MyPostProcessingStack activeStack = myPipelineCamera ? myPipelineCamera.PostProcessingStack : defaultStack; bool scaledRendering = (renderScale <1f || renderScale> 1f) && camera.cameraType == CameraType.Game; int renderWidth = camera.pixelWidth; int renderHeight = camera.pixelHeight; if (scaledRendering) { renderWidth = (int)(renderWidth * renderScale); renderHeight = (int)(renderHeight * renderScale); } int renderSamples = camera.allowMSAA ? msaaSamples : 1; bool renderToTexture = scaledRendering || renderSamples > 1 || activeStack; bool needsDepth = activeStack && activeStack.NeedsDepth; bool needsDirectDepth = needsDepth && renderSamples == 1; bool needsDepthOnlyPass = needsDepth && renderSamples > 1; RenderTextureFormat format = allowHDR && camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default; if (renderToTexture) { cameraBuffer.GetTemporaryRT( cameraColorTextureId, renderWidth, renderHeight, needsDirectDepth ? 0 : 24, FilterMode.Bilinear, format, RenderTextureReadWrite.Default, renderSamples ); if (needsDepth) { cameraBuffer.GetTemporaryRT( cameraDepthTextureId, renderWidth, renderHeight, 24, FilterMode.Point, RenderTextureFormat.Depth, RenderTextureReadWrite.Linear, 1 ); } if (needsDirectDepth) { cameraBuffer.SetRenderTarget( cameraColorTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, cameraDepthTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store ); } else { cameraBuffer.SetRenderTarget( cameraColorTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store ); } } CameraClearFlags clearFlags = camera.clearFlags; cameraBuffer.ClearRenderTarget( (clearFlags & CameraClearFlags.Depth) != 0, (clearFlags & CameraClearFlags.Color) != 0, camera.backgroundColor ); cameraBuffer.BeginSample("Render Camera"); cameraBuffer.SetGlobalVectorArray( visibleLightColorsId, visibleLightColors ); cameraBuffer.SetGlobalVectorArray( visibleLightDirectionsOrPositionsId, visibleLightDirectionsOrPositions ); cameraBuffer.SetGlobalVectorArray( visibleLightAttenuationId, visibleLightAttenuations ); cameraBuffer.SetGlobalVectorArray( visibleLightSpotDirectionsId, visibleLightSpotDirections ); cameraBuffer.SetGlobalVectorArray( visibleLightOcclusionMasksId, visibleLightOcclusionMasks ); globalShadowData.z = 1f - cullingParameters.shadowDistance * globalShadowData.y; cameraBuffer.SetGlobalVector(globalShadowDataId, globalShadowData); context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); var drawSettings = new DrawRendererSettings( camera, new ShaderPassName("SRPDefaultUnlit") ) { flags = drawFlags }; if (cull.visibleLights.Count > 0) { drawSettings.rendererConfiguration = RendererConfiguration.PerObjectLightIndices8; } drawSettings.rendererConfiguration |= RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectLightProbeProxyVolume | RendererConfiguration.PerObjectShadowMask | RendererConfiguration.PerObjectOcclusionProbe | RendererConfiguration.PerObjectOcclusionProbeProxyVolume; drawSettings.sorting.flags = SortFlags.CommonOpaque; var filterSettings = new FilterRenderersSettings(true) { renderQueueRange = RenderQueueRange.opaque }; context.DrawRenderers( cull.visibleRenderers, ref drawSettings, filterSettings ); context.DrawSkybox(camera); if (activeStack) { if (needsDepthOnlyPass) { var depthOnlyDrawSettings = new DrawRendererSettings( camera, new ShaderPassName("DepthOnly") ) { flags = drawFlags }; depthOnlyDrawSettings.sorting.flags = SortFlags.CommonOpaque; cameraBuffer.SetRenderTarget( cameraDepthTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store ); cameraBuffer.ClearRenderTarget(true, false, Color.clear); context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); context.DrawRenderers( cull.visibleRenderers, ref depthOnlyDrawSettings, filterSettings ); } activeStack.RenderAfterOpaque( postProcessingBuffer, cameraColorTextureId, cameraDepthTextureId, renderWidth, renderHeight, msaaSamples, format ); context.ExecuteCommandBuffer(postProcessingBuffer); postProcessingBuffer.Clear(); if (needsDirectDepth) { cameraBuffer.SetRenderTarget( cameraColorTextureId, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store, cameraDepthTextureId, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store ); } else { cameraBuffer.SetRenderTarget( cameraColorTextureId, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store ); } context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); } drawSettings.sorting.flags = SortFlags.CommonTransparent; filterSettings.renderQueueRange = RenderQueueRange.transparent; context.DrawRenderers( cull.visibleRenderers, ref drawSettings, filterSettings ); DrawDefaultPipeline(context, camera); if (renderToTexture) { if (activeStack) { activeStack.RenderAfterTransparent( postProcessingBuffer, cameraColorTextureId, cameraDepthTextureId, renderWidth, renderHeight, msaaSamples, format ); context.ExecuteCommandBuffer(postProcessingBuffer); postProcessingBuffer.Clear(); } else { cameraBuffer.Blit( cameraColorTextureId, BuiltinRenderTextureType.CameraTarget ); } cameraBuffer.ReleaseTemporaryRT(cameraColorTextureId); if (needsDepth) { cameraBuffer.ReleaseTemporaryRT(cameraDepthTextureId); } } cameraBuffer.EndSample("Render Camera"); context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); context.Submit(); if (shadowMap) { RenderTexture.ReleaseTemporary(shadowMap); shadowMap = null; } if (cascadedShadowMap) { RenderTexture.ReleaseTemporary(cascadedShadowMap); cascadedShadowMap = null; } }
void Render(ScriptableRenderContext context, Camera camera) { // 剔除参数 ScriptableCullingParameters cullingParameters; // 获取剔除参数 if (!CullResults.GetCullingParameters(camera, out cullingParameters)) { // 如果相机设定非法,直接返回 return; } // 设置阴影参数 cullingParameters.shadowDistance = Mathf.Min(shadowDistance, camera.farClipPlane); // 仅在编辑模式下 #if UNITY_EDITOR // 仅在渲染场景视图时。否则游戏视图中的UI元素会被渲染两次 if (camera.cameraType == CameraType.SceneView) { // 当canvas的渲染被设置在世界空间时,UI元素不会出现在场景视图中 // 需要手动指定以使其正确显示 ScriptableRenderContext.EmitWorldGeometryForSceneView(camera); } #endif // 剔除 CullResults.Cull(ref cullingParameters, context, ref cull); if (cull.visibleLights.Count > 0) { ConfigureLights(); if (mainLightExists) { RenderCascadedShadows(context); } else { cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword); cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword); } if (shadowTileCount > 0) { RenderShadows(context); } else { cameraBuffer.DisableShaderKeyword(shadowsHardKeyword); cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword); } } else { // 由于该值会被保留为上一个物体使用的值,因此需要手动设置 cameraBuffer.SetGlobalVector(lightIndicesOffsetAndCountID, Vector4.zero); cameraBuffer.DisableShaderKeyword(cascadedShadowsHardKeyword); cameraBuffer.DisableShaderKeyword(cascadedShadowsSoftKeyword); cameraBuffer.DisableShaderKeyword(shadowsHardKeyword); cameraBuffer.DisableShaderKeyword(shadowsSoftKeyword); } // 设置unity_MatrixVP,以及一些其他属性 context.SetupCameraProperties(camera); // 获取摄像机的定制后处理栈 var myPipelineCamera = camera.GetComponent <MyPipelineCamera>(); MyPostProcessingStack activeStack = myPipelineCamera ? myPipelineCamera.PostProcessingStack : defaultStack; // 只影响游戏摄像机 bool scaledRendering = (renderScale <1f || renderScale> 1f) && camera.cameraType == CameraType.Game; int renderWidth = camera.pixelWidth; int renderHeight = camera.pixelHeight; if (scaledRendering) { renderWidth = (int)(renderWidth * renderScale); renderHeight = (int)(renderHeight * renderScale); } // 摄像机是否开启MSAA int renderSamples = camera.allowMSAA ? msaaSamples : 1; // 开启渲染到纹理 bool renderToTexture = scaledRendering || renderSamples > 1 || activeStack; // 是否需要深度纹理(深度纹理不支持MSAA) bool needsDepth = activeStack && activeStack.NeedsDepth; bool needsDirectDepth = needsDepth && renderSamples == 1; // 不使用MSAA bool needsDepthOnlyPass = needsDepth && renderSamples > 1; // 使用MSAA、 // 纹理格式 RenderTextureFormat format = allowHDR && camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default; // 获取并设置渲染目标,用于后处理 if (renderToTexture) { cameraBuffer.GetTemporaryRT( cameraColorTextureId, renderWidth, renderHeight, needsDirectDepth ? 0 : 24, FilterMode.Bilinear, format, RenderTextureReadWrite.Default, renderSamples ); if (needsDepth) { cameraBuffer.GetTemporaryRT( cameraDepthTextureId, renderWidth, renderHeight, 24, FilterMode.Point, RenderTextureFormat.Depth, RenderTextureReadWrite.Linear, 1 // 1表示不使用MSAA ); } if (needsDirectDepth) { cameraBuffer.SetRenderTarget( cameraColorTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, cameraDepthTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store ); } else { cameraBuffer.SetRenderTarget( cameraColorTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store ); } } // 清空 CameraClearFlags clearFlags = camera.clearFlags; cameraBuffer.ClearRenderTarget((clearFlags & CameraClearFlags.Depth) != 0, (clearFlags & CameraClearFlags.Color) != 0, camera.backgroundColor); // 设置采样标志,用于在Frame Debugger中组织结构 cameraBuffer.BeginSample("HY Render Camera"); // 设置光数据 cameraBuffer.SetGlobalVectorArray(visibleLightColorsId, visibleLightColors); cameraBuffer.SetGlobalVectorArray(visibleLightDirectionsOrPositionsId, visibleLightDirectionsOrPositions); cameraBuffer.SetGlobalVectorArray(visibleLightAttenuationsId, visibleLightAttenuations); cameraBuffer.SetGlobalVectorArray(visibleLightSpotDirectionsId, visibleLightSpotDirections); // 执行指令缓冲。这并不会立即执行指令,只是将指令拷贝到上下文的内部缓冲中 context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); // 绘制设定 // camera参数设定排序和剔除层,pass参数指定使用哪一个shader pass var drawSettings = new DrawRendererSettings(camera, new ShaderPassName("SRPDefaultUnlit")) { flags = drawFlags }; // 仅在有可见光时设置,否则Unity会崩溃 if (cull.visibleLights.Count > 0) { // 指定Unity为每个物体传输光索引数据 drawSettings.rendererConfiguration = RendererConfiguration.PerObjectLightIndices8; } // 指定使用反射探针,如果场景中没有反射探针,则使用天空球的立方体贴图 drawSettings.rendererConfiguration |= RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps; // 指定排序,从前往后 drawSettings.sorting.flags = SortFlags.CommonOpaque; // 过滤设定 // true表示包括所有物体 var filterSettings = new FilterRenderersSettings(true) { // 绘制不透明物体,渲染队列为[0,2500] renderQueueRange = RenderQueueRange.opaque }; context.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings); // 绘制天空盒 // camera参数仅用来判断是否绘制天空盒(根据camera的清空标志位) context.DrawSkybox(camera); // 后处理 if (activeStack) { // depth-only pass if (needsDepthOnlyPass) { var depthOnlyDrawSettings = new DrawRendererSettings( camera, new ShaderPassName("DepthOnly") ) { flags = drawFlags }; depthOnlyDrawSettings.sorting.flags = SortFlags.CommonOpaque; cameraBuffer.SetRenderTarget( cameraDepthTextureId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store ); cameraBuffer.ClearRenderTarget(true, false, Color.clear); context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); context.DrawRenderers( cull.visibleRenderers, ref depthOnlyDrawSettings, filterSettings ); } activeStack.RenderAfterOpaque( postProcessingBuffer, cameraColorTextureId, cameraDepthTextureId, renderWidth, renderHeight, renderSamples, format ); context.ExecuteCommandBuffer(postProcessingBuffer); postProcessingBuffer.Clear(); if (needsDirectDepth) { cameraBuffer.SetRenderTarget( cameraColorTextureId, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store, cameraDepthTextureId, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store ); } else { cameraBuffer.SetRenderTarget( cameraColorTextureId, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store ); } context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); } // 指定排序,从后往前 drawSettings.sorting.flags = SortFlags.CommonTransparent; // 绘制透明物体,渲染队列为[2501,5000] filterSettings.renderQueueRange = RenderQueueRange.transparent; context.DrawRenderers(cull.visibleRenderers, ref drawSettings, filterSettings); DrawDefaultPipeline(context, camera); // 后处理 if (renderToTexture) { if (activeStack) { activeStack.RenderAfterTransparent( postProcessingBuffer, cameraColorTextureId, cameraDepthTextureId, renderWidth, renderHeight, renderSamples, format ); context.ExecuteCommandBuffer(postProcessingBuffer); postProcessingBuffer.Clear(); } else { cameraBuffer.Blit( cameraColorTextureId, BuiltinRenderTextureType.CameraTarget ); } cameraBuffer.ReleaseTemporaryRT(cameraColorTextureId); if (needsDepth) { cameraBuffer.ReleaseTemporaryRT(cameraDepthTextureId); } } cameraBuffer.EndSample("HY Render Camera"); context.ExecuteCommandBuffer(cameraBuffer); cameraBuffer.Clear(); // 提交指令 context.Submit(); // 释放阴影纹理 if (shadowMap) { RenderTexture.ReleaseTemporary(shadowMap); shadowMap = null; } // 释放层级阴影纹理 if (cascadedShadowMap) { RenderTexture.ReleaseTemporary(cascadedShadowMap); cascadedShadowMap = null; } }