Unity ShaderGraph中Lit转换成URP的LitShader

ShaderGraph中的LitShader如下:

在顶点和片元着色器暴露出了上图中的几个参数,要转换成URPLitShaderLab,首先要找到这几个参数,打开LitShader,找到第一个Pass,可以看到下图中的顶点和片元的定义函数,还有引用的两个库。

打开LitForwardPass.hlsl

顶点着色器如下:

片元着色器代码如下: 

 在ShaderGraph中的片元着色器的几个参数在SurfaceData中,只要在需要改变的时候重写如下函数即可。

最简URP下的Lit Shader代码如下:

Shader "CustomURPLitShaderBase"
{
    Properties
    {

    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Opaque"
            "Queue"="Geometry"
        }
        Pass
        {
            Name "Universal Forward"
            Tags
            {
                "LightMode" = "UniversalForward"
            }
        
        // Render State
        Cull Back
        Blend One Zero
        ZTest LEqual
        ZWrite On
        
        HLSLPROGRAM
        // Pragmas
        #pragma target 4.5
        #pragma exclude_renderers gles gles3 glcore
        #pragma vertex vert
        #pragma fragment frag
        #define _NORMALMAP 1
        
        // Includes
        #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
        
        struct Attributes
        {
             float3 positionOS : POSITION;
             float3 normalOS : NORMAL;
             float4 tangentOS : TANGENT;
             float4 uv1 : TEXCOORD1;
             float4 uv2 : TEXCOORD2;
        };
        struct Varyings
        {
            float4 positionCS : SV_POSITION;
            float3 positionWS : TEXCOORD0;
            float3 normalWS : NORMAL;
            float3 viewDirectionWS : TEXCOORD1;
        };

        void InitializeInputData(Varyings input,out InputData inputData)
        {
            inputData = (InputData)0;
            inputData.positionWS = input.positionWS;
            inputData.normalWS = NormalizeNormalPerPixel(input.normalWS);
            inputData.viewDirectionWS = SafeNormalize(input.viewDirectionWS);
            inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, float3(0,0,0), inputData.normalWS);
            inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
        }

        Varyings vert(Attributes input)
        {
            Varyings output = (Varyings)0;
            //世界空间下的坐标
            float3 positionWS = TransformObjectToWorld(input.positionOS);
            //世界空间下的法线坐标
            output.normalWS = TransformObjectToWorldNormal(input.normalOS);
            output.positionCS = TransformWorldToHClip(positionWS);
            output.viewDirectionWS = GetWorldSpaceViewDir(positionWS);
            return output;
        }

        half4 frag(Varyings unpacked) : SV_TARGET
        {
            InputData inputData;
            InitializeInputData(unpacked,inputData);

            SurfaceData surface;
            #ifdef UNITY_COLORSPACE_GAMMA
                surface.albedo = float3(0.5, 0.5, 0.5);
            #else
                surface.albedo = SRGBToLinear(float3(0.5, 0.5, 0.5));
            #endif
            surface.metallic            = 0;
            surface.specular            = 0;
            surface.smoothness          = 0.5;
            surface.occlusion           = 1;
            surface.emission            = float3(0, 0, 0);
            surface.alpha               = 1;
            surface.normalTS            = half3(0, 0, 0);
            surface.clearCoatMask       = 0;
            surface.clearCoatSmoothness = 1;

            half4 color = UniversalFragmentPBR(inputData, surface);
            return color;
        }        
        ENDHLSL
        }
    }
}

结果:

如果需要显示阴影就在 CustomURPLitShaderBase的Subshader中增加一个阴影的pass即可

      Pass
      {
            Name "ShadowCaster"
            Tags{"LightMode" = "ShadowCaster"}

            ZWrite On
            ZTest LEqual
            ColorMask 0
            Cull[_Cull]

            HLSLPROGRAM
            #pragma exclude_renderers gles gles3 glcore
            #pragma target 4.5

            #pragma vertex ShadowPassVertex
            #pragma fragment ShadowPassFragment

            #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
            ENDHLSL
        }

结果:

<think>嗯,用户问的是如何将内置渲染管线的Shader转换为URP的Shader。首先,我需要回忆一下之前提供的引用内容。引用3提到,URP中使用的是HLSL语言,而内置管线用的是Cg,所以转换的时候需要调整语言部分。另外,引用4和5也提到了一些转换的步骤和注意事项,比如使用URP Asset和ShaderGraph,以及可能遇到的环境问题。 首先,用户可能需要一个步骤指南。根据引用3和4,转换的第一步应该是安装URP包并创建配置文件。然后,需要修改项目设置中的Graphics部分,使用URP Asset。接下来,可能要用到Unity的Render Pipeline Converter工具,这个工具能帮助自动转换部分代码,但可能需要手动调整。 然后,语法差异方面,引用2指出URP Shader使用HLSL内嵌代码,而内置的是Cg,所以需要将Cg代码转成HLSL。同时,光照模型的处理不同,URP可能使用更简化的光照函数,比如Lighting.hlsl中的方法。此外,URP的Shader结构可能更模块化,需要引用核心库如Core.hlsl。 手动调整部分,替换内置的着色器标签,比如把"LightMode"="ForwardBase"改为URP适用的标签。还有,URP不支持某些旧的内置变量,如_LightColor0,需要用新的方法获取光照信息,比如GetMainLight()。 迁移后的验证也很重要,比如检查材质是否正常,测试不同光照环境,以及使用ShaderGraph创建新的Shader。引用5提到,如果渲染效果不对,可能需要考虑灯光、着色器或场景因素,所以测试环节不能少。 可能的问题包括语法不兼容、光照计算差异、纹理采样器变化等,用户需要逐一检查。此外,引用4提到转换过程不可逆,所以备份项目是必要的。 最后,生成相关问题的时候,要围绕转换步骤、语法差异、常见问题、ShaderGraph使用以及回退方案来提问,这样能帮助用户深入理解整个流程。</think>### 如何将内置渲染管线的Shader转换为URP Shader? #### 1. **转换核心步骤** - **安装URP包**:通过Package Manager安装`Universal RP`包,并在项目中创建URP配置文件(`URP Asset`)[^4]。 - **修改渲染管线配置**:在`Project Settings -> Graphics`中指定URP Asset,替换原有内置管线配置。 - **使用转换工具**:通过`Window -> Rendering -> Render Pipeline Converter`运行自动转换工具。该工具会尝试替换内置Shader标签和语法,但部分代码需手动调整。 - **代码迁移**:将内置Shader中的Cg代码(`CGPROGRAM`)替换为HLSL代码,并引用URP核心库(如`Core.hlsl`、`Lighting.hlsl`)[^3][^2]。 #### 2. **关键语法差异** - **语言切换**:内置管线使用Cg语言,URP要求内嵌HLSL代码,例如: ```hlsl // 内置管线 CGPROGRAM #pragma surface surf Lambert // URP HLSLPROGRAM #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" ``` - **光照模型**:URP使用简化的光照函数(如`LightingPhysicallyBased`),需替换内置的`Surface Shader`光照计算逻辑[^1][^5]。 - **着色器标签**:将`"LightMode"="ForwardBase"`改为URP支持的标签(如`"LightMode"="UniversalForward"`)[^3]。 #### 3. **手动调整示例** - **旧版代码**(内置管线): ```hlsl sampler2D _MainTex; float4 _LightColor0; // 内置光照颜色变量 ``` - **URP适配**: ```hlsl TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" // 通过GetMainLight()获取光照信息 ``` #### 4. **迁移后验证** - **检查材质表现**:转换后若材质显示为粉色,说明Shader编译失败,需排查语法或依赖库问题。 - **测试光照兼容性**:URP的光照系统更精简,需验证复杂光照场景下的效果[^1][^5]。 - **使用ShaderGraph**:对于复杂效果,可通过ShaderGraph可视化工具重建Shader逻辑[^4]。 #### 5. **常见问题** - **不兼容语法**:如`unity_WorldToObject`等内置变量需替换为`GetWorldToObjectMatrix()`[^3]。 - **纹理采样器差异**:URP要求使用`TEXTURE2D`+`SAMPLER`宏替代旧版`sampler2D`[^2]。 - **Fallback处理**:删除或替换不兼容的Fallback Shader(如`Diffuse`改为`Universal Render Pipeline/Lit`)[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值