{"id":1348,"date":"2020-02-25T22:27:03","date_gmt":"2020-02-25T14:27:03","guid":{"rendered":"http:\/\/blog.coolcoding.cn\/?p=1348"},"modified":"2020-12-23T17:43:25","modified_gmt":"2020-12-23T09:43:25","slug":"lwrp","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=1348","title":{"rendered":"lwrp"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>#if UNITY_EDITOR\nusing System;\nusing UnityEditor;\nusing UnityEditor.ProjectWindowCallback;\n#endif\n \nnamespace UnityEngine.Experimental.Rendering.LightweightPipeline\n{\n    \/\/\/ &lt;summary>\n    \/\/\/ \u9634\u5f71\u7ea7\u8054\n    \/\/\/ &lt;\/summary>\n    public enum ShadowCascades\n    {\n        NO_CASCADES = 0,\n        TWO_CASCADES,\n        FOUR_CASCADES,\n    }\n    \/\/\/ &lt;summary>\n    \/\/\/ \u9634\u5f71\u7c7b\u578b\n    \/\/\/ &lt;\/summary>\n    public enum ShadowType\n    {\n        NO_SHADOW = 0,\n        HARD_SHADOWS,\n        SOFT_SHADOWS,\n    }\n    \/\/\/ &lt;summary>\n    \/\/\/ \u9634\u5f71\u5206\u8fa8\u7387\n    \/\/\/ &lt;\/summary>\n    public enum ShadowResolution\n    {\n        _256 = 256,\n        _512 = 512,\n        _1024 = 1024,\n        _2048 = 2048,\n        _4096 = 4096\n    }\n    \/\/\/ &lt;summary>\n    \/\/\/ MSAA\u8d28\u91cf\n    \/\/\/ MSAA\u662f\u201c\u591a\u91cd\u91c7\u6837\u6297\u952f\u9f7f\u201d\uff0c\u53ef\u4ee5\u4f7f\u753b\u9762\u66f4\u52a0\u5e73\u6ed1\u3002\n    \/\/\/ \u8d85\u7ea7\u91c7\u6837\u6297\u952f\u9f7f\uff08Super Sampling Anti-Aliasing\uff09\u7684\u539f\u7406\u662f\u628a\u5f53\u524d\u5206\u8fa8\u7387\u6210\u500d\u63d0\u9ad8,\u7136\u540e\u518d\u628a\u753b\u7f29\u653e\u5230\u5f53\u524d\u7684\u663e\u793a\u5668\u4e0a\u3002\n    \/\/\/ \u8fd9\u6837\u7684\u505a\u6cd5\u5b9e\u9645\u4e0a\u5c31\u662f\u5728\u663e\u793a\u5c3a\u5bf8\u4e0d\u53d8\u7684\u60c5\u51b5\u63d0\u9ad8\u5206\u8fa8\u7387\uff0c\u8ba9\u5355\u4e2a\u50cf\u7d20\u53d8\u5f97\u6781\u5c0f\uff0c\u8fd9\u6837\u5c31\u80fd\u591f\u5927\u5e45\u51cf\u8f7b\u753b\u9762\u7684\u952f\u9f7f\u611f\u4e86\u3002\n    \/\/\/ \u4e0d\u8fc7\u662f\u7531\u4e8e\u5bf9\u6574\u4e2a\u663e\u793a\u753b\u9762\u7684\u653e\u5927\uff0c\u56e0\u6b64\u5b83\u6d88\u8017\u7684\u663e\u793a\u8d44\u6e90\u4e5f\u662f\u975e\u5e38\u5927\u7684\u3002\n    \/\/\/ \u4e0d\u8fc7MSAA\u662f\u5bfb\u627e\u51fa\u7269\u4f53\u8fb9\u7f18\u90e8\u5206\u7684\u50cf\u7d20\uff0c\u7136\u540e\u5bf9\u5b83\u4eec\u8fdb\u884c\u7f29\u653e\u5904\u7406\u3002\n    \/\/\/ \u7531\u4e8e\u53ea\u662f\u7269\u4f53\u7684\u5916\u5c42\u50cf\u7d20\u8fdb\u884c\u7f29\u653e\u5904\u7406\uff0c\u5ffd\u7565\u6389\u4e86\u4e0d\u4f1a\u4ea7\u751f\u952f\u9f7f\u7684\u5185\u90e8\u50cf\u7d20\uff0c\n    \/\/\/ \u6240\u4ee5\u663e\u5361\u4e0d\u4f1a\u50cf\u5904\u7406SSAA\uff08\u8d85\u7ea7\u91c7\u6837\u6297\u952f\u9f7f\uff09\u90a3\u6837\u9700\u8981\u5e9e\u5927\u7684\u8ba1\u7b97\u91cf\uff0c\u56e0\u6b64MSAA\u6bd4\u8d77SSAA\u6765\u66f4\u6709\u6548\u3002\n    \/\/\/ &lt;\/summary>\n    public enum MSAAQuality\n    {\n        Disabled = 1,\n        _2x = 2,\n        _4x = 4,\n        _8x = 8\n    }\n    \/\/\/ &lt;summary>\n    \/\/\/ \u964d\u91c7\u6837\uff0c\u5728ForwardLitPass\u4e2d\u4f7f\u7528\n    \/\/\/ &lt;\/summary>\n    public enum Downsampling\n    {\n        None = 0,\n        _2xBilinear,\n        _4xBox,\n        _4xBilinear\n    }\n    \/\/\/ &lt;summary>\n    \/\/\/ \u9ed8\u8ba4\u6750\u8d28\u7c7b\u578b\n    \/\/\/ LightweightPipelineEditorResources\u7684\u8d44\u6e90\u4e2d\u83b7\u5f97\n    \/\/\/ &lt;\/summary>\n    public enum DefaultMaterialType\n    {\n        Standard = 0,\n        Particle,\n        Terrain,\n        UnityBuiltinDefault\n    }\n \n    public class LightweightPipelineAsset : RenderPipelineAsset, ISerializationCallbackReceiver\n    {\n        \/\/ \u8fd9\u4e24\u4e2a\u8def\u5f84\u7528\u4e8e\u67e5\u627eScriptableObject\uff0c\u4f18\u5148\u5728\"Assets\"\u4e2d\u67e5\u627e\uff0c\u82e5\u4e0d\u5b58\u5728\u76f4\u63a5\u53d6\u9ed8\u8ba4\n        public static readonly string s_SearchPathProject = \"Assets\";\n        public static readonly string s_SearchPathPackage = \"Packages\/com.unity.render-pipelines.lightweight\";\n \n        \/\/\/ &lt;summary>\n        \/\/\/ GetDefaultShader()\u65b9\u6cd5\u8c03\u7528\u9ed8\u8ba4shader\u7684\u79c1\u6709\u53d8\u91cf\n        \/\/\/ &lt;\/summary>\n        Shader m_DefaultShader;\n \n        \/\/ Default values set when a new LightweightPipeli ne asset is created\n        \/\/\/ &lt;summary>\n        \/\/\/ \u7248\u672c\u53f7\uff0c\u7528\u4e8e\u5f00\u53d1\u8fc7\u7a0b\u7684\u8fed\u4ee3\uff0c\u5728ISerializationCallbackReceiver\u63a5\u53e3\u7684OnAfterDeserialize()\u4e2d\u53ef\u4ee5\u5c06\u65e7\u7248\u6570\u636e\u8f6c\u6362\u4e3a\u65b0\u7248\u4f7f\u7528\u7684\u6570\u636e\n        \/\/\/ &lt;\/summary>\n        [SerializeField] int k_AssetVersion = 3;\n        #region Editor\u4e2d\u5305\u542b\u7684\u5143\u7d20\n        \/\/\/ &lt;summary>\n        \/\/\/ \u6700\u5927\u9010\u50cf\u7d20\u5149\u6e90\u4e2a\u6570\n        \/\/\/ &lt;\/summary>\n        [SerializeField] int m_MaxPixelLights = 4;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u9876\u70b9\u5149\u7167\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_SupportsVertexLight = false;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9700\u8981\u6df1\u5ea6\u7eb9\u7406\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_RequireDepthTexture = false;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9700\u8981\u8f6f\u7c92\u5b50\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_RequireSoftParticles = false;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9700\u8981\u4e0d\u900f\u660e\u8d34\u56fe\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_RequireOpaqueTexture = false;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u4e0d\u900f\u660e\u964d\u91c7\u6837\n        \/\/\/ &lt;\/summary>\n        [SerializeField] Downsampling m_OpaqueDownsampling = Downsampling._2xBilinear;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301HDR\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_SupportsHDR = false;\n        \/\/\/ &lt;summary>\n        \/\/\/ MSAA\n        \/\/\/ &lt;\/summary>\n        [SerializeField] MSAAQuality m_MSAA = MSAAQuality._4x;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u6e32\u67d3\u6bd4\u4f8b\n        \/\/\/ &lt;\/summary>\n        [SerializeField] float m_RenderScale = 1.0f;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u52a8\u6001\u6279\u5904\u7406\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_SupportsDynamicBatching = true;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u5b9a\u5411\u9634\u5f71\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_DirectionalShadowsSupported = true;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9634\u5f71\u56fe\u96c6\u5206\u8fa8\u7387\n        \/\/\/ &lt;\/summary>\n        [SerializeField] ShadowResolution m_ShadowAtlasResolution = ShadowResolution._2048;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9634\u5f71\u8ddd\u79bb\n        \/\/\/ &lt;\/summary>\n        [SerializeField] float m_ShadowDistance = 50.0f;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9634\u5f71\u7ea7\u8054\n        \/\/\/ &lt;\/summary>\n        [SerializeField] ShadowCascades m_ShadowCascades = ShadowCascades.FOUR_CASCADES;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u4e8c\u7ea7\u7ea7\u8054\u5206\u754c\n        \/\/\/ &lt;\/summary>\n        [SerializeField] float m_Cascade2Split = 0.25f;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u56db\u7ea7\u7ea7\u8054\u5206\u754c\n        \/\/\/ &lt;\/summary>\n        [SerializeField] Vector3 m_Cascade4Split = new Vector3(0.067f, 0.2f, 0.467f);\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u975e\u5e73\u884c\u5149\u9634\u5f71\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_LocalShadowsSupported = true;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u975e\u5e73\u884c\u5149\u9634\u5f71\u56fe\u96c6\u5206\u8fa8\u7387\n        \/\/\/ &lt;\/summary>\n        [SerializeField] ShadowResolution m_LocalShadowsAtlasResolution = ShadowResolution._512;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u8f6f\u9634\u5f71\n        \/\/\/ &lt;\/summary>\n        [SerializeField] bool m_SoftShadowsSupported = false; \n        #endregion\n        \/\/\u4ee5\u4e0b\u5185\u5bb9\uff0c\u5173\u7cfb\u5230LightweightPipelineCore\u4e2d\u7684 static PipelineCapabilities s_PipelineCapabilities\n        [SerializeField] bool m_KeepAdditionalLightVariants = true;\n        [SerializeField] bool m_KeepVertexLightVariants = true;\n        [SerializeField] bool m_KeepDirectionalShadowVariants = true;\n        [SerializeField] bool m_KeepLocalShadowVariants = true;\n        [SerializeField] bool m_KeepSoftShadowVariants = true;\n        \/\/\/ &lt;summary>\n        \/\/\/ 4\u4e2ashader \uff1aBlitShader;CopyDepthShader;ScreenSpaceShadowShader;SamplingShader;\n        \/\/\/ &lt;\/summary>\n        [SerializeField] LightweightPipelineResources m_ResourcesAsset;\n \n        \/\/ Deprecated\n        [SerializeField] ShadowType m_ShadowType = ShadowType.HARD_SHADOWS;\n \n#if UNITY_EDITOR\n        \/\/\/ &lt;summary>\n        \/\/\/ \u4e09\u4e2a\u6750\u8d28\n        \/\/\/ &lt;\/summary>\n        [NonSerialized]\n        LightweightPipelineEditorResources m_EditorResourcesAsset;\n \n        [MenuItem(\"Assets\/Create\/Rendering\/Lightweight Pipeline Asset\", priority = CoreUtils.assetCreateMenuPriority1)]\n        static void CreateLightweightPipeline()\n        {\n            ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance&lt;CreateLightweightPipelineAsset>(),\n                \"LightweightAsset.asset\", null, null);\n        }\n \n        \/\/[MenuItem(\"Assets\/Create\/Rendering\/Lightweight Pipeline Resources\", priority = CoreUtils.assetCreateMenuPriority1)]\n        static void CreateLightweightPipelineResources()\n        {\n            var instance = CreateInstance&lt;LightweightPipelineResources>();\n            AssetDatabase.CreateAsset(instance, string.Format(\"Assets\/{0}.asset\", typeof(LightweightPipelineResources).Name));\n        }\n \n        \/\/[MenuItem(\"Assets\/Create\/Rendering\/Lightweight Pipeline Editor Resources\", priority = CoreUtils.assetCreateMenuPriority1)]\n        static void CreateLightweightPipelineEditorResources()\n        {\n            var instance = CreateInstance&lt;LightweightPipelineEditorResources>();\n            AssetDatabase.CreateAsset(instance, string.Format(\"Assets\/{0}.asset\", typeof(LightweightPipelineEditorResources).Name));\n        }\n \n        \/\/\/ &lt;summary>\n        \/\/\/ \u521b\u5efa\u5e26\u521d\u59cb\u5316\u7684\u7a97\u53e3\n        \/\/\/ &lt;\/summary>\n        class CreateLightweightPipelineAsset : EndNameEditAction\n        {\n            public override void Action(int instanceId, string pathName, string resourceFile)\n            {\n                var instance = CreateInstance&lt;LightweightPipelineAsset>();\n                instance.m_EditorResourcesAsset = LoadResourceFile&lt;LightweightPipelineEditorResources>();\n                instance.m_ResourcesAsset = LoadResourceFile&lt;LightweightPipelineResources>();\n                AssetDatabase.CreateAsset(instance, pathName);\n            }\n        }\n \n        \/\/\/ &lt;summary>\n        \/\/\/ \u52a0\u8f7dScriptableObject\u8d44\u6e90\uff0c\u5148\u67e5\u627eAsset\u6587\u4ef6\u5939\uff0c\u82e5\u4e0d\u5b58\u5728\u4f7f\u7528\u9ed8\u8ba4\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;typeparam name=\"T\">&lt;\/typeparam>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        static T LoadResourceFile&lt;T>() where T : ScriptableObject\n        {\n            T resourceAsset = null;\n            var guids = AssetDatabase.FindAssets(typeof(T).Name + \" t:scriptableobject\", new[] {s_SearchPathProject});\n            foreach (string guid in guids)\n            {\n                string path = AssetDatabase.GUIDToAssetPath(guid);\n                resourceAsset = AssetDatabase.LoadAssetAtPath&lt;T>(path);\n                if (resourceAsset != null)\n                    break;\n            }\n \n            \/\/ There's currently an issue that prevents FindAssets from find resources withing the package folder.\n            if (resourceAsset == null)\n            {\n                string path = s_SearchPathPackage + \"\/LWRP\/Data\/\" + typeof(T).Name + \".asset\";\n                resourceAsset = AssetDatabase.LoadAssetAtPath&lt;T>(path);\n            }\n            return resourceAsset;\n        }\n \n        LightweightPipelineEditorResources editorResources\n        {\n            get\n            {\n                if (m_EditorResourcesAsset == null)\n                    m_EditorResourcesAsset = LoadResourceFile&lt;LightweightPipelineEditorResources>();\n \n                return m_EditorResourcesAsset;\n            }\n        }\n#endif\n        LightweightPipelineResources resources\n        {\n            get\n            {\n#if UNITY_EDITOR\n                if (m_ResourcesAsset == null)\n                    m_ResourcesAsset = LoadResourceFile&lt;LightweightPipelineResources>();\n#endif\n                return m_ResourcesAsset;\n            }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u521b\u5efa\u6e32\u67d3\u7ba1\u7ebf\u7684\u65b9\u6cd5\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        protected override IRenderPipeline InternalCreatePipeline()\n        {\n            return new LightweightPipeline(this);\n        }\n \n        \/\/\/ &lt;summary>\n        \/\/\/ \u83b7\u5f97ScriptableObject\u4e2d\u7684\u6750\u8d28\u8d44\u6e90\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"materialType\">&lt;\/param>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        Material GetMaterial(DefaultMaterialType materialType)\n        {\n#if UNITY_EDITOR\n            if (editorResources == null)\n                return null;\n \n            switch (materialType)\n            {\n                case DefaultMaterialType.Standard:\n                    return editorResources.DefaultMaterial;\n \n                case DefaultMaterialType.Particle:\n                    return editorResources.DefaultParticleMaterial;\n \n                case DefaultMaterialType.Terrain:\n                    return editorResources.DefaultTerrainMaterial;\n \n                \/\/ Unity Builtin Default\n                default:\n                    return null;\n            }\n#else\n            return null;\n#endif\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u83b7\u5f97\u7248\u672c\u53f7\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public int GetAssetVersion()\n        {\n            return k_AssetVersion;\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u6700\u5927\u9010\u50cf\u7d20\u5149\u6e90\u6570\u91cf\n        \/\/\/ &lt;\/summary>\n        public int maxPixelLights\n        {\n            get { return m_MaxPixelLights; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u9876\u70b9\u5149\u7167\n        \/\/\/ &lt;\/summary>\n        public bool supportsVertexLight\n        {\n            get { return m_SupportsVertexLight; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u6df1\u5ea6\u7eb9\u7406\n        \/\/\/ &lt;\/summary>\n        public bool supportsCameraDepthTexture\n        {\n            get { return m_RequireDepthTexture; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u8f6f\u7c92\u5b50\n        \/\/\/ &lt;\/summary>\n        public bool supportsSoftParticles\n        {\n            get { return m_RequireSoftParticles; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u4e0d\u900f\u660e\u8d34\u56fe\n        \/\/\/ &lt;\/summary>\n        public bool supportsCameraOpaqueTexture\n        {\n            get { return m_RequireOpaqueTexture; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u4e0d\u900f\u660e\u964d\u91c7\u6837 Downsampling._2xBilinear\n        \/\/\/ &lt;\/summary>\n        public Downsampling opaqueDownsampling\n        {\n            get { return m_OpaqueDownsampling; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301HDR\n        \/\/\/ &lt;\/summary>\n        public bool supportsHDR\n        {\n            get { return m_SupportsHDR; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ MSAA\u7684\u7a0b\u5ea6\n        \/\/\/ &lt;\/summary>\n        public int msaaSampleCount\n        {\n            get { return (int)m_MSAA; }\n            set { m_MSAA = (MSAAQuality)value; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u6e32\u67d3\u6bd4\u4f8b\n        \/\/\/ &lt;\/summary>\n        public float renderScale\n        {\n            get { return m_RenderScale; }\n            set { m_RenderScale = value; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u52a8\u6001\u6279\u5904\u7406\n        \/\/\/ &lt;\/summary>\n        public bool supportsDynamicBatching\n        {\n            get { return m_SupportsDynamicBatching; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u5b9a\u5411\u9634\u5f71\n        \/\/\/ &lt;\/summary>\n        public bool supportsDirectionalShadows\n        {\n            get { return m_DirectionalShadowsSupported; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u5b9a\u5411\u9634\u5f71\u56fe\u96c6\u5206\u8fa8\u7387\n        \/\/\/ &lt;\/summary>\n        public int directionalShadowAtlasResolution\n        {\n            get { return (int)m_ShadowAtlasResolution; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9634\u5f71\u8ddd\u79bb\n        \/\/\/ &lt;\/summary>\n        public float shadowDistance\n        {\n            get { return m_ShadowDistance; }\n            set { m_ShadowDistance = value; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9634\u5f71\u7ea7\u8054\uff081\u30012\u30014\uff09\n        \/\/\/ &lt;\/summary>\n        public int cascadeCount\n        {\n            get\n            {\n                switch (m_ShadowCascades)\n                {\n                    case ShadowCascades.TWO_CASCADES:\n                        return 2;\n                    case ShadowCascades.FOUR_CASCADES:\n                        return 4;\n                    default:\n                        return 1;\n                }\n            }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9634\u5f71\u7ea7\u80542\u7ea7\n        \/\/\/ &lt;\/summary>\n        public float cascade2Split\n        {\n            get { return m_Cascade2Split; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u9634\u5f71\u7ea7\u80544\u7ea7\n        \/\/\/ &lt;\/summary>\n        public Vector3 cascade4Split\n        {\n            get { return m_Cascade4Split; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u975e\u5e73\u884c\u5149\u9634\u5f71\n        \/\/\/ &lt;\/summary>\n        public bool supportsLocalShadows\n        {\n            get { return m_LocalShadowsSupported; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u975e\u5e73\u884c\u5149\u9634\u5f71\u5206\u8fa8\u7387\n        \/\/\/ &lt;\/summary>\n        public int localShadowAtlasResolution\n        {\n            get { return (int)m_LocalShadowsAtlasResolution; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u652f\u6301\u8f6f\u9634\u5f71\n        \/\/\/ &lt;\/summary>\n        public bool supportsSoftShadows\n        {\n            get { return m_SoftShadowsSupported; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u81ea\u5b9a\u4e49Shader\u53d8\u91cf\u5206\u79bb\uff0cFalse\n        \/\/\/ &lt;\/summary>\n        public bool customShaderVariantStripping\n        {\n            get { return false; }\n        }\n        \/\/\u4ee5\u4e0b\u5185\u5bb9\uff0c\u5173\u7cfb\u5230LightweightPipelineCore\u4e2d\u7684 static PipelineCapabilities s_PipelineCapabilities\n        public bool keepAdditionalLightVariants\n        {\n            get { return m_KeepAdditionalLightVariants; }\n        }\n \n        public bool keepVertexLightVariants\n        {\n            get { return m_KeepVertexLightVariants; }\n        }\n \n        public bool keepDirectionalShadowVariants\n        {\n            get { return m_KeepDirectionalShadowVariants; }\n        }\n \n        public bool keepLocalShadowVariants\n        {\n            get { return m_KeepLocalShadowVariants; }\n        }\n \n        public bool keepSoftShadowVariants\n        {\n            get { return m_KeepSoftShadowVariants; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ Lightweight-Default.mat\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Material GetDefaultMaterial()\n        {\n            return GetMaterial(DefaultMaterialType.Standard);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ Lightweight-DefaultParticle.mat\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Material GetDefaultParticleMaterial()\n        {\n            return GetMaterial(DefaultMaterialType.Particle);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ null\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Material GetDefaultLineMaterial()\n        {\n            return GetMaterial(DefaultMaterialType.UnityBuiltinDefault);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ Lightweight-DefaultTerrain.mat\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Material GetDefaultTerrainMaterial()\n        {\n            return GetMaterial(DefaultMaterialType.Terrain);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ null\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Material GetDefaultUIMaterial()\n        {\n            return GetMaterial(DefaultMaterialType.UnityBuiltinDefault);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ null\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Material GetDefaultUIOverdrawMaterial()\n        {\n            return GetMaterial(DefaultMaterialType.UnityBuiltinDefault);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ null\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Material GetDefaultUIETC1SupportedMaterial()\n        {\n            return GetMaterial(DefaultMaterialType.UnityBuiltinDefault);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ null\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Material GetDefault2DMaterial()\n        {\n            return GetMaterial(DefaultMaterialType.UnityBuiltinDefault);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u83b7\u53d6\u9ed8\u8ba4shader\n        \/\/\/ LightweightShaderUtils\u5185\u6709\u9759\u6001\u6570\u636e\n        \/\/\/ \u5b9e\u9645\u5b57\u7b26\u4e32\u4e3a\"LightweightPipeline\/Standard (Physically Based)\"\n        \/\/\/ Lightweight-Default.mat\u4e5f\u4f7f\u7528\u8be5Shader\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        public override Shader GetDefaultShader()\n        {\n            if (m_DefaultShader == null)\n                m_DefaultShader = Shader.Find(LightweightShaderUtils.GetShaderPath(ShaderPathID.STANDARD_PBS));\n            return m_DefaultShader;\n        }\n \n        \/\/\/ &lt;summary>\n        \/\/\/ \"Hidden\/LightweightPipeline\/BlitShader\"\n        \/\/\/ &lt;\/summary>\n        public Shader blitShader\n        {\n            get { return resources != null ? resources.BlitShader : null; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \"Hidden\/LightweightPipeline\/CopyDepthShader\"\n        \/\/\/ &lt;\/summary>\n        public Shader copyDepthShader\n        {\n            get { return resources != null ? resources.CopyDepthShader : null; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \"Hidden\/LightweightPipeline\/ScreenSpaceShadows\"\n        \/\/\/ &lt;\/summary>\n        public Shader screenSpaceShadowShader\n        {\n            get { return resources != null ? resources.ScreenSpaceShadowShader : null; }\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \"Hidden\/LightweightPipeline\/SamplingShader\"\n        \/\/\/ &lt;\/summary>\n        public Shader samplingShader\n        {\n            get { return resources != null ? resources.SamplingShader : null; }\n        }\n \n        public void OnBeforeSerialize()\n        {\n        }\n \n        \/\/\/ &lt;summary>\n        \/\/\/ m_ShadowType\u5df2\u5f03\u7528\uff0c\u5c06\u65e7\u7248\u8d44\u6e90\u7684m_ShadowType\u8f6c\u4e3am_SoftShadowsSupported\u5b57\u6bb5\n        \/\/\/ &lt;\/summary>\n        public void OnAfterDeserialize()\n        {\n            if (k_AssetVersion &lt; 3)\n            {\n                k_AssetVersion = 3;\n                m_SoftShadowsSupported = (m_ShadowType == ShadowType.SOFT_SHADOWS);\n            }\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>\nusing UnityEngine;\n \npublic class LightweightPipelineResources : ScriptableObject\n{\n    public Shader BlitShader;\n    public Shader CopyDepthShader;\n    public Shader ScreenSpaceShadowShader;\n    public Shader SamplingShader;\n}\nusing System;\nusing UnityEngine;\n \npublic class LightweightPipelineEditorResources : ScriptableObject\n{\n    public Material DefaultMaterial;\n    public Material DefaultParticleMaterial;\n    public Material DefaultTerrainMaterial;\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>using System;\nusing System.Collections.Generic;\n#if UNITY_EDITOR\nusing UnityEditor.Experimental.Rendering.LightweightPipeline;\n#endif\nusing UnityEngine.Rendering;\nusing UnityEngine.Rendering.PostProcessing;\nusing UnityEngine.XR;\n \nnamespace UnityEngine.Experimental.Rendering.LightweightPipeline\n{\n    public partial class LightweightPipeline : RenderPipeline\n    {\n        \/\/\/ &lt;summary>\n        \/\/\/ \u6e32\u67d3\u7ba1\u7ebf\u8d44\u6e90\n        \/\/\/ &lt;\/summary>\n        public LightweightPipelineAsset pipelineAsset { get; private set; }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u6444\u50cf\u673a\u6309\u6df1\u5ea6\u6392\u5e8f\n        \/\/\/ &lt;\/summary>\n        CameraComparer m_CameraComparer = new CameraComparer();\n        \/\/\/ &lt;summary>\n        \/\/\/ \u524d\u5411\u6e32\u67d3\u7c7b\n        \/\/\/ &lt;\/summary>\n        LightweightForwardRenderer m_Renderer;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u5254\u9664\u7ed3\u679c\n        \/\/\/ &lt;\/summary>\n        CullResults m_CullResults;\n        \/\/\/ &lt;summary>\n        \/\/\/ \u975e\u5e73\u884c\u5149\u6e90\u7f16\u53f7\u7d22\u5f15\uff0c\u7528\u4e8e\u9634\u5f71\u751f\u6210\n        \/\/\/ &lt;\/summary>\n        List&lt;int> m_LocalLightIndices = new List&lt;int>();\n        \/\/\/ &lt;summary>\n        \/\/\/ \u6807\u8bb0\u9010\u76f8\u673a\u6e32\u67d3\u8fdb\u884c\u8fc7\u7a0b\n        \/\/\/ &lt;\/summary>\n        bool m_IsCameraRendering;\n \n        public LightweightPipeline(LightweightPipelineAsset asset)\n        {\n            pipelineAsset = asset;\n \n            SetSupportedRenderingFeatures();\n            SetPipelineCapabilities(asset);\n \n            PerFrameBuffer._GlossyEnvironmentColor = Shader.PropertyToID(\"_GlossyEnvironmentColor\");\n            PerFrameBuffer._SubtractiveShadowColor = Shader.PropertyToID(\"_SubtractiveShadowColor\");\n \n            PerCameraBuffer._ScaledScreenParams = Shader.PropertyToID(\"_ScaledScreenParams\");\n            m_Renderer = new LightweightForwardRenderer(asset);\n \n            \/\/ Let engine know we have MSAA on for cases where we support MSAA backbuffer\n            if (QualitySettings.antiAliasing != pipelineAsset.msaaSampleCount)\n                QualitySettings.antiAliasing = pipelineAsset.msaaSampleCount;\n \n            Shader.globalRenderPipeline = \"LightweightPipeline\";\n            m_IsCameraRendering = false;\n        }\n \n        public override void Dispose()\n        {\n            base.Dispose();\n            Shader.globalRenderPipeline = \"\";\n            SupportedRenderingFeatures.active = new SupportedRenderingFeatures();\n \n#if UNITY_EDITOR\n            SceneViewDrawMode.ResetDrawMode();\n#endif\n \n            m_Renderer.Dispose();\n        }\n \n        public override void Render(ScriptableRenderContext context, Camera[] cameras)\n        {\n            if (m_IsCameraRendering)\n            {\n                Debug.LogWarning(\"Nested camera rendering is forbidden. If you are calling camera.Render inside OnWillRenderObject callback, use BeginCameraRender callback instead.\");\n                return;\n            }\n \n            \/\/\u521d\u59cb\u5316\u6bcf\u5e27\u6570\u636e\n            base.Render(context, cameras);\n            BeginFrameRendering(cameras);\n \n            GraphicsSettings.lightsUseLinearIntensity = true;\n            SetupPerFrameShaderConstants();\n \n            \/\/ Sort cameras array by camera depth\n            Array.Sort(cameras, m_CameraComparer);\n \n            foreach (Camera camera in cameras)\n            {\n                BeginCameraRendering(camera);\n                string renderCameraTag = \"Render \" + camera.name;\n                CommandBuffer cmd = CommandBufferPool.Get(renderCameraTag);\n                \/\/using \u7ed3\u675f\u6216\u4e2d\u9014\u4e2d\u65ad\u4f1a\u8c03\u7528()\u4e2d\u7c7b\u7684Dispose()\u65b9\u6cd5\n                using (new ProfilingSample(cmd, renderCameraTag))\n                {\n                    \/\/\u521d\u59cb\u5316\u9010\u76f8\u673a\u7684\u6570\u636e\n                    CameraData cameraData;\n                    InitializeCameraData(camera, out cameraData);\n                    SetupPerCameraShaderConstants(cameraData);\n                    \/\/\u5254\u9664\n                    ScriptableCullingParameters cullingParameters;\n                    if (!CullResults.GetCullingParameters(camera, cameraData.isStereoEnabled, out cullingParameters))\n                    {\n                        CommandBufferPool.Release(cmd);\n                        continue;\n                    }\n \n                    cullingParameters.shadowDistance = Mathf.Min(cameraData.maxShadowDistance, camera.farClipPlane);\n                    \/\/\u8fd9\u91cc\u6267\u884c\u7684new ProfilingSample(cmd, renderCameraTag)\u4e2d\u8bbe\u7f6e\u7684cmd.BeginSample(name);\u547d\u4ee4\n                    context.ExecuteCommandBuffer(cmd);\n                    cmd.Clear();\n \n#if UNITY_EDITOR\n                    try\n#endif\n                    {\n                        m_IsCameraRendering = true;\n#if UNITY_EDITOR\n                        \/\/ Emit scene view UI\n                        if (cameraData.isSceneViewCamera)\n                            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);\n#endif\n                        \/\/\u5254\u9664\u7ed3\u679c\n                        CullResults.Cull(ref cullingParameters, context, ref m_CullResults);\n                        List&lt;VisibleLight> visibleLights = m_CullResults.visibleLights;\n \n                        RenderingData renderingData;\n                        InitializeRenderingData(ref cameraData, visibleLights,\n                            m_Renderer.maxSupportedLocalLightsPerPass, m_Renderer.maxSupportedVertexLights,\n                            out renderingData);\n                        m_Renderer.Setup(ref context, ref m_CullResults, ref renderingData);\n                        m_Renderer.Execute(ref context, ref m_CullResults, ref renderingData);\n                    }\n#if UNITY_EDITOR\n                    catch (Exception)\n                    {\n                        CommandBufferPool.Release(cmd);\n                        throw;\n                    }\n                    finally\n#endif\n                    {\n                        m_IsCameraRendering = false;\n                    }\n                }\n                \/\/\u8fd9\u91cc\u6267\u884c\u7684ProfilingSample.Dispose()\u4e2d\u8bbe\u7f6e\u7684m_Cmd.EndSample(m_Name);\u547d\u4ee4\n                context.ExecuteCommandBuffer(cmd);\n                CommandBufferPool.Release(cmd);\n                context.Submit();\n            }\n        }\n \n        public static void RenderPostProcess(CommandBuffer cmd, PostProcessRenderContext context, ref CameraData cameraData, RenderTextureFormat colorFormat, RenderTargetIdentifier source, RenderTargetIdentifier dest, bool opaqueOnly)\n        {\n            context.Reset();\n            context.camera = cameraData.camera;\n            context.source = source;\n            context.sourceFormat = colorFormat;\n            context.destination = dest;\n            context.command = cmd;\n            context.flip = cameraData.camera.targetTexture == null;\n \n            if (opaqueOnly)\n                cameraData.postProcessLayer.RenderOpaqueOnly(context);\n            else\n                cameraData.postProcessLayer.Render(context);\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u8bbe\u7f6e\u652f\u6301\u7684\u6e32\u67d3\u7279\u5f81,active\u662f\u9759\u6001\u7684\n        \/\/\/ &lt;\/summary>\n        void SetSupportedRenderingFeatures()\n        {\n#if UNITY_EDITOR\n            SupportedRenderingFeatures.active = new SupportedRenderingFeatures()\n            {\n                \/\/\u53cd\u5c04\u63a2\u9488\n                reflectionProbeSupportFlags = SupportedRenderingFeatures.ReflectionProbeSupportFlags.None,\n                \/\/\u9ed8\u8ba4\u7684\u5149\u7167\u8d34\u56fe\u7684\u6df7\u5408\u70d8\u7119\u6a21\u5f0f\n                defaultMixedLightingMode = SupportedRenderingFeatures.LightmapMixedBakeMode.Subtractive,\n                \/\/\u652f\u6301\u7684\u5149\u7167\u8d34\u56fe\u7684\u6df7\u5408\u70d8\u7119\u6a21\u5f0f\n                supportedMixedLightingModes = SupportedRenderingFeatures.LightmapMixedBakeMode.Subtractive,\n                \/\/\u652f\u6301\u7684\u5149\u7167\u8d34\u56fe\u70d8\u7119\u6a21\u5f0f\n                supportedLightmapBakeTypes = LightmapBakeType.Baked | LightmapBakeType.Mixed,\n                \/\/\u652f\u6301\u7684\u5149\u7167\u8d34\u56fe\u7c7b\u578b\n                supportedLightmapsModes = LightmapsMode.CombinedDirectional | LightmapsMode.NonDirectional,\n                \/\/\u652f\u6301\u5149\u7167\u63a2\u9488\u4ee3\u7406\n                rendererSupportsLightProbeProxyVolumes = false,\n                \/\/\u652f\u6301\u8fd0\u52a8\u77e2\u91cf\n                rendererSupportsMotionVectors = false,\n                \/\/\u63a5\u53d7\u9634\u5f71\n                rendererSupportsReceiveShadows = true,\n                \/\/\u53cd\u5c04\u63a2\u9488\n                rendererSupportsReflectionProbes = true\n            };\n            SceneViewDrawMode.SetupDrawMode();\n#endif\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u521d\u59cb\u5316\u6444\u50cf\u673a\u6570\u636e\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"camera\">&lt;\/param>\n        \/\/\/ &lt;param name=\"cameraData\">&lt;\/param>\n        void InitializeCameraData(Camera camera, out CameraData cameraData)\n        {\n            \/\/\u63a5\u8fd11\u7684pipelineAsset.renderScale(\u6216\u8005XRSettings.eyeTextureResolutionScale)\uff0c\u7f6e\u4e3a1\n            const float kRenderScaleThreshold = 0.05f;\n            cameraData.camera = camera;\n \n            bool msaaEnabled = camera.allowMSAA &amp;&amp; pipelineAsset.msaaSampleCount > 1;\n            if (msaaEnabled)\n                cameraData.msaaSamples = (camera.targetTexture != null) ? camera.targetTexture.antiAliasing : pipelineAsset.msaaSampleCount;\n            else\n                cameraData.msaaSamples = 1;\n            \/\/\u573a\u666f\u76f8\u673a\n            cameraData.isSceneViewCamera = camera.cameraType == CameraType.SceneView;\n            \/\/\u5b58\u5728RT\u4e14\u4e0d\u662f\u573a\u666f\u76f8\u673a\n            cameraData.isOffscreenRender = camera.targetTexture != null &amp;&amp; !cameraData.isSceneViewCamera;\n            cameraData.isStereoEnabled = IsStereoEnabled(camera);\n            cameraData.isHdrEnabled = camera.allowHDR &amp;&amp; pipelineAsset.supportsHDR;\n \n            cameraData.postProcessLayer = camera.GetComponent&lt;PostProcessLayer>();\n            cameraData.postProcessEnabled = cameraData.postProcessLayer != null &amp;&amp; cameraData.postProcessLayer.isActiveAndEnabled;\n \n            \/\/ PostProcess for VR is not working atm. Disable it for now.\n            cameraData.postProcessEnabled &amp;= !cameraData.isStereoEnabled;\n \n            Rect cameraRect = camera.rect;\n            cameraData.isDefaultViewport = (!(Math.Abs(cameraRect.x) > 0.0f || Math.Abs(cameraRect.y) > 0.0f ||\n                                              Math.Abs(cameraRect.width) &lt; 1.0f || Math.Abs(cameraRect.height) &lt; 1.0f));\n \n            \/\/ Discard variations lesser than kRenderScaleThreshold.\n            \/\/ Scale is only enabled for gameview.\n            \/\/ In XR mode, grab renderScale from XRSettings instead of SRP asset for now.\n            \/\/ This is just a temporary change pending full integration of XR with SRP\n \n            if (camera.cameraType == CameraType.Game)\n            {\n#if !UNITY_SWITCH\n                if (cameraData.isStereoEnabled)\n                {\n                    cameraData.renderScale = XRSettings.eyeTextureResolutionScale;\n                } else\n#endif\n                {\n                    cameraData.renderScale = pipelineAsset.renderScale;\n                }\n            }\n            else\n            {\n                cameraData.renderScale = 1.0f;\n            }\n \n            cameraData.renderScale = (Mathf.Abs(1.0f - cameraData.renderScale) &lt; kRenderScaleThreshold) ? 1.0f : cameraData.renderScale;\n \n            cameraData.requiresDepthTexture = pipelineAsset.supportsCameraDepthTexture || cameraData.isSceneViewCamera;\n            cameraData.requiresSoftParticles = pipelineAsset.supportsSoftParticles;\n            cameraData.requiresOpaqueTexture = pipelineAsset.supportsCameraOpaqueTexture;\n            cameraData.opaqueTextureDownsampling = pipelineAsset.opaqueDownsampling;\n \n            bool anyShadowsEnabled = pipelineAsset.supportsDirectionalShadows || pipelineAsset.supportsLocalShadows;\n            cameraData.maxShadowDistance = (anyShadowsEnabled) ? pipelineAsset.shadowDistance : 0.0f;\n            \/\/\u8fd9\u662f\u4e00\u4e2a\u989d\u5916\u6dfb\u52a0\u7684\u811a\u672c\n            LightweightAdditionalCameraData additionalCameraData = camera.gameObject.GetComponent&lt;LightweightAdditionalCameraData>();\n            if (additionalCameraData != null)\n            {\n                cameraData.maxShadowDistance = (additionalCameraData.renderShadows) ? cameraData.maxShadowDistance : 0.0f;\n                cameraData.requiresDepthTexture &amp;= additionalCameraData.requiresDepthTexture;\n                cameraData.requiresOpaqueTexture &amp;= additionalCameraData.requiresColorTexture;\n            }\n            else if (!cameraData.isSceneViewCamera &amp;&amp; camera.cameraType != CameraType.Reflection &amp;&amp; camera.cameraType != CameraType.Preview)\n            {\n                cameraData.requiresDepthTexture = false;\n                cameraData.requiresOpaqueTexture = false;\n            }\n \n            cameraData.requiresDepthTexture |= cameraData.postProcessEnabled;\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u521d\u59cb\u5316\u6e32\u67d3\u6570\u636e\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"cameraData\">&lt;\/param>\n        \/\/\/ &lt;param name=\"visibleLights\">&lt;\/param>\n        \/\/\/ &lt;param name=\"maxSupportedLocalLightsPerPass\">&lt;\/param>\n        \/\/\/ &lt;param name=\"maxSupportedVertexLights\">&lt;\/param>\n        \/\/\/ &lt;param name=\"renderingData\">&lt;\/param>\n        void InitializeRenderingData(ref CameraData cameraData, List&lt;VisibleLight> visibleLights, int maxSupportedLocalLightsPerPass, int maxSupportedVertexLights, out RenderingData renderingData)\n        {\n            \/\/\u7528\u4e8e\u751f\u6210\u9634\u5f71\u7684\u975e\u5e73\u884c\u5149\u6e90\n            m_LocalLightIndices.Clear();\n            \/\/\u6709\u9634\u5f71\u6295\u5c04\u5e73\u884c\u5149\u6e90\n            bool hasDirectionalShadowCastingLight = false;\n            \/\/\u6709\u9634\u5f71\u6295\u5c04\u975e\u5e73\u884c\u5149\u6e90\n            bool hasLocalShadowCastingLight = false;\n            \/\/\u521d\u59cb\u5316\u9634\u5f71\u7684\u76f8\u5173\u53d8\u91cf\n            if (cameraData.maxShadowDistance > 0.0f)\n            {\n                for (int i = 0; i &lt; visibleLights.Count; ++i)\n                {\n                    Light light = visibleLights[i].light;\n                    bool castShadows = light != null &amp;&amp; light.shadows != LightShadows.None;\n                    if (visibleLights[i].lightType == LightType.Directional)\n                    {\n                        hasDirectionalShadowCastingLight |= castShadows;\n                    }\n                    else\n                    {\n                        hasLocalShadowCastingLight |= castShadows;\n                        m_LocalLightIndices.Add(i);\n                    }\n                }\n            }\n \n            renderingData.cameraData = cameraData;\n            InitializeLightData(visibleLights, maxSupportedLocalLightsPerPass, maxSupportedVertexLights, out renderingData.lightData);\n            InitializeShadowData(hasDirectionalShadowCastingLight, hasLocalShadowCastingLight, out renderingData.shadowData);\n            renderingData.supportsDynamicBatching = pipelineAsset.supportsDynamicBatching;\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u521d\u59cb\u5316\u9634\u5f71\u6570\u636e\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"hasDirectionalShadowCastingLight\">&lt;\/param>\n        \/\/\/ &lt;param name=\"hasLocalShadowCastingLight\">&lt;\/param>\n        \/\/\/ &lt;param name=\"shadowData\">&lt;\/param>\n        void InitializeShadowData(bool hasDirectionalShadowCastingLight, bool hasLocalShadowCastingLight, out ShadowData shadowData)\n        {\n            \/\/ Until we can have keyword stripping forcing single cascade hard shadows on gles2\n            bool supportsScreenSpaceShadows = SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2;\n            \/\/\u6e32\u67d3\u5e73\u884c\u5149\u9634\u5f71\n            shadowData.renderDirectionalShadows = pipelineAsset.supportsDirectionalShadows &amp;&amp; hasDirectionalShadowCastingLight;\n \n            \/\/ we resolve shadows in screenspace when cascades are enabled to save ALU as computing cascade index + shadowCoord on fragment is expensive\n            shadowData.requiresScreenSpaceShadowResolve = shadowData.renderDirectionalShadows &amp;&amp; supportsScreenSpaceShadows &amp;&amp; pipelineAsset.cascadeCount > 1;\n            \/\/\u9634\u5f71\u7ea7\u8054\n            shadowData.directionalLightCascadeCount = (shadowData.requiresScreenSpaceShadowResolve) ? pipelineAsset.cascadeCount : 1;\n            shadowData.directionalShadowAtlasWidth = pipelineAsset.directionalShadowAtlasResolution;\n            shadowData.directionalShadowAtlasHeight = pipelineAsset.directionalShadowAtlasResolution;\n            \/\/\u9634\u5f71\u7ea7\u8054\u7edf\u4e00\u4e3aVector3\u8868\u8fbe\n            switch (shadowData.directionalLightCascadeCount)\n            {\n                case 1:\n                    shadowData.directionalLightCascades = new Vector3(1.0f, 0.0f, 0.0f);\n                    break;\n \n                case 2:\n                    shadowData.directionalLightCascades = new Vector3(pipelineAsset.cascade2Split, 1.0f, 0.0f);\n                    break;\n \n                default:\n                    shadowData.directionalLightCascades = pipelineAsset.cascade4Split;\n                    break;\n            }\n            \/\/\u6e32\u67d3\u975e\u5e73\u884c\u5149\u9634\u5f71\n            shadowData.renderLocalShadows = pipelineAsset.supportsLocalShadows &amp;&amp; hasLocalShadowCastingLight;\n            shadowData.localShadowAtlasWidth = shadowData.localShadowAtlasHeight = pipelineAsset.localShadowAtlasResolution;\n            shadowData.supportsSoftShadows = pipelineAsset.supportsSoftShadows;\n            shadowData.bufferBitCount = 16;\n \n            shadowData.renderedDirectionalShadowQuality = LightShadows.None;\n            shadowData.renderedLocalShadowQuality = LightShadows.None;\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u521d\u59cb\u5316\u5149\u6e90\u6570\u636e\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"visibleLights\">&lt;\/param>\n        \/\/\/ &lt;param name=\"maxSupportedLocalLightsPerPass\">&lt;\/param>\n        \/\/\/ &lt;param name=\"maxSupportedVertexLights\">&lt;\/param>\n        \/\/\/ &lt;param name=\"lightData\">&lt;\/param>\n        void InitializeLightData(List&lt;VisibleLight> visibleLights, int maxSupportedLocalLightsPerPass, int maxSupportedVertexLights, out LightData lightData)\n        {\n            \/\/\u63a7\u5236\u6700\u5927\u53ef\u89c1\u5149\u6e90\u6570\u91cf&lt;=pipelineAsset.maxPixelLights\n            int visibleLightsCount = Math.Min(visibleLights.Count, pipelineAsset.maxPixelLights);\n            lightData.mainLightIndex = GetMainLight(visibleLights);\n \n            \/\/ If we have a main light we don't shade it in the per-object light loop. We also remove it from the per-object cull list\n            int mainLightPresent = (lightData.mainLightIndex >= 0) ? 1 : 0;\n            \/\/\u8ba1\u7b97\u9644\u52a0\u5149\u6570\u91cf\uff0cmaxSupportedLocalLightsPerPasss\u662f4\u621616\n            int additionalPixelLightsCount = Math.Min(visibleLightsCount - mainLightPresent, maxSupportedLocalLightsPerPass);\n            int vertexLightCount = (pipelineAsset.supportsVertexLight) ? Math.Min(visibleLights.Count, maxSupportedLocalLightsPerPass) - additionalPixelLightsCount : 0;\n            \/\/\u8ba1\u7b97\u9010\u9876\u70b9\u5149\u6570\u91cf\uff0cmaxSupportedVertexLights\u662f4\n            vertexLightCount = Math.Min(vertexLightCount, maxSupportedVertexLights);\n \n            \/\/\u9644\u52a0\u5149\u6570\u91cf\n            lightData.pixelAdditionalLightsCount = additionalPixelLightsCount;\n            \/\/\u4e0d\u652f\u6301\u9876\u70b9\u5149\u65f6vertexLightCount\u662f0\uff0c\u6700\u540e\u662fadditionalPixelLightsCount\uff1b\n            \/\/\u652f\u6301\u65f6\u6700\u540e\u662f Math.Min(visibleLights.Count, maxSupportedLocalLightsPerPass)\n            lightData.totalAdditionalLightsCount = additionalPixelLightsCount + vertexLightCount;\n            lightData.visibleLights = visibleLights;\n            lightData.visibleLocalLightIndices = m_LocalLightIndices;\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u67e5\u627e\u7b2c\u4e00\u4e2aDirection\u5149\u6e90\uff0c\u8fd4\u56de\u6570\u7ec4\u4e2d\u7f16\u53f7\uff0c\u82e5\u65e0\u8fd4\u56de-1\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"visibleLights\">&lt;\/param>\n        \/\/\/ &lt;returns>&lt;\/returns>\n        \/\/ Main Light is always a directional light\n        int GetMainLight(List&lt;VisibleLight> visibleLights)\n        {\n            int totalVisibleLights = visibleLights.Count;\n \n            if (totalVisibleLights == 0 || pipelineAsset.maxPixelLights == 0)\n                return -1;\n \n            for (int i = 0; i &lt; totalVisibleLights; ++i)\n            {\n                VisibleLight currLight = visibleLights[i];\n \n                \/\/ Particle system lights have the light property as null. We sort lights so all particles lights\n                \/\/ come last. Therefore, if first light is particle light then all lights are particle lights.\n                \/\/ In this case we either have no main light or already found it.\n                if (currLight.light == null)\n                    break;\n \n                \/\/ In case no shadow light is present we will return the brightest directional light\n                if (currLight.lightType == LightType.Directional)\n                    return i;\n            }\n \n            return -1;\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u8bbe\u7f6e\u6bcf\u5e27\u7684Shader\u5e38\u91cf_GlossyEnvironmentColor\u3001_SubtractiveShadowColor\n        \/\/\/ &lt;\/summary>\n        void SetupPerFrameShaderConstants()\n        {\n            \/\/ When glossy reflections are OFF in the shader we set a constant color to use as indirect specular\n            SphericalHarmonicsL2 ambientSH = RenderSettings.ambientProbe;\n            Color linearGlossyEnvColor = new Color(ambientSH[0, 0], ambientSH[1, 0], ambientSH[2, 0]) * RenderSettings.reflectionIntensity;\n            Color glossyEnvColor = CoreUtils.ConvertLinearToActiveColorSpace(linearGlossyEnvColor);\n            Shader.SetGlobalVector(PerFrameBuffer._GlossyEnvironmentColor, glossyEnvColor);\n \n            \/\/ Used when subtractive mode is selected\n            Shader.SetGlobalVector(PerFrameBuffer._SubtractiveShadowColor, CoreUtils.ConvertSRGBToActiveColorSpace(RenderSettings.subtractiveShadowColor));\n        }\n        \/\/\/ &lt;summary>\n        \/\/\/ \u8bbe\u7f6e\u6bcf\u4e2a\u76f8\u673a\u7684Shader\u5e38\u91cf_ScaledScreenParams\n        \/\/\/ &lt;\/summary>\n        \/\/\/ &lt;param name=\"cameraData\">&lt;\/param>\n        void SetupPerCameraShaderConstants(CameraData cameraData)\n        {\n            float cameraWidth = (float)cameraData.camera.pixelWidth * cameraData.renderScale;\n            float cameraHeight = (float)cameraData.camera.pixelWidth * cameraData.renderScale;\n            Shader.SetGlobalVector(PerCameraBuffer._ScaledScreenParams, new Vector4(cameraWidth, cameraHeight, 1.0f + 1.0f \/ cameraWidth, 1.0f + 1.0f \/ cameraHeight));\n        }\n \n        bool IsStereoEnabled(Camera camera)\n        {\n#if !UNITY_SWITCH\n            bool isSceneViewCamera = camera.cameraType == CameraType.SceneView;\n            return XRSettings.isDeviceActive &amp;&amp; !isSceneViewCamera &amp;&amp; (camera.stereoTargetEye == StereoTargetEyeMask.Both);\n#else\n            return false;\n#endif\n        }\n    }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[18],"_links":{"self":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/1348"}],"collection":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1348"}],"version-history":[{"count":1,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/1348\/revisions"}],"predecessor-version":[{"id":1349,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/1348\/revisions\/1349"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1348"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1348"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1348"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}