实现自定义阴影图时,如何不依赖Camera组件调用ScriptableRenderContext.Cull?
解决无Camera组件下获取CullingResults的问题
错误的核心原因是ScriptableCullingParameters需要关联一个Camera实例来处理LOD衰减和渲染器上下文逻辑,哪怕你不使用场景中的Camera组件,也可以通过创建临时的、未挂载到场景的Camera对象来满足要求。
修改步骤与代码示例
// 创建临时Camera(无需挂载到任何GameObject) var tempCamera = new Camera(); tempCamera.transform.SetPositionAndRotation(_transform.position, _transform.rotation); tempCamera.orthographic = true; tempCamera.nearClipPlane = _nearClip; tempCamera.farClipPlane = _farClip; tempCamera.projectionMatrix = _projectionMatrix; // 绑定自定义投影矩阵 // 用临时Camera初始化裁剪参数(自动填充必要上下文) if (!ScriptableCullingParameters.TryGetCullingParameters(tempCamera, out var cullParams)) { Debug.LogError("无法获取裁剪参数"); Object.DestroyImmediate(tempCamera); return; } // 自定义裁剪配置(按需调整) cullParams.cullingOptions = CullingOptions.None; cullParams.maximumVisibleLights = 0; // 替换裁剪平面(如果需要自定义) var nearClipPlane = new Plane(Vector3.forward, tempCamera.transform.position + Vector3.forward * _nearClip); var farClipPlane = new Plane(-Vector3.forward, tempCamera.transform.position + Vector3.forward * _farClip); cullParams.cullingPlaneCount = 2; cullParams.SetCullingPlane(0, nearClipPlane); cullParams.SetCullingPlane(1, farClipPlane); // 执行裁剪获取结果 var cullData = context.Cull(ref cullParams); // 后续渲染命令保持逻辑,注意RendererListDesc使用临时Camera _commandBuffer.SetRenderTarget(_depthTexture); _commandBuffer.ClearRenderTarget(true, true, Color.clear); _commandBuffer.SetViewMatrix(_viewMatrix); _commandBuffer.SetProjectionMatrix(_projectionMatrix); var rendererListDesc = new RendererListDesc(new ShaderTagId("UniversalForward"), cullData, tempCamera) { sortingCriteria = SortingCriteria.CommonOpaque, rendererConfiguration = PerObjectData.None, renderQueueRange = RenderQueueRange.opaque, overrideMaterial = _testMaterial }; var rendererList = context.CreateRendererList(rendererListDesc); _commandBuffer.DrawRendererList(rendererList); context.ExecuteCommandBuffer(_commandBuffer); _commandBuffer.Clear(); // 销毁临时Camera,避免内存泄漏 Object.DestroyImmediate(tempCamera);
关键注意点
- 临时Camera仅用于提供裁剪所需的上下文,不会在场景中显示或产生额外开销
- 使用
TryGetCullingParameters初始化参数比手动赋值更可靠,能自动处理LOD、视锥体等基础逻辑 - 用完必须销毁临时Camera,防止内存泄漏
- 原始代码中裁剪平面的法线方向可能有误,已在示例中修正(近裁剪平面法线指向相机前方,远裁剪平面法线指向相机后方)
内容的提问来源于stack exchange,提问作者Nikolai
相关产品推荐
相关产品推荐

