You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

将Unity内置渲染管线着色器转换为URP着色器求助

3D Game Kit 内置着色器转URP版本

以下是适配URP的完整着色器代码,完全保留原着色器的顶点位移、透明裁剪、边缘发光等核心效果:

Shader "Custom/3DGameKit_URP_Cutout"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
        _Noise ("Noise Texture", 2D) = "white" {}
        _Gradient ("Gradient Texture", 2D) = "white" {}
        _Normal ("Normal Map", 2D) = "bump" {}
        _MetallicSmooth ("Metallic/Smoothness Map", 2D) = "white" {}
        _AO ("AO Map", 2D) = "white" {}
        _Color ("Tint Color", Color) = (1,1,1,1)
        _EdgeColor1 ("Edge Color", Color) = (1,0,0,1)
        _Emission ("Emission Color", Color) = (0,0,0,1)
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _Cutoff ("Alpha Cutoff", Range(0,1)) = 0.5
        _EdgeSize ("Edge Size", Range(0,1)) = 0.1
        _NoiseStrength ("Noise Strength", Range(0,1)) = 0.5
        _DisplaceAmount ("Displacement Amount", Float) = 0.1
        [Toggle(_USE_GRADIENT_ON)] _UseGradient ("Use Gradient", Float) = 1
    }

    SubShader
    {
        Tags 
        { 
            "Queue"="AlphaTest" 
            "RenderType"="TransparentCutout" 
            "IgnoreProjector"="True"
            "RenderPipeline"="UniversalPipeline"
        }

        Cull Back
        ZWrite On
        ZTest LEqual

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma shader_feature _USE_GRADIENT_ON

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"

            struct Attributes
            {
                float4 positionOS   : POSITION;
                float2 uv_MainTex   : TEXCOORD0;
                float2 uv_Noise     : TEXCOORD1;
                float3 normalOS     : NORMAL;
                float4 color        : COLOR0;
            };

            struct Varyings
            {
                float2 uv_MainTex   : TEXCOORD0;
                float2 uv_Noise     : TEXCOORD1;
                float3 positionWS   : TEXCOORD2;
                float4 positionHCS  : SV_POSITION;
                float3 normalWS     : TEXCOORD3;
                float4 color        : COLOR4;
            };

            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);
            TEXTURE2D(_Noise);
            SAMPLER(sampler_Noise);
            TEXTURE2D(_Gradient);
            SAMPLER(sampler_Gradient);
            TEXTURE2D(_Normal);
            SAMPLER(sampler_Normal);
            TEXTURE2D(_MetallicSmooth);
            SAMPLER(sampler_MetallicSmooth);
            TEXTURE2D(_AO);
            SAMPLER(sampler_AO);

            CBUFFER_START(UnityPerMaterial)
                half _Glossiness, _Metallic, _Cutoff, _EdgeSize, _NoiseStrength, _DisplaceAmount;
                half4 _Color, _EdgeColor1, _Emission;
                float4 _MainTex_ST;
                float4 _Noise_ST;
                float4 _Gradient_ST;
                float4 _Normal_ST;
                float4 _MetallicSmooth_ST;
                float4 _AO_ST;
            CBUFFER_END

            Varyings vert(Attributes input)
            {
                Varyings output;

                // 顶点位移逻辑
                float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
                positionWS.x += _Time.x * 30;
                float4 noiseTex = SAMPLE_TEXTURE2D_LOD(_Noise, sampler_Noise, positionWS.xz * 0.5, 0);
                float4 gradientTex = SAMPLE_TEXTURE2D_LOD(_Gradient, sampler_Gradient, input.uv_MainTex, 0);
                float mask = smoothstep(_Cutoff, _Cutoff - 0.3, 1 - gradientTex.r);
                input.positionOS.xyz += input.normalOS * noiseTex.r * mask * _Cutoff * _DisplaceAmount;

                output.positionHCS = TransformObjectToHClip(input.positionOS.xyz);
                output.uv_MainTex = TRANSFORM_TEX(input.uv_MainTex, _MainTex);
                output.uv_Noise = TRANSFORM_TEX(input.uv_Noise, _Noise);
                output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
                output.normalWS = TransformObjectToWorldNormal(input.normalOS);
                output.color = input.color;

                return output;
            }

            half4 frag(Varyings input) : SV_Target
            {
                half3 noise = SAMPLE_TEXTURE2D(_Noise, sampler_Noise, input.uv_Noise).rgb;
                half4 metallicSmooth = SAMPLE_TEXTURE2D(_MetallicSmooth, sampler_MetallicSmooth, input.uv_MainTex);

                half edge;
                #ifdef _USE_GRADIENT_ON
                    half3 gradient = SAMPLE_TEXTURE2D(_Gradient, sampler_Gradient, input.uv_MainTex).rgb;
                    edge = smoothstep(_Cutoff, _Cutoff - _EdgeSize, 1 - (gradient.r + noise.r * (1 - gradient.r) * _NoiseStrength));
                #else
                    edge = smoothstep(_Cutoff, _Cutoff - _EdgeSize, 1 - noise.r);
                #endif

                // 透明裁剪
                clip(1 - edge - _Cutoff);

                half4 mainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv_MainTex);
                half3 albedo = mainTex.rgb * _Color.rgb;
                half3 emissive = mainTex.a * _Emission.rgb + _EdgeColor1.rgb * edge;
                half occlusion = SAMPLE_TEXTURE2D(_AO, sampler_AO, input.uv_MainTex).r;

                // 法线贴图采样与转换
                half3 normalTS = SAMPLE_TEXTURE2D(_Normal, sampler_Normal, input.uv_MainTex).rgb;
                half3 normalWS = TransformTangentToWorldNormal(normalTS, input.normalWS);
                normalWS = normalize(normalWS);

                // 光照计算
                Light mainLight = GetMainLight();
                half NdotL = saturate(dot(normalWS, mainLight.direction));
                half3 diffuse = albedo * mainLight.color * NdotL;
                half3 specular = SpecularStrength(metallicSmooth.a * _Glossiness, _Metallic) * mainLight.color * pow(NdotL, 16);

                half3 finalColor = diffuse + specular + emissive;
                finalColor *= occlusion;

                return half4(finalColor, 1.0);
            }
            ENDHLSL
        }
    }
    FallBack "Hidden/Universal Render Pipeline/FallbackError"
}

关键修改说明

  • 适配URP渲染管线:添加专属标签并引入URP内置Shader库
  • 替换Surface Shader为URP标准的顶点/片段着色器结构
  • 更新纹理采样API,使用URP的TEXTURE2D/SAMPLER
  • 手动实现Standard光照模型的漫反射与高光计算
  • 完全保留原着色器的顶点位移、边缘发光、透明裁剪逻辑
  • 保留_USE_GRADIENT_ON开关,适配URP着色器变体系统

内容的提问来源于stack exchange,提问作者L T R

火山引擎 最新活动