using UnityEngine; using UnityEngine.Rendering; /// /// 相机渲染管理类:单独控制每个相机的渲染 /// public partial class CameraRenderer { ScriptableRenderContext context; Camera camera; const string bufferName = "Render Camera"; // 创建缓冲区 CommandBuffer buffer = new CommandBuffer { name = bufferName }; // 存储相机剔除后的结果 CullingResults cullingResults; // 着色器标记ID static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit"); static ShaderTagId litShaderTagId = new ShaderTagId("CustomLit"); static int frameBufferId = Shader.PropertyToID("_CameraFrameBuffer"); Lighting lighting = new Lighting(); PostFXStack postFXStack = new PostFXStack(); bool useHDR; /// /// 相机渲染 /// /// /// /// /// /// /// /// /// /// public void Render(ScriptableRenderContext context, Camera camera, bool allowHDR, bool useDynamicBatching, bool useGPUInstancing, bool useLightsPerObject, ShadowSettings shadowSettings, PostFXSettings postFXSettings, int colorLUTResolution) { this.context = context; this.camera = camera; // 设置buffer缓冲区的名字 PrepareBuffer(); // 在Game视图绘制的几何体也绘制到Scene视图中 PrepareForSceneWindow(); if (!Cull(shadowSettings.maxDistance)) { return; } useHDR = allowHDR && camera.allowHDR; context.SetupCameraProperties(camera); // 获得相机的clear flags CameraClearFlags flags = camera.clearFlags; buffer.BeginSample(sampleName); ExecuteBuffer(); lighting.Setup(context, cullingResults, shadowSettings, useLightsPerObject); postFXStack.Setup(context, camera, postFXSettings, useHDR, colorLUTResolution); buffer.EndSample(sampleName); Setup(); // 绘制可见几何体 DrawVisibleGeometry(useDynamicBatching, useGPUInstancing, useLightsPerObject); // 绘制SRP不支持的内置shader类型 DrawUnsupportedShaders(); // 绘制Gizmos DrawGizmosBeforeFX(); if (postFXStack.IsActive) { if (flags > CameraClearFlags.Color) { flags = CameraClearFlags.Color; } postFXStack.Render(frameBufferId); } DrawGizmosAfterFX(); Cleanup(); // 提交缓冲区 Submit(); } /// /// 剔除 /// /// bool Cull(float maxShadowDistance) { if (camera.TryGetCullingParameters(out ScriptableCullingParameters p)) { p.shadowDistance = Mathf.Min(maxShadowDistance, camera.farClipPlane); cullingResults = context.Cull(ref p); return true; } return false; } /// /// 设置相机的属性和矩阵,在着色器中被称为unity_matrixvp /// void Setup() { context.SetupCameraProperties(camera); // 得到相机的clearflags CameraClearFlags flags = camera.clearFlags; if (postFXStack.IsActive) { buffer.GetTemporaryRT(frameBufferId, camera.pixelWidth, camera.pixelHeight, 32, FilterMode.Bilinear, useHDR ? RenderTextureFormat.DefaultHDR: RenderTextureFormat.Default); buffer.SetRenderTarget(frameBufferId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); } // 设置相机清除状态 buffer.ClearRenderTarget(flags <= CameraClearFlags.Depth, flags == CameraClearFlags.Color, flags == CameraClearFlags.Color ? camera.backgroundColor.linear : Color.clear); buffer.BeginSample(sampleName); ExecuteBuffer(); } void Cleanup() { // 释放申请的RT内存空间 lighting.Cleanup(); if (postFXStack.IsActive) { buffer.ReleaseTemporaryRT(frameBufferId); } } /// /// 提交缓冲区命令 /// void Submit() { buffer.EndSample(sampleName); ExecuteBuffer(); context.Submit(); } /// /// 执行缓冲区命令 /// void ExecuteBuffer() { context.ExecuteCommandBuffer(buffer); buffer.Clear(); } /// /// 绘制可见几何体,顺序:不透明物体->天空盒->透明物体 /// void DrawVisibleGeometry(bool useDynamicBatching, bool useGPUInstancing, bool useLightsPerObject) { PerObjectData lightsPerObjectFlags = useLightsPerObject ? PerObjectData.LightData | PerObjectData.LightIndices : PerObjectData.None; // 设置绘制顺序和指定渲染相机 var sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque }; // 设置渲染的shader pass和渲染顺序 var drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings) { enableDynamicBatching = useDynamicBatching, enableInstancing = useGPUInstancing, perObjectData = PerObjectData.Lightmaps | PerObjectData.ShadowMask | PerObjectData.LightProbe | PerObjectData.OcclusionProbe | PerObjectData.LightProbeProxyVolume | PerObjectData.ReflectionProbes | lightsPerObjectFlags, }; // 渲染CustomLit表示的pass块 drawingSettings.SetShaderPassName(1, litShaderTagId); // 只绘制RenderQueue为opaque不透明物体 var filteringSettings = new FilteringSettings(RenderQueueRange.opaque); // 绘制不透明物体 context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings); // 绘制天空盒 context.DrawSkybox(camera); sortingSettings.criteria = SortingCriteria.CommonTransparent; drawingSettings.sortingSettings = sortingSettings; // 只绘制RenderQueue为transparent透明的物体 filteringSettings.renderQueueRange = RenderQueueRange.transparent; // 绘制透明物体 context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings); } }