文章

定制ShaderGraph(一)---创建干净的底板

定制ShaderGraph(一)---创建干净的底板

定制ShaderGraph(一)—创建干净的底板

00 前置知识

功能入口

通过搜索Assets/Create/Shader Graph/URP/我们能够找到功能的关键入口类

  • CreateLitShaderGraph

    路径: Library/PackageCache/com.unity.render-pipelines.universal@12.1.10/Editor/ShaderGraph/AssetCallbacks/CreateLitShaderGraph.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    static class CreateLitShaderGraph
        {
            [MenuItem("Assets/Create/Shader Graph/URP/Lit Shader Graph", priority = CoreUtils.Priorities.assetsCreateShaderMenuPriority)]
            public static void CreateLitGraph()
            {
                var target = (UniversalTarget)Activator.CreateInstance(typeof(UniversalTarget));
                target.TrySetActiveSubTarget(typeof(UniversalLitSubTarget));
      
                var blockDescriptors = new[]
                {
                    BlockFields.VertexDescription.Position,
                    BlockFields.VertexDescription.Normal,
                    BlockFields.VertexDescription.Tangent,
                    BlockFields.SurfaceDescription.BaseColor,
                    BlockFields.SurfaceDescription.NormalTS,
                    BlockFields.SurfaceDescription.Metallic,
                    BlockFields.SurfaceDescription.Smoothness,
                    BlockFields.SurfaceDescription.Emission,
                    BlockFields.SurfaceDescription.Occlusion,
                };
      
                GraphUtil.CreateNewGraphWithOutputs(new[] { target }, blockDescriptors);
            }
        }
    

    可以看到, 实际创建的是一个UniversalTarget, 然后通过TrySetActiveSubTarget()方法去将m_ActiveSubTarget赋值为subTarget,

    然后输入blockDescriptors数组就可以构建出最初状态的ShaderGraph着色器.

关键类

  • SubTarget, SubTarget<T>

    路径: Library/PackageCache/com.unity.shadergraph@12.1.10/Editor/Generation/SubTarget.cs

  • UniversalTarget

    路径: Library/PackageCache/com.unity.render-pipelines.universal@12.1.10/Editor/ShaderGraph/Targets/UniversalTarget.cs

  • UniversalLitSubTarget

    路径: Library/PackageCache/com.unity.render-pipelines.universal@12.1.10/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs

01 实施

  • 拷贝关键类CreateLitShaderGraph, UniversalLitSubTarget

  • 制作自己的CreateVehiclePaintShaderGraph

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    static class CreateVehiclePaintShaderGraph
        {
            [MenuItem("Assets/Create/Shader Graph/URP/Vehicle Paint Shader Graph", priority = CoreUtils.Priorities.assetsCreateShaderMenuPriority)]
            public static void CreateVehicleGraph()
            {
                // 基版使用UniversalTarget
                var target = (UniversalTarget)Activator.CreateInstance(typeof(UniversalTarget));
                // SubTarget里面放定制需求
                target.TrySetActiveSubTarget(typeof(UniversalVehiclePaintSubTarget));
                  
                // 定义block块
                var blockDescriptors = new[]
                {
                    BlockFields.VertexDescription.Position,
                    BlockFields.VertexDescription.Normal,
                    BlockFields.VertexDescription.Tangent,
                    BlockFields.SurfaceDescription.BaseColor,
                    BlockFields.SurfaceDescription.NormalTS,
                    BlockFields.SurfaceDescription.Metallic,
                    BlockFields.SurfaceDescription.Smoothness,
                    BlockFields.SurfaceDescription.Emission,
                    BlockFields.SurfaceDescription.Occlusion,
                };
      
                // 创建对象
                GraphUtil.CreateNewGraphWithOutputs(new Target[] { target }, blockDescriptors);
            }
      
        }
    
  • 制作自己的UniversalVehiclePaintSubTarget类, 替换掉guid, 并替换掉名称即可

    1
    2
    3
    4
    5
    6
    7
    
    static readonly GUID kSourceCodeGuid = new GUID("4443eec7cc6a454c86378894f2e8a868"); // UniversalVehiclePaintSubTarget.cs
    ...
    public UniversalVehiclePaintSubTarget()
    {
        // ShaderGraph 的 Material 栏中显示的名字
        displayName = "VehiclePaint";
    }
    

    然后我们就得到了一个可以修改的模板, 并可以在ShaderGraph中选择, 并且在右键菜单进行创建.

    image-20250726133320963

    image-20250726133722824

  • 还可以把里面的各个Region分离为单独的类, 以免整个类太大

    最终我分拆出了这些

    image-20250819132541235

参考网页
本文由作者按照 CC BY 4.0 进行授权