{"id":5738,"date":"2024-06-25T14:26:40","date_gmt":"2024-06-25T06:26:40","guid":{"rendered":"http:\/\/blog.coolcoding.cn\/?p=5738"},"modified":"2024-06-26T12:24:03","modified_gmt":"2024-06-26T04:24:03","slug":"unity-urp-overdraw%e7%9b%b8%e5%85%b3%e8%ae%b0%e5%bd%95","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=5738","title":{"rendered":"Unity URP Overdraw\u76f8\u5173\u8bb0\u5f55"},"content":{"rendered":"\n<p>\u4e00\u3001\u5b98\u65b9URP\u63d0\u4f9b\u4e86RenderingDebugger\u529f\u80fd\uff0c\u53ef\u4ee5\u5728Game\u89c6\u56fe\u7ed8\u5236\u51faOverdraw\u7684\u5185\u5bb9\uff1b \u4f46\u662f\u6240\u6709\u6d89\u53ca\u7684Shader\u90fd\u9700\u8981\u4fee\u6539<\/p>\n\n\n\n<p>\u4e8c\u3001\u5728Scene\u89c6\u56fe\uff0c\u4ecd\u7136\u53ef\u4ee5\u901a\u8fc7SceneView\u7684SetSceneViewShaderReplace\uff0c\u8fbe\u5230\u5728Scene\u89c6\u56fe\u4e2d\uff0c\u6e32\u67d3\u81ea\u5b9a\u4e49Shader<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"413\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2024\/06\/image-1.png\" alt=\"\" class=\"wp-image-5741\" srcset=\"https:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2024\/06\/image-1.png 730w, https:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2024\/06\/image-1-512x290.png 512w, https:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2024\/06\/image-1-160x90.png 160w\" sizes=\"(max-width: 730px) 100vw, 730px\" \/><\/figure>\n\n\n\n<p>\u505a\u6cd5\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class SceneDebugViews\n{\nprivate static readonly Dictionary&lt;SceneView, SceneView.CameraMode&gt; PreviousCameraMode = new();\n\n&#91;InitializeOnLoadMethod]\npublic static void HookIntoSceneView()\n{\n    EditorApplication.delayCall += () =&gt;\n    {\n        SceneView.ClearUserDefinedCameraModes();\n\n        foreach(var ddm in SceneDebugViewsAsset.Instance.DebugDrawModes)\n        {\n            if ( !string.IsNullOrEmpty(ddm.name) &amp;&amp; !string.IsNullOrEmpty(ddm.category))\n            {\n                SceneView.AddCameraMode(ddm.name, ddm.category);\n            }\n        }\n\n        EditorApplication.update += () =&gt;\n        {\n            foreach (SceneView view in SceneView.sceneViews)\n            {\n                if (!PreviousCameraMode.ContainsKey(view) || PreviousCameraMode&#91;view] != view.cameraMode)\n                {\n                    view.SetSceneViewShaderReplace(GetDrawModeShader(view.cameraMode), \"\");\n                }\n\n                PreviousCameraMode&#91;view] = view.cameraMode;\n            }\n        };\n    };\n}\n\nprivate static Shader GetDrawModeShader(SceneView.CameraMode mode)\n{\n    foreach(var ddm in SceneDebugViewsAsset.Instance.DebugDrawModes)\n    {\n        if (string.IsNullOrEmpty(ddm.name) || mode.name != ddm.name)\n        {\n            continue;\n        }\n\n        Shader shader = ddm.shader;\n        if (shader != null)\n        {\n            return shader;\n        }\n    }\n\n    return null;\n}\n\n&#91;MenuItem(\"GameObject\/SceneCamera\/Follow\", false)]\npublic static void FollowCamera()\n{\n    var obj = Selection.activeObject as GameObject;\n    if ( obj == null)\n    {\n        return;\n    }\n    SetSceneCamTransformData(obj.transform.position, obj.transform.rotation);\n}\n\nstatic public void SetSceneCamTransformData(Vector3 position, Quaternion rotation)\n{\n    var scene_view = UnityEditor.SceneView.lastActiveSceneView;\n    scene_view.rotation = rotation;\n    scene_view.pivot = position + rotation * new Vector3(0, 0, scene_view.cameraDistance);\n    scene_view.Repaint();\n}\n\n&#91;CreateAssetMenu(fileName = \"SceneDebugViews.asset\", menuName = \"ASG\/SceneDebugViewsAsset\")]\npublic class SceneDebugViewsAsset : ScriptableObject\n{\n    &#91;Serializable]\n    public struct CustomDrawMode\n    {\n        public string name;\n        public string category;\n        public Shader shader;\n    }\n\n    public List&lt;CustomDrawMode&gt; DebugDrawModes;\n\n    private static SceneDebugViewsAsset cachedInstance;\n\n\n    public static SceneDebugViewsAsset Instance\n    {\n        get\n        {\n            if (cachedInstance == null)\n            {\n                cachedInstance = AssetDatabase.LoadAssetAtPath&lt;SceneDebugViewsAsset&gt;(\n                        \"SceneDebugViews.asset\");\n            }\n\n            return cachedInstance;\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p>Shader\u53ea\u8f93\u51fa\u900f\u660e\u989c\u8272\u5c31\u884c\u4e86<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Shader \"Hidden\/DebugView\/Overdraw\"\r\n{\r\n    SubShader\r\n    {\r\n        Tags\r\n        {\r\n            \"Queue\"=\"Transparent\" \"RenderType\"=\"Transparent\"\r\n        }\r\n        Pass\r\n        {\r\n            ZWrite Off\r\n            ZTest Always\r\n            Blend One One\r\n\r\n            CGPROGRAM           \r\n            #pragma vertex vert\r\n            #pragma fragment frag\r\n            #include \"UnityCG.cginc\"\r\n            struct appdata\r\n            {\r\n                float4 vertex : POSITION;\r\n            };\r\n            struct v2f\r\n            {\r\n                float4 vertex : SV_POSITION;\r\n            };\r\n            v2f vert (appdata v)\r\n            {\r\n                v2f o;\r\n                o.vertex = UnityObjectToClipPos(v.vertex);\r\n                return o;\r\n            }\r\n            float4 frag() : SV_TARGET \r\n            {\r\n                return fixed4(0.1, 0.04, 0.02, 1);\r\n            }\r\n            ENDCG\r\n        }\r\n    }\r\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u4e00\u3001\u5b98\u65b9URP\u63d0\u4f9b\u4e86RenderingDebugger\u529f\u80fd\uff0c\u53ef\u4ee5\u5728Game\u89c6\u56fe\u7ed8\u5236\u51faOverdraw\u7684\u5185\u5bb9\uff1b  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/5738"}],"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=5738"}],"version-history":[{"count":4,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/5738\/revisions"}],"predecessor-version":[{"id":5744,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/5738\/revisions\/5744"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5738"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5738"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5738"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}