unity如何通过反射调用Editor里的代码

代码如下:

        /// <summary>
        /// 通过反射调用Editor里的静态方法
        /// </summary>
        /// <param name="typeName">命名空间.类名</param>
        /// <param name="staticMethod">静态方法名</param>
        public static void CallEditorMethod(string typeName, string staticMethod, object[] parameters)
        {
#if UNITY_EDITOR
            // 获取编辑器程序集
            Assembly editorAssembly = AppDomain.CurrentDomain.GetAssemblies()
                .FirstOrDefault(a => a.FullName.StartsWith("Assembly-CSharp-Editor,"));
        
            // 获取你的编辑器工具类型(需要知道完整的命名空间)
            System.Type toolType = editorAssembly.GetType(typeName);
        
            if (toolType != null)
            {
                // 调用静态方法
                MethodInfo method = toolType.GetMethod(staticMethod, BindingFlags.Public | BindingFlags.Static);
            
                if (method != null)
                {
                    method.Invoke(null, parameters);
                }
            }
            else
            {
                Debug.LogError($"Cann't find type:{typeName}");
            }
#endif      
        }

 

HairLitInput.hlsl
#ifndef UNIVERSAL_LIT_INPUT_INCLUDED
#define UNIVERSAL_LIT_INPUT_INCLUDED

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"

// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
    half4 _BaseColor;
    half _Cutoff;
    half _BumpScale;
    half _Roughness;

    float _RoughnessOffset;
    float _OcclusionOffset;

    half _Specular1Roughness;
    half4 _Specular1Tint;
    half _Specular1Shift;

    half _Specular2Roughness;
    half4 _Specular2Tint;
    half _Specular2Shift;
CBUFFER_END

TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
TEXTURE2D(_BumpMap);
SAMPLER(sampler_BumpMap);
TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap);


SurfaceData InitializeStandardLitSurfaceData(float2 uv, out float aniso)
{
    SurfaceData surfaceData = (SurfaceData)0;

    half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
    half4 bumpMap = SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv);
    half4 maskMap = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, uv);
    aniso = maskMap.r;

    float3 normalTS = UnpackNormalScale(bumpMap, _BumpScale);

    surfaceData.albedo = baseMap.rgb * _BaseColor.rgb;
    surfaceData.alpha = baseMap.a * _BaseColor.a;
    surfaceData.metallic = 0;
    surfaceData.specular = half3(0.0, 0.0, 0.0);
    surfaceData.smoothness = 1 - saturate(maskMap.g + _RoughnessOffset);
    surfaceData.normalTS = normalTS;
    surfaceData.occlusion = saturate(maskMap.b + _OcclusionOffset);
    surfaceData.emission = 0;
    surfaceData.clearCoatMask = half(0.0);
    surfaceData.clearCoatSmoothness = half(0.0);
    return surfaceData;
}

#endif // UNIVERSAL_INPUT_SURFACE_PBR_INCLUDED


Silk.hlsl
#ifndef CUSTOM_SILK_INPUT_INCLUDED
#define CUSTOM_SILK_INPUT_INCLUDED

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


half _Anisotropic;
half4 _AnisotropicColor;
half _AnisoNormalScale;


struct SilkSurfaceData
{
    half3 tangentDir;
    half3 bitangentDir;
    half anisotropic;
    half4 anisotropicColor;
};

SilkSurfaceData InitializeSilkSurfaceData(half3 normalTS, half3x3 tangentToWorld)
{
    SilkSurfaceData surfaceData = (SilkSurfaceData)0;
    float3 tangentT = normalize(float3(1, 0, _AnisoNormalScale * normalTS.x));
    float3 tangentB = normalize(float3(0, 1, _AnisoNormalScale * normalTS.y));
    surfaceData.tangentDir = TransformTangentToWorld(tangentT, tangentToWorld);
    surfaceData.bitangentDir = TransformTangentToWorld(tangentB, tangentToWorld);
    surfaceData.anisotropic = _Anisotropic;
    surfaceData.anisotropicColor = _AnisotropicColor;
    return surfaceData;
}

float Square(float x)
{
    return x * x;
}

// Anisotropic GGX
// [Burley 2012, "Physically-Based Shading at Disney"]
float D_GGXaniso(float ax, float ay, float NoH, float XoH, float YoH)
{
    // The two formulations are mathematically equivalent
    #if 1
    float a2 = ax * ay;
    float3 V = float3(ay * XoH, ax * YoH, a2 * NoH);
    float S = dot(V, V);

    return (1.0f / PI) * a2 * Square(a2 / S);
    #else
    float d = XoH * XoH / (ax * ax) + YoH * YoH / (ay * ay) + NoH * NoH;
    return 1.0f / (PI * ax * ay * d * d);
    #endif
}

// [Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"]
float Vis_SmithJointAniso(float ax, float ay, float NoV, float NoL, float XoV, float XoL, float YoV, float YoL)
{
    float Vis_SmithV = NoL * length(float3(ax * XoV, ay * YoV, NoV));
    float Vis_SmithL = NoV * length(float3(ax * XoL, ay * YoL, NoL));
    return 0.5 * rcp(Vis_SmithV + Vis_SmithL);
}

half3 SilkSpecular(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, SilkSurfaceData silkSurfaceData)
{
    half3 lightDirectionWS = light.direction;
    half NdotL = saturate(dot(normalWS, lightDirectionWS));

    half3 H = normalize(lightDirectionWS + viewDirectionWS);
    half NoH = saturate(dot(normalWS, H));
    half VoH = saturate(dot(viewDirectionWS, H));
    half NoV = saturate(abs(dot(normalWS, viewDirectionWS)) + 1e-5);

    half XoH = dot(silkSurfaceData.tangentDir, H);
    half YoH = dot(silkSurfaceData.bitangentDir, H);
    half XoL = dot(silkSurfaceData.tangentDir, lightDirectionWS);
    half YoL = dot(silkSurfaceData.bitangentDir, lightDirectionWS);
    half XoV = dot(silkSurfaceData.tangentDir, viewDirectionWS);
    half YoV = dot(silkSurfaceData.bitangentDir, viewDirectionWS);

    // 这里参考UE4代码GetAnisotropicRoughness
    // Anisotropic parameters: ax and ay are the roughness along the tangent and bitangent    
    // Kulla 2017, "Revisiting Physically Based Shading at Imageworks"
    half ax = max(brdfData.roughness2 * (1 + silkSurfaceData.anisotropic), 0.001);
    half ay = max(brdfData.roughness2 * (1 - silkSurfaceData.anisotropic), 0.001);

    // 各向异性高光,参考UE4代码SpecularGGX
    half D = D_GGXaniso(ax, ay, NoH, XoH, YoH);
    half Vis = Vis_SmithJointAniso(ax, ay, NoV, NdotL, XoV, XoL, YoV, YoL);
    //half3 F = F_Schlick(kDielectricSpec.rgb, VoH);
    half3 F = F_Schlick(silkSurfaceData.anisotropicColor.rgb, VoH);
    half3 brdfSpec = clamp(0, 100, D * Vis * F);
    return brdfSpec;
}

half3 GlobalIlluminationCommon(BRDFData brdfData, half3 bakedGI, half occlusion, float3 positionWS,
                               half3 normalWS, half3 viewDirectionWS, float2 normalizedScreenSpaceUV)
{
    half3 reflectVector = reflect(-viewDirectionWS, normalWS);
    half NoV = saturate(dot(normalWS, viewDirectionWS) + 1e-5);
    half fresnelTerm = Pow4(1.0 - NoV);

    half3 indirectDiffuse = bakedGI;
    half3 indirectSpecular = GlossyEnvironmentReflection(reflectVector, positionWS, brdfData.perceptualRoughness, 1.0h, normalizedScreenSpaceUV);
    half3 color = EnvironmentBRDF(brdfData, indirectDiffuse, indirectSpecular, fresnelTerm);
    return color * occlusion;
}

half3 GlobalIlluminationSilk(BRDFData brdfData, half3 bakedGI, half occlusion, float3 positionWS,
                             half3 normalWS, half3 viewDirectionWS, float2 normalizedScreenSpaceUV, SilkSurfaceData silkSurfaceData)
{
    // 这里对Cube进行扭曲拉伸,参考Filament代码getReflectedVector
    float3 anisoDir = silkSurfaceData.anisotropic > 0 ? silkSurfaceData.bitangentDir : silkSurfaceData.tangentDir;
    float3 anisoTangent = cross(viewDirectionWS, anisoDir);
    float3 anisoNormal = cross(anisoTangent, anisoDir);
    float3 bentNormal = normalize(lerp(normalWS, anisoNormal, abs(silkSurfaceData.anisotropic)));

    return GlobalIlluminationCommon(brdfData, bakedGI, occlusion, positionWS, bentNormal, viewDirectionWS, normalizedScreenSpaceUV);
}

half3 GlobalIlluminationSilk(BRDFData brdfData, half3 bakedGI, half occlusion, float3 positionWS,
                             half3 normalWS, half3 viewDirectionWS, float2 normalizedScreenSpaceUV, SilkSurfaceData silkSurfaceData, half silkMask)
{
    // 这里对Cube进行扭曲拉伸,参考Filament代码getReflectedVector
    float3 anisoDir = silkSurfaceData.anisotropic > 0 ? silkSurfaceData.bitangentDir : silkSurfaceData.tangentDir;
    float3 anisoTangent = cross(viewDirectionWS, anisoDir);
    float3 anisoNormal = cross(anisoTangent, anisoDir);
    float3 bentNormal = normalize(lerp(normalWS, anisoNormal, abs(silkSurfaceData.anisotropic)));

    float3 finalNormal = lerp(normalWS, bentNormal, silkMask);
    return GlobalIlluminationCommon(brdfData, bakedGI, occlusion, positionWS, finalNormal, viewDirectionWS, normalizedScreenSpaceUV);
}

#endif


SkinSSS.hlsl
#ifndef CUSTOM_SKINSSS_INPUT_INCLUDED
#define CUSTOM_SKINSSS_INPUT_INCLUDED

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

half4 _SSSColor;

TEXTURE2D(_PreIntegratedSSSMap);
SAMPLER(sampler_PreIntegratedSSSMap);


struct SkinSurfaceData
{
    float2 uv;
    half3x3 tangentToWorld;
    float normalMapMipCount;
};

SkinSurfaceData InitializeSkinSurfaceData(float2 uv, half3x3 tangentToWorld)
{
    SkinSurfaceData skinSurfaceData = (SkinSurfaceData)0;
    skinSurfaceData.uv = uv;
    skinSurfaceData.tangentToWorld = tangentToWorld;
    skinSurfaceData.normalMapMipCount = 12;
    return skinSurfaceData;
}

/// 次表面散射
half3 SubsurfaceScattering(SkinSurfaceData skinSurfaceData, half3 lightDir, TEXTURE2D_PARAM(normalMap, sampler_normalMap))
{
    half3x3 tangentSpaceTransform = skinSurfaceData.tangentToWorld;
    float2 uv = skinSurfaceData.uv;
    int mipCount = skinSurfaceData.normalMapMipCount;
    
    half3 weights = 0.0;
    half scattering = 0.0;
    half NdotL = 0.0;
    half brdfLookup = 0.0;
    half directDiffuse = 0.0;
    half3 brdf = 0.0;
    half3 worldNormal = half3(0, 0, 1);

    // Ref: HDRP's DiffusionProfileSettings.cs #105
    // We importance sample the color channel with the widest scattering distance.
    half radius = max(max(_SSSColor.x, _SSSColor.y), _SSSColor.z);

    /////////////////////////////////////////////////////////////////////
    //                            Skin Profile                           //
    /////////////////////////////////////////////////////////////////////

    half3 c = min(1.0, _SSSColor.xyz);

    // Modified using Color Tint with weight from the highest color value of the human skin profile
    half3 profileWeights[6] = {
        (1 - c) * 0.649,
        (1 - c) * 0.366,
        c * 0.198,
        c * 0.113,
        c * 0.358,
        c * 0.078
    };

    const half profileVariance[6] = {
        0.0064,
        0.0484,
        0.187,
        0.567,
        1.99,
        7.41
    };

    const half profileVarianceSqrt[6] = {
        0.08, // sqrt(0.0064)
        0.219, // sqrt(0.0484)
        0.432, // sqrt(0.187)
        0.753, // sqrt(0.567)
        1.410, // sqrt(1.99)
        2.722
    }; // sqrt(7.41)

    // mip count can be calculate in the shader editor and caches it in material property?
    //int mipCount = GetMipCount(TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));

    // approximation mip level
    half blur = radius * PI * mipCount;

    half r = rcp(radius); // 1 / r
    half s = -r * r;

    /////////////////////////////////////////////////////////////////////
    //                  Six Layer Subsurface Scattering                  //
    /////////////////////////////////////////////////////////////////////
    [unroll]
    for (int i = 0; i < 6; i++)
    {
        weights = profileWeights[i];
        scattering = exp(s / profileVarianceSqrt[i]);

        // #ifdef _NORMALMAP
        // blur normal map via mip
        worldNormal = UnpackNormal(SAMPLE_TEXTURE2D_LOD(normalMap, sampler_normalMap, uv, lerp(0.0, blur, profileVariance[i])));
        worldNormal = TransformTangentToWorld(worldNormal, tangentSpaceTransform);
        // #endif

        // Direct Diffuse Lookup
        NdotL = dot(worldNormal, lightDir);
        brdfLookup = mad(NdotL, 0.5, 0.5);

        directDiffuse = SAMPLE_TEXTURE2D(_PreIntegratedSSSMap, sampler_PreIntegratedSSSMap, float2(brdfLookup, scattering)).r;

        //brdf += weights * (directDiffuse + (pow(1 - dot(normalWS, viewDirectionWS), 3)) *  ao * shadow * half3(0.9, 0.3, 0.1));
        brdf += weights * directDiffuse;
    }

    return brdf;
}


#endif


SilkLighting.hlsl
#ifndef UNIVERSAL_LIGHTING_INCLUDED
#define UNIVERSAL_LIGHTING_INCLUDED

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#include "../ShaderLibs/Silk.hlsl"

#define OUTPUT_SH(normalWS, OUT) OUT.xyz = SampleSHVertex(normalWS)

///////////////////////////////////////////////////////////////////////////////
//                      Lighting Functions                                   //
///////////////////////////////////////////////////////////////////////////////

half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, SilkSurfaceData silkSurfaceData)
{
    half3 lightColor = light.color;
    half3 lightDirectionWS = light.direction;
    half lightAttenuation = light.distanceAttenuation * light.shadowAttenuation;
    half NdotL = saturate(dot(normalWS, lightDirectionWS));
    half3 radiance = lightColor * (lightAttenuation * NdotL);

    half3 brdf = brdfData.diffuse;
    //brdf += brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS);

    half3 brdfSilkSpec = SilkSpecular(brdfData, light, normalWS, viewDirectionWS, silkSurfaceData);
    brdf += brdfSilkSpec;

    return brdf * radiance;
}

struct LightingData
{
    half3 giColor;
    half3 mainLightColor;
    half3 additionalLightsColor;
    half3 vertexLightingColor;
    half3 emissionColor;
};

half3 CalculateLightingColor(LightingData lightingData, half3 albedo)
{
    half3 lightingColor = 0;

    if (IsOnlyAOLightingFeatureEnabled())
    {
        return lightingData.giColor; // Contains white + AO
    }

    if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_GLOBAL_ILLUMINATION))
    {
        lightingColor += lightingData.giColor;
    }

    if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_MAIN_LIGHT))
    {
        lightingColor += lightingData.mainLightColor;
    }

    if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_ADDITIONAL_LIGHTS))
    {
        lightingColor += lightingData.additionalLightsColor;
    }

    if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_VERTEX_LIGHTING))
    {
        lightingColor += lightingData.vertexLightingColor;
    }

    lightingColor *= albedo;

    if (IsLightingFeatureEnabled(DEBUGLIGHTINGFEATUREFLAGS_EMISSION))
    {
        lightingColor += lightingData.emissionColor;
    }

    return lightingColor;
}

half4 CalculateFinalColor(LightingData lightingData, half alpha)
{
    half3 finalColor = CalculateLightingColor(lightingData, 1);

    return half4(finalColor, alpha);
}

LightingData CreateLightingData(InputData inputData, SurfaceData surfaceData)
{
    LightingData lightingData;

    lightingData.giColor = inputData.bakedGI;
    lightingData.emissionColor = surfaceData.emission;
    lightingData.vertexLightingColor = 0;
    lightingData.mainLightColor = 0;
    lightingData.additionalLightsColor = 0;

    return lightingData;
}

///////////////////////////////////////////////////////////////////////////////
//                      Fragment Functions                                   //
//       Used by ShaderGraph and others builtin renderers                    //
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// PBR lighting...
////////////////////////////////////////////////////////////////////////////////
half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData, SilkSurfaceData silkSurfaceData)
{
    BRDFData brdfData;

    // NOTE: can modify "surfaceData"...
    InitializeBRDFData(surfaceData, brdfData);
    
    half4 shadowMask = CalculateShadowMask(inputData);
    AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
    uint meshRenderingLayers = GetMeshRenderingLayer();
    Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);

    // NOTE: We don't apply AO to the GI here because it's done in the lighting calculation below...
    MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI);

    LightingData lightingData = CreateLightingData(inputData, surfaceData);

    lightingData.giColor = GlobalIlluminationSilk(brdfData, inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
                                              inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV, silkSurfaceData);
    
#ifdef _LIGHT_LAYERS
    if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
#endif
    {
        lightingData.mainLightColor = LightingPhysicallyBased(brdfData, mainLight, inputData.normalWS, inputData.viewDirectionWS, silkSurfaceData);
    }

    #if defined(_ADDITIONAL_LIGHTS)
    uint pixelLightCount = GetAdditionalLightsCount();

    LIGHT_LOOP_BEGIN(pixelLightCount)
        Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);

#ifdef _LIGHT_LAYERS
        if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
        {
            lightingData.additionalLightsColor += LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS, silkSurfaceData);
        }
    LIGHT_LOOP_END
    #endif

#if REAL_IS_HALF
    // Clamp any half.inf+ to HALF_MAX
    return min(CalculateFinalColor(lightingData, surfaceData.alpha), HALF_MAX);
#else
    return CalculateFinalColor(lightingData, surfaceData.alpha);
#endif
}

#endif


Shader "Omnee/Role/Silk Lit"
{
    Properties
    {
        [Main(Base, _, off, off)] _BaseGroup("基础设置", float) = 0
        [Sub(Base)] [NoScaleOffset] _BaseMap("Albedo", 2D) = "white" {}
        [Sub(Base)] _BaseColor("Color", Color) = (1,1,1,1)

        [Sub(Base)] _BumpMap("Normal Map", 2D) = "bump" {}
        [Sub(Base)] _NormalScale ("Normal Scale", Range(0, 5)) = 1
        
        [Sub(Base)] _MaskMap("Mask(MRO)", 2D) = "white" {}
        
        [Title(Base, pbr params)]
        [Sub(Base)] _MetallicOffset("金属度偏移", Range(-1, 1)) = 0
        [Sub(Base)] _RoughnessOffset("粗糙度偏移", Range(-1, 1)) = 0
        [Sub(Base)] _OcclusionOffset("环境光遮蔽偏移", Range(-1, 1)) = 0

        [Main(Aniso, _, off, off)] _Aniso("各向异性", float) = 0
        [Sub(Aniso)] _Anisotropic ("各向异性强度", Range(-1, 1)) = 0
        [Sub(Aniso)] [HDR] _AnisotropicColor("各向异性颜色", Color) = (0.04, 0.04, 0.04,1)
        [Sub(Aniso)] _AnisoNormalScale ("各向异性法线强度", Range(0, 5)) = 1
        
        [Main(Preset, _, off, off)] _PresetGroup ("渲染设置", float) = 0
        [Preset(Preset, LWGUI_Preset_BlendMode)] _BlendMode ("Blend Mode", float) = 0
        [SubEnum(Preset, UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 2
        [SubEnum(Preset, UnityEngine.Rendering.BlendMode)] _SrcBlend ("SrcBlend", Float) = 1
        [SubEnum(Preset, UnityEngine.Rendering.BlendMode)] _DstBlend ("DstBlend", Float) = 0
        [SubToggle(Preset)] _ZWrite ("ZWrite ", Float) = 1
    }

    SubShader
    {
        // Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings
        // this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this
        // material work with both Universal Render Pipeline and Builtin Unity Pipeline
        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
            "UniversalMaterialType" = "Lit"
            "IgnoreProjector" = "True"
        }
        LOD 500

        // ------------------------------------------------------------------
        //  Forward pass. Shades all light in a single pass. GI + emission + Fog
        Pass
        {
            // Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
            // no LightMode tag are also rendered by Universal Render Pipeline
            Name "ForwardLit"
            Tags
            {
                "LightMode" = "UniversalForward"
            }

            // -------------------------------------
            // Render State Commands
            Cull [_Cull]
            ZWrite [_ZWrite]
            Blend [_SrcBlend] [_DstBlend]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex LitPassVertex
            #pragma fragment LitPassFragment

            // -------------------------------------
            // Material Keywords

            // -------------------------------------
            // Universal Pipeline keywords
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
            #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
            #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX
            #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
            #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING
            #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION
            #pragma multi_compile_fragment _ _SHADOWS_SOFT
            #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
            #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
            #pragma multi_compile_fragment _ _LIGHT_LAYERS
            #pragma multi_compile_fragment _ _LIGHT_COOKIES
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"


            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile _ SHADOWS_SHADOWMASK
            #pragma multi_compile_fog

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #pragma instancing_options renderinglayer
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

            #include "SilkLitInput.hlsl"
            #include "SilkLitForwardPass.hlsl"
            ENDHLSL
        }

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

            // -------------------------------------
            // Render State Commands
            ZWrite On
            ZTest LEqual
            ColorMask 0
            Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex ShadowPassVertex
            #pragma fragment ShadowPassFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local_fragment _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

            // -------------------------------------
            // Universal Pipeline keywords

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            // This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
            #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW

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

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

            // -------------------------------------
            // Render State Commands
            ZWrite On
            ColorMask R
            Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex DepthOnlyVertex
            #pragma fragment DepthOnlyFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local_fragment _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

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

        // This pass is used when drawing to a _CameraNormalsTexture texture
        Pass
        {
            Name "DepthNormals"
            Tags
            {
                "LightMode" = "DepthNormals"
            }

            // -------------------------------------
            // Render State Commands
            ZWrite On
            Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex DepthNormalsVertex
            #pragma fragment DepthNormalsFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _NORMALMAP
            #pragma shader_feature_local _PARALLAXMAP
            #pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
            #pragma shader_feature_local_fragment _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            // -------------------------------------
            // Universal Pipeline keywords
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

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

    FallBack "Hidden/Universal Render Pipeline/FallbackError"
    CustomEditor "LWGUI.LWGUI"
}


SilkLitForwardPass.hlsl
#ifndef UNIVERSAL_FORWARD_LIT_PASS_INCLUDED
#define UNIVERSAL_FORWARD_LIT_PASS_INCLUDED

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

// keep this file in sync with LitGBufferPass.hlsl

struct Attributes
{
    float4 positionOS   : POSITION;
    float3 normalOS     : NORMAL;
    float4 tangentOS    : TANGENT;
    float2 texcoord     : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct Varyings
{
    float2 uv                       : TEXCOORD0;

    float3 positionWS               : TEXCOORD1;

    float3 normalWS                 : TEXCOORD2;
    half4 tangentWS                 : TEXCOORD3;    // xyz: tangent, w: sign

    half  fogFactor                 : TEXCOORD4;
    half3 vertexSH                  : TEXCOORD5;

    float4 positionCS               : SV_POSITION;
    UNITY_VERTEX_INPUT_INSTANCE_ID
    UNITY_VERTEX_OUTPUT_STEREO
};

InputData InitializeInputData(Varyings input, half3 normalTS)
{
    InputData inputData = (InputData)0;

    inputData.positionWS = input.positionWS;

    half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS);
    float sgn = input.tangentWS.w;      // should be either +1 or -1
    float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz);
    half3x3 tangentToWorld = half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz);

    inputData.tangentToWorld = tangentToWorld;
    inputData.normalWS = TransformTangentToWorld(normalTS, tangentToWorld);

    inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
    inputData.viewDirectionWS = viewDirWS;

    inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
    inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.fogFactor);

    inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS);

    inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
    inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV);

    return inputData;
}

///////////////////////////////////////////////////////////////////////////////
//                  Vertex and Fragment functions                            //
///////////////////////////////////////////////////////////////////////////////

// Used in Standard (Physically Based) shader
Varyings LitPassVertex(Attributes input)
{
    Varyings output = (Varyings)0;

    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_TRANSFER_INSTANCE_ID(input, output);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

    VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);

    // normalWS and tangentWS already normalize.
    // this is required to avoid skewing the direction during interpolation
    // also required for per-vertex lighting and SH evaluation
    VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);

    half fogFactor = 0;
    #if !defined(_FOG_FRAGMENT)
        fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
    #endif

    output.uv = input.texcoord;

    // already normalized from normal transform to WS.
    output.normalWS = normalInput.normalWS;
    real sign = input.tangentOS.w * GetOddNegativeScale();
    half4 tangentWS = half4(normalInput.tangentWS.xyz, sign);
    output.tangentWS = tangentWS;

    OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
    output.fogFactor = fogFactor;

    output.positionWS = vertexInput.positionWS;

    output.positionCS = vertexInput.positionCS;

    return output;
}

// Used in Standard (Physically Based) shader
half4 LitPassFragment(Varyings input) : SV_Target0
{
    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

    SurfaceData surfaceData = InitializeStandardLitSurfaceData(input.uv);
    InputData inputData = InitializeInputData(input, surfaceData.normalTS);
    SilkSurfaceData silkSurfaceData = InitializeSilkSurfaceData(surfaceData.normalTS, inputData.tangentToWorld);

    half4 color = UniversalFragmentPBR(inputData, surfaceData, silkSurfaceData);
    color.rgb = MixFog(color.rgb, inputData.fogCoord);

    return color;
}

#endif


SilkLitInput.hlsl
#ifndef UNIVERSAL_LIT_INPUT_INCLUDED
#define UNIVERSAL_LIT_INPUT_INCLUDED

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"

// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
    half4 _BaseColor;

    float _MetallicOffset;
    float _RoughnessOffset;
    float _OcclusionOffset;

    half _NormalScale;
    half4 _BumpMap_ST;
CBUFFER_END

TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap);

SurfaceData InitializeStandardLitSurfaceData(float2 uv)
{
    SurfaceData outSurfaceData = (SurfaceData)0;

    half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
    half4 maskMap = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, uv);
    half4 normalMap = SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv * _BumpMap_ST.xy + _BumpMap_ST.zw);
    half3 normalTS = UnpackNormalScale(normalMap, _NormalScale);

    outSurfaceData.albedo = baseMap.rgb * _BaseColor.rgb;
    outSurfaceData.alpha = baseMap.a * _BaseColor.a;

    outSurfaceData.metallic = saturate(maskMap.r + _MetallicOffset);
    outSurfaceData.specular = half3(0.0, 0.0, 0.0);

    outSurfaceData.smoothness = 1 - saturate(maskMap.g + _RoughnessOffset);
    outSurfaceData.normalTS = normalTS;
    outSurfaceData.occlusion = saturate(maskMap.b + _OcclusionOffset);
    outSurfaceData.emission = 0;

    outSurfaceData.clearCoatMask = half(0.0);
    outSurfaceData.clearCoatSmoothness = half(0.0);

    return outSurfaceData;
}

#endif // UNIVERSAL_INPUT_SURFACE_PBR_INCLUDED


SkinLighting.hlsl
#ifndef UNIVERSAL_LIGHTING_INCLUDED
#define UNIVERSAL_LIGHTING_INCLUDED

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#include "../ShaderLibs/SkinSSS.hlsl"


///////////////////////////////////////////////////////////////////////////////
//                      Lighting Functions                                   //
///////////////////////////////////////////////////////////////////////////////

half3 LightingPhysicallySSS(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, SkinSurfaceData skinSurfaceData)
{
    half3 lightColor = light.color;
    half3 lightDirectionWS = light.direction;
    half lightAttenuation = light.distanceAttenuation * light.shadowAttenuation;

    half3 brdf = brdfData.diffuse;
    brdf += brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS);

    #if _USESSS_ON
    // 次表面散射
    half3 sss = SubsurfaceScattering(skinSurfaceData, lightDirectionWS, TEXTURE2D_ARGS(_NormalMap, sampler_NormalMap));
    half3 radiance = sss * lightColor * lightAttenuation;
    #else
    half NdotL = saturate(dot(normalWS, lightDirectionWS));
    half3 radiance = lightColor * (lightAttenuation * NdotL);
    #endif

    return brdf * radiance;;
}

half3 SkinGlobalIllumination(BRDFData brdfData, half3 bakedGI, half occlusion, float3 positionWS,
                             half3 normalWS, half3 viewDirectionWS, float2 normalizedScreenSpaceUV)
{
    half3 reflectVector = reflect(-viewDirectionWS, normalWS);
    half NoV = saturate(dot(normalWS, viewDirectionWS));
    half fresnelTerm = Pow4(1.0 - NoV);

    half3 indirectDiffuse = bakedGI;
    half3 indirectSpecular = GlossyEnvironmentReflection(reflectVector, positionWS, brdfData.perceptualRoughness, 1.0h, normalizedScreenSpaceUV);
    half3 color = EnvironmentBRDF(brdfData, indirectDiffuse, indirectSpecular, fresnelTerm);
    return color * occlusion;
}

half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData, SkinSurfaceData skinSurfaceData)
{
    BRDFData brdfData;

    // NOTE: can modify "surfaceData"...
    InitializeBRDFData(surfaceData, brdfData);

    // Clear-coat calculation...
    half4 shadowMask = CalculateShadowMask(inputData);
    AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
    //uint meshRenderingLayers = GetMeshRenderingLayer();
    Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);

    half3 giColor = SkinGlobalIllumination(brdfData, inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
                                           inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV);
    half3 mainLightColor = LightingPhysicallySSS(brdfData, mainLight, inputData.normalWS, inputData.viewDirectionWS, skinSurfaceData);

    half3 addLightColor = 0;
    uint pixelLightCount = GetAdditionalLightsCount();

    LIGHT_LOOP_BEGIN(pixelLightCount)
        Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);

#ifdef _LIGHT_LAYERS
        if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
#endif
        {
            addLightColor += LightingPhysicallySSS(brdfData, light, inputData.normalWS, inputData.viewDirectionWS, skinSurfaceData);
        }
    LIGHT_LOOP_END

    half4 color;
    color.rgb = giColor + mainLightColor + addLightColor;
    color.a = surfaceData.alpha;
    return color;
}

#endif


Shader "Omnee/Role/Skin Lit"
{
    Properties
    {
        [Main(Base, _, off, off)] _BaseGroup ("基础设置", float) = 0
        [Sub(Base)] [NoScaleOffset] _BaseMap("颜色图", 2D) = "white" {}
        [Sub(Base)] _BaseColor("颜色", Color) = (1,1,1,1)
        [Sub(Base)] [NoScaleOffset] _NormalMap("法线图", 2D) = "bump" {}
        [Sub(Base)] _NormalScale("法线强度", Float) = 1.0
        [Sub(Base)] [NoScaleOffset] _MaskMap("遮罩图(R:边缘光MatCap RG,G:粗糙度,B:环境光遮蔽,A:边缘光MatCap B)", 2D) = "white" {}

        [Title(Base, pbr params)]
        //[Sub(Base)] _MetallicOffset("金属度偏移", Range(-1, 1)) = 0
        [Sub(Base)] _RoughnessOffset("粗糙度偏移", Range(-1, 1)) = 0
        [Sub(Base)] _OcclusionOffset("环境光遮蔽偏移", Range(-1, 1)) = 0

        [Main(SSS, _USESSS_ON, off)] _SSSGroup ("次表面散射", float) = 0
        [Sub(SSS)] [NoScaleOffset] _PreIntegratedSSSMap("PreIntegrated SSS Map", 2D) = "white" {}
        [Sub(SSS)] _SSSColor("SSS Color", Color) = (1,0.6637605,0.572327,1)

        [Main(Rim, _USERIM_ON, off)] _RimGroup("边缘光", float) = 0
        [Sub(Rim)] [NoScaleOffset] _MatCapMap("MatCap R通道:左边范围 G通道:右边范围 B通道:左边增强", 2D) = "black" {}
        [SubToggle(Rim, _ROTATEMATCAP_ON)] _UseRotateMatcap("旋转matcap", float) = 0
        [Sub(Rim_ROTATEMATCAP_ON)] _MatCapAngle("旋转", Range(0, 360)) = 0
        [Sub(Rim)] [HDR] _LeftRimColor("左边Rim颜色",Color) = (0.7490,0.5568,0.43252,1)
        [Sub(Rim)] _LeftRimColorIntensity("左边Rim颜色强度", Range(0, 3)) = 2
        [Sub(Rim)] [HDR] _RightRimColor("右边Rim颜色",Color) = (0.4196,0.5725,0.9333,1)
        [Sub(Rim)] _RightRimColorIntensity("右边Rim颜色强度", Range(0, 3)) = 2
        [Sub(Rim)] [HDR] _CentreRimColor("中间Rim颜色",Color) = (0,0,0,1)
        [Sub(Rim)] _CentreRimColorIntensity("中间Rim颜色强度", Range(0, 3)) = 0
    }

    SubShader
    {
        // Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings
        // this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this
        // material work with both Universal Render Pipeline and Builtin Unity Pipeline
        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
            "UniversalMaterialType" = "Lit"
            "IgnoreProjector" = "True"
            "Queue" = "Geometry"
        }
        LOD 300

        // ------------------------------------------------------------------
        //  Forward pass. Shades all light in a single pass. GI + emission + Fog
        Pass
        {
            // Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
            // no LightMode tag are also rendered by Universal Render Pipeline
            Name "ForwardLit"
            Tags
            {
                "LightMode" = "UniversalForward"
            }

            // -------------------------------------
            // Render State Commands
            //Cull [_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex LitPassVertex
            #pragma fragment LitPassFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local_fragment _USESSS_ON
            #pragma shader_feature_local_fragment _USERIM_ON
            #pragma shader_feature_local_fragment _ROTATEMATCAP_ON

            // -------------------------------------
            // Universal Pipeline keywords
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
            #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
            #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX
            #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
            #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING
            #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION
            #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH
            #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
            #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
            #pragma multi_compile_fragment _ _LIGHT_COOKIES
            #pragma multi_compile _ _LIGHT_LAYERS
            #pragma multi_compile _ _FORWARD_PLUS
            #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"


            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
            #pragma multi_compile _ SHADOWS_SHADOWMASK
            #pragma multi_compile _ DIRLIGHTMAP_COMBINED
            #pragma multi_compile _ LIGHTMAP_ON
            #pragma multi_compile _ DYNAMICLIGHTMAP_ON
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE
            #pragma multi_compile_fog

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #pragma instancing_options renderinglayer
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

            #include "SkinLitInput.hlsl"
            #include "SkinLitForwardPass.hlsl"
            ENDHLSL
        }

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

            // -------------------------------------
            // Render State Commands
            ZWrite On
            ZTest LEqual
            ColorMask 0
            //Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex ShadowPassVertex
            #pragma fragment ShadowPassFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

            // -------------------------------------
            // Universal Pipeline keywords

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            // This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
            #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW

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

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

            // -------------------------------------
            // Render State Commands
            ZWrite On
            ColorMask R
            //Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex DepthOnlyVertex
            #pragma fragment DepthOnlyFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

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

        // This pass is used when drawing to a _CameraNormalsTexture texture
        Pass
        {
            Name "DepthNormals"
            Tags
            {
                "LightMode" = "DepthNormals"
            }

            // -------------------------------------
            // Render State Commands
            ZWrite On
            //Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex DepthNormalsVertex
            #pragma fragment DepthNormalsFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _NORMALMAP
            #pragma shader_feature_local _PARALLAXMAP
            #pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
            #pragma shader_feature_local _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            // -------------------------------------
            // Universal Pipeline keywords
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

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

    }

    FallBack "Hidden/Universal Render Pipeline/FallbackError"
    CustomEditor "LWGUI.LWGUI"
}

SkinLitForwardPass.hlsl
#ifndef UNIVERSAL_FORWARD_LIT_PASS_INCLUDED
#define UNIVERSAL_FORWARD_LIT_PASS_INCLUDED

#include "SkinLighting.hlsl"
#include "Assets/AssetArt/Shaders/ShaderLibs/MatcapRimInput.hlsl"
#if defined(LOD_FADE_CROSSFADE)
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl"
#endif

struct Attributes
{
    float4 positionOS : POSITION;
    float3 normalOS : NORMAL;
    float4 tangentOS : TANGENT;
    float2 texcoord : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct Varyings
{
    float4 positionCS : SV_POSITION;
    float2 uv : TEXCOORD0;
    float3 positionWS : TEXCOORD1;
    float3 normalWS : TEXCOORD2;
    half4 tangentWS : TEXCOORD3; // xyz: tangent, w: sign
    float4 bitangentWS : TEXCOORD4; // xyz: bitangent, w: fogFactor

    UNITY_VERTEX_INPUT_INSTANCE_ID
};

InputData InitializeInputData(Varyings input, half3 normalTS)
{
    InputData inputData = (InputData)0;

    inputData.positionWS = input.positionWS;

    half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS);
    half3x3 tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz);

    inputData.tangentToWorld = tangentToWorld;
    inputData.normalWS = TransformTangentToWorld(normalTS, tangentToWorld);

    inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
    inputData.viewDirectionWS = viewDirWS;

    inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
    inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.bitangentWS.w);

    inputData.bakedGI = SampleSH(inputData.normalWS);

    inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
    inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV);

    return inputData;
}

///////////////////////////////////////////////////////////////////////////////
//                  Vertex and Fragment functions                            //
///////////////////////////////////////////////////////////////////////////////

// Used in Standard (Physically Based) shader
Varyings LitPassVertex(Attributes input)
{
    Varyings output = (Varyings)0;

    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_TRANSFER_INSTANCE_ID(input, output);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

    VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);

    // normalWS and tangentWS already normalize.
    // this is required to avoid skewing the direction during interpolation
    // also required for per-vertex lighting and SH evaluation
    VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);

    half fogFactor = 0;
    #if !defined(_FOG_FRAGMENT)
    fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
    #endif

    output.uv = input.texcoord;

    // already normalized from normal transform to WS.
    output.normalWS = normalInput.normalWS;
    real sign = input.tangentOS.w * GetOddNegativeScale();
    output.tangentWS = half4(normalInput.tangentWS.xyz, sign);
    output.bitangentWS.xyz = normalInput.bitangentWS;
    output.bitangentWS.w = fogFactor;

    output.positionWS = vertexInput.positionWS;
    output.positionCS = vertexInput.positionCS;

    return output;
}

// Used in Standard (Physically Based) shader
half4 LitPassFragment(
    Varyings input
    #ifdef _WRITE_RENDERING_LAYERS
    , out float4 outRenderingLayers : SV_Target1
    #endif
) : SV_Target0
{
    UNITY_SETUP_INSTANCE_ID(input);

    float2 rimMask;
    SurfaceData surfaceData = InitializeStandardLitSurfaceData(input.uv, rimMask);

    #ifdef LOD_FADE_CROSSFADE
    LODFadeCrossFade(input.positionCS);
    #endif

    InputData inputData = InitializeInputData(input, surfaceData.normalTS);

    #ifdef _DBUFFER
    ApplyDecalToSurfaceData(input.positionCS, surfaceData, inputData);
    #endif

    SkinSurfaceData skinSurfaceData = InitializeSkinSurfaceData(input.uv, inputData.tangentToWorld);
    half4 color = UniversalFragmentPBR(inputData, surfaceData, skinSurfaceData);
    
    //边缘光
    #if _USERIM_ON
    half3 rimColor = CalcMatCapRimColor(inputData.viewDirectionWS, inputData.normalWS, surfaceData.occlusion, rimMask);
    color.rgb += rimColor;
    #endif
    
    color.rgb = MixFog(color.rgb, inputData.fogCoord);

    #ifdef _WRITE_RENDERING_LAYERS
    uint renderingLayers = GetMeshRenderingLayer();
    outRenderingLayers = float4(EncodeMeshRenderingLayer(renderingLayers), 0, 0, 0);
    #endif

    return color;
}

#endif


SkinLitInput.hlsl
#ifndef UNIVERSAL_LIT_INPUT_INCLUDED
#define UNIVERSAL_LIT_INPUT_INCLUDED

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"

// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
    half4 _BaseColor;
    float _NormalScale;
    //float _MetallicOffset;
    float _RoughnessOffset;
    float _OcclusionOffset;
CBUFFER_END

TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap);

SurfaceData InitializeStandardLitSurfaceData(float2 uv, out float2 rimMask)
{
    SurfaceData outSurfaceData = (SurfaceData)0;

    half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
    half4 bumpMap = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, uv);
    half4 maskMap = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, uv); // R:边缘光MatCap RG,G:粗糙度,B:环境光遮蔽,A:边缘光MatCap B
    rimMask = float2(maskMap.r, maskMap.a);

    float3 normalTS = UnpackNormalScale(bumpMap, _NormalScale);

    outSurfaceData.albedo = baseMap.rgb * _BaseColor.rgb;
    outSurfaceData.alpha = 1;
    outSurfaceData.metallic = 0;
    outSurfaceData.specular = half3(0.0, 0.0, 0.0);
    outSurfaceData.smoothness = 1 - saturate(maskMap.g + _RoughnessOffset);
    outSurfaceData.normalTS = normalTS;
    outSurfaceData.occlusion = saturate(maskMap.b + _OcclusionOffset);
    outSurfaceData.emission = 0;

    outSurfaceData.clearCoatMask = half(0.0);
    outSurfaceData.clearCoatSmoothness = half(0.0);

    return outSurfaceData;
}

#endif // UNIVERSAL_INPUT_SURFACE_PBR_INCLUDED


SockLighting.hlsl
#ifndef UNIVERSAL_LIGHTING_INCLUDED
#define UNIVERSAL_LIGHTING_INCLUDED

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#include "../ShaderLibs/Silk.hlsl"
#include "../ShaderLibs/SkinSSS.hlsl"


struct SockSurfaceData
{
    SilkSurfaceData silkSurfaceData;
    SkinSurfaceData skinSurfaceData;
    float skinMask;
    float silkMask;
};

SockSurfaceData InitializeSockSurfaceData(float2 uv, half3 normalTS, half3x3 tangentToWorld, float skinMask)
{
    SockSurfaceData surfaceData = (SockSurfaceData)0;
    surfaceData.silkSurfaceData = InitializeSilkSurfaceData(normalTS, tangentToWorld);
    surfaceData.skinSurfaceData = InitializeSkinSurfaceData(uv, tangentToWorld);
    surfaceData.skinMask = skinMask;
    surfaceData.silkMask = 1 - skinMask;
    return surfaceData;
}

half3 LightingPhysicallyBased(BRDFData brdfData, Light light, half3 normalWS, half3 viewDirectionWS, SockSurfaceData sockSurfaceData)
{
    half3 lightColor = light.color;
    half3 lightDirectionWS = light.direction;
    half lightAttenuation = light.distanceAttenuation * light.shadowAttenuation;

    half NdotL = saturate(dot(normalWS, lightDirectionWS));
    half3 radianceCommon = lightColor * (lightAttenuation * NdotL);
    half3 sss = SubsurfaceScattering(sockSurfaceData.skinSurfaceData, lightDirectionWS, TEXTURE2D_ARGS(_NormalMap, sampler_NormalMap));
    half3 radianceSkinSSS = sss * lightColor * lightAttenuation;
    half3 radiance = lerp(radianceSkinSSS, radianceCommon, sockSurfaceData.silkMask);
    
    half3 brdf = brdfData.diffuse;
    
    // specular
    half3 brdfSpecularPBR = brdfData.specular * DirectBRDFSpecular(brdfData, normalWS, lightDirectionWS, viewDirectionWS);
    half3 brdfSilkSpec = SilkSpecular(brdfData, light, normalWS, viewDirectionWS, sockSurfaceData.silkSurfaceData);
    half3 brdfFinalSpec = lerp(brdfSpecularPBR, brdfSilkSpec, sockSurfaceData.silkMask);
    brdf += brdfFinalSpec;

    return brdf * radiance;
}

// PBR lighting...
half4 UniversalFragmentPBR(InputData inputData, SurfaceData surfaceData, SockSurfaceData sockSurfaceData)
{
    BRDFData brdfData;

    // NOTE: can modify "surfaceData"...
    InitializeBRDFData(surfaceData, brdfData);

    half4 shadowMask = CalculateShadowMask(inputData);
    AmbientOcclusionFactor aoFactor = CreateAmbientOcclusionFactor(inputData, surfaceData);
    uint meshRenderingLayers = GetMeshRenderingLayer();
    Light mainLight = GetMainLight(inputData, shadowMask, aoFactor);

    half3 giColor = GlobalIlluminationSilk(brdfData, inputData.bakedGI, aoFactor.indirectAmbientOcclusion, inputData.positionWS,
                                           inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV,
                                           sockSurfaceData.silkSurfaceData, sockSurfaceData.silkMask);
    
    half3 mainLightColor = 0;
    half3 additionalLightsColor = 0;
    #ifdef _LIGHT_LAYERS
    if (IsMatchingLightLayer(mainLight.layerMask, meshRenderingLayers))
    #endif
    {
        mainLightColor = LightingPhysicallyBased(brdfData, mainLight, inputData.normalWS, inputData.viewDirectionWS, sockSurfaceData);
    }

    #if defined(_ADDITIONAL_LIGHTS)
    uint pixelLightCount = GetAdditionalLightsCount();

    LIGHT_LOOP_BEGIN(pixelLightCount)
    Light light = GetAdditionalLight(lightIndex, inputData, shadowMask, aoFactor);

    #ifdef _LIGHT_LAYERS
    if (IsMatchingLightLayer(light.layerMask, meshRenderingLayers))
    #endif
    {
        additionalLightsColor += LightingPhysicallyBased(brdfData, light, inputData.normalWS, inputData.viewDirectionWS, sockSurfaceData);
    }
    LIGHT_LOOP_END
    #endif

    half3 color = giColor + mainLightColor + additionalLightsColor + surfaceData.emission;
    return half4(color, surfaceData.alpha);
}

#endif


Shader "Omnee/Role/Sock Lit"
{
    Properties
    {
        [Main(Base, _, off, off)] _BaseGroup("基础设置", float) = 0
        [Sub(Base)] [NoScaleOffset] _BaseMap("Albedo", 2D) = "white" {}
        [Sub(Base)] _BaseColor("Color", Color) = (1,1,1,1)

        [Sub(Base)] [NoScaleOffset] _NormalMap("Normal Map", 2D) = "bump" {}
        [Sub(Base)] _NormalScale ("Normal Scale", Range(0, 5)) = 1
        
        [Sub(Base)] [NoScaleOffset] _PBRMaskMap("PBR Mask %R:金属度, G:粗糙度, B:环境光遮蔽%", 2D) = "white" {}
        [Sub(Base)] [NoScaleOffset] _MaskMap("Mask %R:边缘光MatCap RG, G:边缘光MatCap B, B:皮肤%", 2D) = "white" {}
        
        [Title(Silk)]
        [SubToggle(Base, _USESILKDETAILNORMAL_ON)] _UseSilkDetailNormal("使用丝袜细节法线?", float) = 0
        [Sub(Base_USESILKDETAILNORMAL_ON)] _SilkDetailNormalMap("Silk detail Normal Map", 2D) = "bump" {}
        [Sub(Base_USESILKDETAILNORMAL_ON)] _SilkDetailNormalScale ("Silk Detail Normal Scale", Range(0, 5)) = 1
        
        [Title(Base, pbr params)]
        [Sub(Base)] _MetallicOffset("金属度偏移", Range(-1, 1)) = 0
        [Sub(Base)] _RoughnessOffset("粗糙度偏移", Range(-1, 1)) = 0
        [Sub(Base)] _OcclusionOffset("环境光遮蔽偏移", Range(-1, 1)) = 0

        [Main(SSS, _, off, off)] _SSSGroup ("次表面散射", float) = 0
        [Sub(SSS)] [NoScaleOffset] _PreIntegratedSSSMap("PreIntegrated SSS Map", 2D) = "white" {}
        [Sub(SSS)] _SSSColor("SSS Color", Color) = (1,0.6637605,0.572327,1)
        
        [Main(Aniso, _, off, off)] _Aniso("各向异性", float) = 0
        [Sub(Aniso)] _Anisotropic ("各向异性强度", Range(-1, 1)) = 0
        [Sub(Aniso)] [HDR] _AnisotropicColor("各向异性颜色", Color) = (0.04, 0.04, 0.04,1)
        [Sub(Aniso)] _AnisoNormalScale ("各向异性法线强度", Range(0, 5)) = 1
        
        [Main(Rim, _USERIM_ON, off)] _RimGroup("边缘光", float) = 0
        [Sub(Rim)] [NoScaleOffset] _MatCapMap("MatCap R通道:左边范围 G通道:右边范围 B通道:左边增强", 2D) = "black" {}
        [SubToggle(Rim, _ROTATEMATCAP_ON)] _UseRotateMatcap("旋转matcap", float) = 0
        [Sub(Rim_ROTATEMATCAP_ON)] _MatCapAngle("旋转", Range(0, 360)) = 0
        [Sub(Rim)] [HDR] _LeftRimColor("左边Rim颜色",Color) = (0.7490,0.5568,0.43252,1)
        [Sub(Rim)] _LeftRimColorIntensity("左边Rim颜色强度", Range(0, 3)) = 2
        [Sub(Rim)] [HDR] _RightRimColor("右边Rim颜色",Color) = (0.4196,0.5725,0.9333,1)
        [Sub(Rim)] _RightRimColorIntensity("右边Rim颜色强度", Range(0, 3)) = 2
        [Sub(Rim)] [HDR] _CentreRimColor("中间Rim颜色",Color) = (0,0,0,1)
        [Sub(Rim)] _CentreRimColorIntensity("中间Rim颜色强度", Range(0, 3)) = 0
        
        [Main(Preset, _, off, off)] _PresetGroup ("渲染设置", float) = 0
        [Preset(Preset, LWGUI_Preset_BlendMode)] _BlendMode ("Blend Mode", float) = 0
        [SubEnum(Preset, UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 2
        [SubEnum(Preset, UnityEngine.Rendering.BlendMode)] _SrcBlend ("SrcBlend", Float) = 1
        [SubEnum(Preset, UnityEngine.Rendering.BlendMode)] _DstBlend ("DstBlend", Float) = 0
        [SubToggle(Preset)] _ZWrite ("ZWrite ", Float) = 1
    }

    SubShader
    {
        // Universal Pipeline tag is required. If Universal render pipeline is not set in the graphics settings
        // this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this
        // material work with both Universal Render Pipeline and Builtin Unity Pipeline
        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
            "UniversalMaterialType" = "Lit"
            "IgnoreProjector" = "True"
        }
        LOD 500

        // ------------------------------------------------------------------
        //  Forward pass. Shades all light in a single pass. GI + emission + Fog
        Pass
        {
            // Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
            // no LightMode tag are also rendered by Universal Render Pipeline
            Name "ForwardLit"
            Tags
            {
                "LightMode" = "UniversalForward"
            }

            // -------------------------------------
            // Render State Commands
            Cull [_Cull]
            ZWrite [_ZWrite]
            Blend [_SrcBlend] [_DstBlend]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex LitPassVertex
            #pragma fragment LitPassFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local_fragment _USERIM_ON
            #pragma shader_feature_local_fragment _ROTATEMATCAP_ON
            #pragma shader_feature_local_fragment _USESILKDETAILNORMAL_ON

            // -------------------------------------
            // Universal Pipeline keywords
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
            #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
            #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX
            #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
            #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING
            #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION
            #pragma multi_compile_fragment _ _SHADOWS_SOFT
            #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
            #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
            #pragma multi_compile_fragment _ _LIGHT_LAYERS
            #pragma multi_compile_fragment _ _LIGHT_COOKIES
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"


            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile _ SHADOWS_SHADOWMASK
            #pragma multi_compile_fog

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #pragma instancing_options renderinglayer
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

            #include "SockLitInput.hlsl"
            #include "SockLitForwardPass.hlsl"
            ENDHLSL
        }

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

            // -------------------------------------
            // Render State Commands
            ZWrite On
            ZTest LEqual
            ColorMask 0
            Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex ShadowPassVertex
            #pragma fragment ShadowPassFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local_fragment _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

            // -------------------------------------
            // Universal Pipeline keywords

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            // This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
            #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW

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

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

            // -------------------------------------
            // Render State Commands
            ZWrite On
            ColorMask R
            Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex DepthOnlyVertex
            #pragma fragment DepthOnlyFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local_fragment _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

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

        // This pass is used when drawing to a _CameraNormalsTexture texture
        Pass
        {
            Name "DepthNormals"
            Tags
            {
                "LightMode" = "DepthNormals"
            }

            // -------------------------------------
            // Render State Commands
            ZWrite On
            Cull[_Cull]

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex DepthNormalsVertex
            #pragma fragment DepthNormalsFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _NORMALMAP
            #pragma shader_feature_local _PARALLAXMAP
            #pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
            #pragma shader_feature_local_fragment _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE

            // -------------------------------------
            // Universal Pipeline keywords
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl"

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"

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

    FallBack "Hidden/Universal Render Pipeline/FallbackError"
    CustomEditor "LWGUI.LWGUI"
}


SockLitForwardPass.hlsl
#ifndef UNIVERSAL_FORWARD_LIT_PASS_INCLUDED
#define UNIVERSAL_FORWARD_LIT_PASS_INCLUDED

//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "SockLighting.hlsl"
#include "Assets/AssetArt/Shaders/ShaderLibs/MatcapRimInput.hlsl"

// keep this file in sync with LitGBufferPass.hlsl

struct Attributes
{
    float4 positionOS : POSITION;
    float3 normalOS : NORMAL;
    float4 tangentOS : TANGENT;
    float2 texcoord : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct Varyings
{
    float4 positionCS : SV_POSITION;
    float2 uv : TEXCOORD0;
    float3 positionWS : TEXCOORD1;
    float3 normalWS : TEXCOORD2;
    half4 tangentWS : TEXCOORD3; // xyz: tangent, w: sign
    float4 bitangentWS : TEXCOORD4;

    UNITY_VERTEX_INPUT_INSTANCE_ID
    UNITY_VERTEX_OUTPUT_STEREO
};

InputData InitializeInputData(Varyings input, half3 normalTS)
{
    InputData inputData = (InputData)0;

    inputData.positionWS = input.positionWS;

    half3 viewDirWS = GetWorldSpaceNormalizeViewDir(input.positionWS);
    half3x3 tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz);

    inputData.tangentToWorld = tangentToWorld;
    inputData.normalWS = TransformTangentToWorld(normalTS, tangentToWorld);

    inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
    inputData.viewDirectionWS = viewDirWS;

    inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
    inputData.fogCoord = InitializeInputDataFog(float4(input.positionWS, 1.0), input.bitangentWS.w);

    inputData.bakedGI = SampleSH(inputData.normalWS);

    inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
    inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV);

    return inputData;
}

///////////////////////////////////////////////////////////////////////////////
//                  Vertex and Fragment functions                            //
///////////////////////////////////////////////////////////////////////////////

// Used in Standard (Physically Based) shader
Varyings LitPassVertex(Attributes input)
{
    Varyings output = (Varyings)0;

    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_TRANSFER_INSTANCE_ID(input, output);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

    VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);

    // normalWS and tangentWS already normalize.
    // this is required to avoid skewing the direction during interpolation
    // also required for per-vertex lighting and SH evaluation
    VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);

    half fogFactor = 0;
    #if !defined(_FOG_FRAGMENT)
    fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
    #endif

    output.uv = input.texcoord;

    // already normalized from normal transform to WS.
    output.normalWS = normalInput.normalWS;
    real sign = input.tangentOS.w * GetOddNegativeScale();
    half4 tangentWS = half4(normalInput.tangentWS.xyz, sign);
    output.tangentWS = tangentWS;

    output.bitangentWS.xyz = normalInput.bitangentWS;
    output.bitangentWS.w = fogFactor;

    output.positionWS = vertexInput.positionWS;

    output.positionCS = vertexInput.positionCS;

    return output;
}

// Used in Standard (Physically Based) shader
half4 LitPassFragment(Varyings input) : SV_Target0
{
    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

    float skinMask;
    float2 rimMask;
    SurfaceData surfaceData = InitializeStandardLitSurfaceData(input.uv, skinMask, rimMask);
    InputData inputData = InitializeInputData(input, surfaceData.normalTS);
    SockSurfaceData sockSurfaceData = InitializeSockSurfaceData(input.uv, surfaceData.normalTS, inputData.tangentToWorld, skinMask);

    half4 color = UniversalFragmentPBR(inputData, surfaceData, sockSurfaceData);
    
    //边缘光
    #if _USERIM_ON
    half3 rimColor = CalcMatCapRimColor(inputData.viewDirectionWS, inputData.normalWS, surfaceData.occlusion, rimMask);
    color.rgb += rimColor;
    #endif
    
    color.rgb = MixFog(color.rgb, inputData.fogCoord);
    return color;
}

#endif


SockLitInput.hlsl
#ifndef UNIVERSAL_LIT_INPUT_INCLUDED
#define UNIVERSAL_LIT_INPUT_INCLUDED

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"

// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial)
    half4 _BaseColor;
    float _MetallicOffset;
    float _RoughnessOffset;
    float _OcclusionOffset;
    half _NormalScale;
    float4 _SilkDetailNormalMap_ST;
    float _SilkDetailNormalScale;
CBUFFER_END

TEXTURE2D(_NormalMap);
SAMPLER(sampler_NormalMap);
TEXTURE2D(_MaskMap);
SAMPLER(sampler_MaskMap);
TEXTURE2D(_PBRMaskMap);
SAMPLER(sampler_PBRMaskMap);
TEXTURE2D(_SilkDetailNormalMap);
SAMPLER(sampler_SilkDetailNormalMap);


SurfaceData InitializeStandardLitSurfaceData(float2 uv, out float skinMask, out float2 rimMask)
{
    SurfaceData outSurfaceData = (SurfaceData)0;

    half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
    half4 pbrMaskMap = SAMPLE_TEXTURE2D(_PBRMaskMap, sampler_PBRMaskMap, uv);

    half4 maskMap = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, uv); // R:边缘光MatCap RG,G:边缘光MatCap B,B:皮肤
    rimMask = float2(maskMap.r, maskMap.g);
    skinMask = maskMap.b;
    
    half4 normalMap = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, uv);
    half3 normalTS = UnpackNormalScale(normalMap, _NormalScale);
    
    #if _USESILKDETAILNORMAL_ON
    half4 silkDetailNormalMap = SAMPLE_TEXTURE2D(_SilkDetailNormalMap, sampler_SilkDetailNormalMap, uv * _SilkDetailNormalMap_ST.xy);
    half3 silkDetailNormalTS = UnpackNormalScale(silkDetailNormalMap, _SilkDetailNormalScale);
    silkDetailNormalTS = lerp(silkDetailNormalTS, half3(0,0,1), skinMask);
    half3 finalNormalTS = BlendNormalRNM(normalTS, silkDetailNormalTS);
    #else
    half3 finalNormalTS = normalTS;
    #endif

    outSurfaceData.albedo = baseMap.rgb * _BaseColor.rgb;
    outSurfaceData.alpha = baseMap.a * _BaseColor.a;

    outSurfaceData.metallic = saturate(pbrMaskMap.r + _MetallicOffset);
    outSurfaceData.specular = half3(0.0, 0.0, 0.0);

    outSurfaceData.smoothness = 1 - saturate(pbrMaskMap.g + _RoughnessOffset);
    outSurfaceData.normalTS = finalNormalTS;
    outSurfaceData.occlusion = saturate(pbrMaskMap.b + _OcclusionOffset);
    outSurfaceData.emission = 0;

    outSurfaceData.clearCoatMask = half(0.0);
    outSurfaceData.clearCoatSmoothness = half(0.0);

    return outSurfaceData;
}

#endif // UNIVERSAL_INPUT_SURFACE_PBR_INCLUDED


Shader "Omnee/Role/Eye Lit"
{
    Properties
    {
        [Toggle] _IsRightEye("是否为右眼?", float) = 0
        
        [Main(Sclera, _, off, off)] _Sclera ("巩膜", float) = 0
        [Sub(Sclera)] _ScleraColor("巩膜颜色", Color) = (1,1,1,1)
        [Sub(Sclera)] _ScleraRoughness("巩膜粗糙度", Range(0, 1)) = 0.5

        [Main(Cornea, _, off, off)] _Cornea ("角膜", float) = 0
        [Sub(Cornea)] _CorneaRoughness("角膜粗糙度", Range(0, 1)) = 0.5
        [Sub(Cornea)] [NoScaleOffset] _CorneaNormalMap("角膜法线贴图", 2D) = "bump" {}
        [Sub(Cornea)] _CorneaNormalScale("角膜法线强度", Range(0,2)) = 1

        [Main(Iris, _, off, off)] _Iris ("虹膜", float) = 0
        [Sub(Iris)] [NoScaleOffset] _IrisMap("虹膜贴图", 2D) = "white" {}
        [Sub(Iris)] _IrisRadius("虹膜半径", Range(0,1)) = 0.25
        [Sub(Iris)] _IrisParallaxStrength("虹膜视差偏移程度", float) = 0

        [Main(Lighting, _, off, off)] _Lighting ("光照", float) = 0
        [Title(Lighting, Specular)]
        [Sub(Lighting)] [NoScaleOffset] _SpecularMap("高光贴图", 2D) = "black" {}
        [Sub(Lighting)] _SpecularPositionOffset("高光位置偏移(xy)", Vector) = (0,0,0,0)

        [Title(Lighting, Env)]
        [Sub(Lighting)] [NoScaleOffset] _EnvCubeMap("环境球", Cube) = "black" {}
        [Sub(Lighting)] _EnvIntensity("环境反射强度", Range(0,1)) = 0.2
        [SubToggle(Lighting, _USEROTATEENVON)] _UseRotateEnv("旋转环境球", float) = 0
        [Sub(Lighting_USEROTATEENVON)] _RotateEnvAngle("旋转环境球角度", Range(0,360)) = 0
        
        [Title(Lighting, Shadow)]
        [Sub(Lighting)] [NoScaleOffset] _ShadowMap("阴影贴图", 2D) = "white" {}
    }

    SubShader
    {
        Tags
        {
            "RenderType" = "Opaque"
            "RenderPipeline" = "UniversalPipeline"
            "Queue" = "Geometry"
        }
        LOD 300

        Pass
        {
            Tags
            {
                "LightMode" = "UniversalForward"
            }

            // -------------------------------------
            // Render State Commands
            //Cull Off

            HLSLPROGRAM
            #pragma target 2.0

            // -------------------------------------
            // Shader Stages
            #pragma vertex LitPassVertex
            #pragma fragment LitPassFragment

            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local_fragment _USEROTATEENVON
            #pragma shader_feature_local_fragment _ISRIGHTEYE_ON

            // -------------------------------------
            // Universal Pipeline keywords
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
            #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
            #pragma multi_compile _ EVALUATE_SH_MIXED EVALUATE_SH_VERTEX
            #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
            #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING
            #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION
            #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH
            #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
            #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
            #pragma multi_compile_fragment _ _LIGHT_COOKIES
            #pragma multi_compile _ _LIGHT_LAYERS
            #pragma multi_compile _ _FORWARD_PLUS


            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
            #pragma multi_compile _ SHADOWS_SHADOWMASK
            #pragma multi_compile _ DIRLIGHTMAP_COMBINED
            #pragma multi_compile _ LIGHTMAP_ON
            #pragma multi_compile _ DYNAMICLIGHTMAP_ON
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE
            #pragma multi_compile_fog

            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #pragma instancing_options renderinglayer

            //#include "EyeLitInput.hlsl"
            //#include "EyeLitForwardPass.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #include "Assets/AssetArt/Shaders/ShaderLibs/Common.hlsl"

            CBUFFER_START(UnityPerMaterial)
                half4 _ScleraColor;
                float _ScleraRoughness;
                float _CorneaRoughness;
                float _CorneaNormalScale;
                float _IrisRadius;
                float _IrisParallaxStrength;
                float2 _SpecularPositionOffset;
                float _SpecularMoveSpeed;
                float4 _EnvCubeMap_HDR;
                float _EnvIntensity;
                float _RotateEnvAngle;
            CBUFFER_END

            TEXTURE2D(_SpecularMap);
            SAMPLER(sampler_SpecularMap);
            TEXTURE2D(_IrisMap);
            SAMPLER(sampler_IrisMap);
            TEXTURE2D(_CorneaNormalMap);
            SAMPLER(sampler_CorneaNormalMap);
            TEXTURECUBE(_EnvCubeMap);
            SAMPLER(sampler_EnvCubeMap);
            TEXTURE2D(_ShadowMap);
            SAMPLER(sampler_ShadowMap);

            
            struct Attributes
            {
                float4 positionOS : POSITION;
                float3 normalOS : NORMAL;
                float4 tangentOS : TANGENT;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 positionWS : TEXCOORD1;
                float3 normalWS : TEXCOORD2;
                half4 tangentWS : TEXCOORD3; // xyz: tangent, w: sign
                float3 bitangentWS : TEXCOORD4;
                float4 sh : TEXCOORD5; // xyz: sh, w: fogFactor
                float3 forwardDirWS : TEXCOORD6;

                UNITY_VERTEX_INPUT_INSTANCE_ID
            };


            Varyings LitPassVertex(Attributes input)
            {
                Varyings output = (Varyings)0;

                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_TRANSFER_INSTANCE_ID(input, output);

                VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);

                // normalWS and tangentWS already normalize.
                // this is required to avoid skewing the direction during interpolation
                // also required for per-vertex lighting and SH evaluation
                VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);

                half fogFactor = 0;
                #if !defined(_FOG_FRAGMENT)
                fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
                #endif

                output.uv = input.texcoord;

                // already normalized from normal transform to WS.
                output.normalWS = normalInput.normalWS;
                real sign = input.tangentOS.w * GetOddNegativeScale();
                output.tangentWS = half4(normalInput.tangentWS.xyz, sign);
                output.bitangentWS = normalInput.bitangentWS;

                output.positionWS = vertexInput.positionWS;
                output.positionCS = vertexInput.positionCS;

                output.sh.xyz = SampleSH(normalInput.normalWS);
                output.sh.w = fogFactor;

                output.forwardDirWS = TransformObjectToWorldDir(float3(0, 0, 1));
                return output;
            }

            /*
            half2 ParallaxOffset(half height, half amplitude, half3 viewDirTS)
            {
                height = height * amplitude - amplitude / 2.0;
                half3 v = normalize(viewDirTS);
                v.z += 0.42;
                return height * (v.xy / v.z);
            }
            */

            // Used in Standard (Physically Based) shader
            half4 LitPassFragment(Varyings input) : SV_Target0
            {
                UNITY_SETUP_INSTANCE_ID(input);

                float3 positionWS = input.positionWS;
                half3 V = GetWorldSpaceNormalizeViewDir(positionWS);
                half3x3 TBN = half3x3(input.tangentWS.xyz, input.bitangentWS, input.normalWS);
                float fogFactor = input.sh.z;

                // iris uv
                float2 uv = input.uv;
                float distanceToCenter = distance(uv, float2(0.5, 0.5));
                float isSclera = step(_IrisRadius, distanceToCenter);
                float2 irisUV = 0.5 * (uv - float2(0.5, 0.5)) * rcp(_IrisRadius) + float2(0.5, 0.5);

                // 视差映射
                float parallaxHeight = smoothstep(_IrisRadius, 0.03, distanceToCenter);
                //parallaxHeight = SAMPLE_TEXTURE2D(_IrisMap, sampler_IrisMap, irisUV).a;
                float3 vTS = TransformWorldToTangentDir(V, TBN, true);
                float2 parallaxOffset = (vTS.xy / (vTS.z + 0.42)) * parallaxHeight * _IrisParallaxStrength;

                float2 irisParallaxUV = irisUV - parallaxOffset;

                half4 irisMap = SAMPLE_TEXTURE2D(_IrisMap, sampler_IrisMap, irisParallaxUV);
                half3 albedo = lerp(irisMap.rgb, _ScleraColor.rgb, isSclera);

                // 法线
                half4 corneaNormalMap = SAMPLE_TEXTURE2D(_CorneaNormalMap, sampler_CorneaNormalMap, uv);
                float3 corneaNormalTS = UnpackNormalScale(corneaNormalMap, _CorneaNormalScale);
                corneaNormalTS = lerp(corneaNormalTS, float3(0, 0, 1), isSclera);

                float3 irisNormalTS = float3(-corneaNormalTS.x, -corneaNormalTS.y, corneaNormalTS.z);
                irisNormalTS = lerp(irisNormalTS, float3(0, 0, 1), isSclera);

                float3 NIris = TransformTangentToWorld(irisNormalTS, TBN, true);
                float3 NCornea = TransformTangentToWorld(corneaNormalTS, TBN, true);

                // 光照计算 -------->

                // main light
                Light mainLight = GetMainLight();
                float3 L = normalize(mainLight.direction);
                half3 radiance = mainLight.color * mainLight.distanceAttenuation * mainLight.shadowAttenuation;

                // diffuse
                float NoLIris = dot(NIris, L) * 0.5 + 0.5;
                float3 diffuseLighting = albedo * NoLIris * radiance;

                // specular
                float3 H = V + L;
                float NoHEyEForward = dot(input.forwardDirWS, H);
                float specularSpeedX;
                #if _ISRIGHTEYE_ON
                specularSpeedX = -0.3;
                #else
                specularSpeedX = 0.3;
                #endif
                float2 specularUV = irisUV + _SpecularPositionOffset.xy + (V.xy + NoHEyEForward) * float2(specularSpeedX, 0.1);
                half4 specularMap = SAMPLE_TEXTURE2D(_SpecularMap, sampler_SpecularMap, specularUV);
                half3 specularLighting = lerp(specularMap.rgb, 0, isSclera);

                // 环境漫反射
                float3 sh = input.sh * albedo;

                // 环境球
                float3 reflectDir = reflect(-V, NCornea);
                #if _USEROTATEENVON
                reflectDir = Rotation3DY(reflectDir, _RotateEnvAngle);
                #endif
                float roughness = lerp(_CorneaRoughness, _ScleraRoughness, isSclera);
                half mip = PerceptualRoughnessToMipmapLevel(roughness);
                half4 envCubeMap = SAMPLE_TEXTURECUBE_LOD(_EnvCubeMap, sampler_EnvCubeMap, reflectDir, mip);
                float3 envCube = DecodeHDREnvironment(envCubeMap, _EnvCubeMap_HDR);
                half3 envColor = envCube * _EnvIntensity;
                half envLumin = dot(envColor, float3(0.299, 0.587, 0.114));
                envColor *= envLumin;

                // 光照计算 --------<

                half4 color;
                color.rgb = diffuseLighting + specularLighting + sh + envColor;
                color.a = 1;

                // 阴影
                half4 shadowMap = SAMPLE_TEXTURE2D(_ShadowMap, sampler_ShadowMap, input.uv);
                color.rgb *= shadowMap.rgb;
                
                //
                color.rgb = MixFog(color.rgb, fogFactor);
                return color;
            }
            ENDHLSL

        }

    }

    FallBack "Hidden/Universal Render Pipeline/FallbackError"
    CustomEditor "LWGUI.LWGUI"
}
View Code

 

posted @ 2026-03-19 16:58  太乙_真人  阅读(15)  评论(0)    收藏  举报