赞
踩
使用unity版本为2022.2.21f1
shader文件
- Shader "Unlit/SRUniversal"
- {
- Properties
- {
- [KeywordEnum(None,Face,Hair,UpperBody,LowerBody)] _Area("Material area", Float) = 0
- [HideInInspector] _HeadForward("", Vector) = (0,0,1)
- [HideInInspector] _HeadRight("", Vector) = (1,0,0)
-
- [Header(Base Color)]
- [HideInInspector] _BaseMap("", 2D) = "white"{}
- [NoScaleOffset] _FaceColorMap("Face color map (Default white)", 2D) = "white"{}
- [NoScaleOffset] _HairColorMap("Hair color map (Default white)", 2D) = "white"{}
- [NoScaleOffset] _UpperBodyColorMap("Upper body color map (Default white)", 2D) = "white"{}
- [NoScaleOffset] _LowerBodyColorMap("Lower body color map (Default white)", 2D) = "white"{}
- _FrontFaceTintColor("Front face tint color (Default white)", Color) = (1,1,1)
- _BackFaceTintColor("Back face tint color (Default white)", Color) = (1,1,1)
- _Alpha("Alpha (Default 1)", Range(0, 1)) = 1
- _AlphaClip("Alpha clip (Default 0.333)", Range(0, 1)) = 0.333
-
- [Header(Light Map)]
- [NoScaleOffset] _HairLightMap("Hair light map (Default black)", 2D) = "black"{}
- [NoScaleOffset] _UpperBodyLightMap("Upper body light map (Default black)", 2D) = "black"{}
- [NoScaleOffset] _LowerBodyLightMap("Lower body light map (Default black)", 2D) = "black"{}
-
- [Header(Ramp Map)]
- [NoScaleOffset] _HairCoolRamp("Hair cool ramp (Default white)", 2D) = "white"{}
- [NoScaleOffset] _HairWarmRamp("Hair warm ramp (Default white)", 2D) = "white"{}
- [NoScaleOffset] _BodyCoolRamp("Body cool ramp (Default white)", 2D) = "white"{}
- [NoScaleOffset] _BodyWarmRamp("Body warm ramp (Default white)", 2D) = "white"{}
-
- [Header(Indirect Lighting)]
- _IndirectLightFlattenNormal("Indirect light flatten normal (Default 0)", Range(0, 1)) = 0
- _IndirectLightUsage("Indirect light usage (Default 0.5)", Range(0, 1)) = 0.5
- _IndirectLightOcclusionUsage("Indirect light occlusion usage (Default 0.5)", Range(0, 1)) = 0.5
- _IndirectLightMixBaseColor("Indirect light base color (Default 1)", Range(0, 1)) = 1
-
- [Header(Main Lighting)]
- _MainLightColorUsage("Main light color usage (Default 1)", Range(0, 1)) = 1
- _ShadowThresholdCenter("Shadow threshold center (Default 0)", Range(-1, 1)) = 0
- _ShadowThresholdSoftness("Shadow threshold softness (Default 0.1)", Range(0, 1)) = 0.1
- _ShadowRampOffset("Shadow ramp offset (Default 0.75)", Range(0, 1)) = 0.75
-
- [Header(Face)]
- [NoScaleOffset] _FaceMap("Face map (Default black)", 2D) = "black"{}
- _FaceShadowOffset("Face shadow offset (Default -0.01)", Range(-1, 1)) = -0.01
- _FaceShadowTransitionSoftness("Face shadow transition softness (Default 0.05)", Range(0, 1)) = 0.05
-
- [Header(Specular)]
- _SpecularExpon("Specular exponent (Default 50)", Range(1, 128)) = 50
- _SpecularKsNonMetal("Specular Ks non-metal (Default 0.04)", Range(0, 1)) = 0.04
- _SpecularKsMetal("Specular Ks metal (Default 1)", Range(0, 1)) = 1
- _SpecularBrightness("Specular brightness (Default 1)", Range(0, 10)) = 1
-
- [Header(Sockings)]
- [NoScaleOffset] _UpperBodyStockings("Upper body stockings (Default black)", 2D) = "black"{}
- [NoScaleOffset] _LowerBodyStockings("Lower body stockings (Default black)", 2D) = "black"{}
- _StockingsDarkColor("Stocking dark color (Default black)", Color) = (0,0,0)
- [HDR] _StockingsLightColor("Stocking light color (Default 1.8 1.48299 0.856821)", Color) = (1.8, 1.48299, 0.856821)
- [HDR] _StockingsTransitionColor("Stocking Transition color (Default 0.360381 0.242986 0.358131)", Color) = (0.360381, 0.242986, 0.358131)
- _StockingsTransitionThreshold("Stocking transition threshold (Default 0.58)", Range(0, 1)) = 0.58
- _StockingsTransitionPower("Stocking transition Power (Default 1)", Range(0.1, 50)) = 1
- _StockingsTransitionHardness("Stocking transition hardness (Default 0.4)", Range(0, 1)) = 0.4
- _StockingsTextureUsage("Stocking texture usage (Default 0.1)", Range(0, 1)) = 0.1
-
- [Header(Rim Lighting)]
- _RimLightWidth("Rim light width (Default 1)", Range(0, 10)) = 1
- _RimLightThreshold("Rim light threshold (Default 0.05)", Range(-1, 1)) = 0.05
- _RimLightFadeout("Rim light fadeout (Default 1)", Range(0.01, 1)) = 1
- [HDR] _RimLightTintColor("Rim light tint color (Default white)", Color) = (1,1,1)
- _RimLightBrightness("Rim light brightness (Default 1)", Range(0, 10)) = 1
- _RimLightMixAlbedo("Rim light mix albedo (Default 0.9)", Range(0, 1)) = 0.9
-
- [Header(Emission)]
- [Toggle(_EMISSION_ON)] _UseEmission("Use emission (Default False)", Float) = 0
- _EmissionMixBaseColor("Emission mix base color (Default 1)", Range(0, 1)) = 1
- _EmissionTintColor("Emission tint color (Default white)", Color) = (1,1,1)
- _EmissionIntensity("Emission intensity (Default 1)", Range(0, 100)) = 1
-
- [Header(Outline)]
- [Toggle(_OUTLINE_ON)] _UseOutline("Use outline (Default True)", Float) = 1
- [Toggle(_OUTLINE_VERTEX_COLOR_SMOOTH_NORMAL)] _OutlineUseVertexColorSmoothNormal("Use vertex color smooth normal (Default False)", Float) = 0
- _OutlineWidth("Outline width (Default 1)", Range(0, 10)) = 1
- _OutlineGamma("Outline gamma (Default 16)", Range(1, 255)) = 16
-
- [Header(Surface Options)]
- [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull (Default back)", Float) = 2
- [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlendMode("Src blend mode (Default One)", Float) = 1
- [Enum(UnityEngine.Rendering.BlendMode)] _DstBlendMode("Dst blend mode (Default Zero)", Float) = 0
- [Enum(UnityEngine.Rendering.BlendOp)] _BlendOp("Blend operation (Default Add)", Float) = 0
- [Enum(Off, 0, On, 1)] _ZWrite("ZWrite (Default On)", Float) = 1
- _StencilRef("Stencil reference (Default 0)", Range(0, 255)) = 0
- [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil comparison (Default disabled)", Int) = 0
- [Enum(UnityEngine.Rendering.StencilOp)] _StencilPassOp("Stencil pass operation (Default keep)", Int) = 0
- [Enum(UnityEngine.Rendering.StencilOp)] _StencilFailOp("Stencil fail operation (Default keep)", Int) = 0
- [Enum(UnityEngine.Rendering.StencilOp)] _StencilZFailOp("Stencil Z fail operation (Default keep)", Int) = 0
-
- [Header(Draw Overlay)]
- [Toggle(_DRAW_OVERLAY_ON)] _UseDrawOverlay("Use draw overlay (Default False)", Float) = 0
- [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlendModeOverlay("Overlay pass src blend mode (Default One)", Float) = 1
- [Enum(UnityEngine.Rendering.BlendMode)] _DstBlendModeOverlay("Overlay pass src blend mode (Default Zero)", Float) = 0
- [Enum(UnityEngine.Rendering.BlendOp)] _BlendOpOverlay("Overlay pass blend operation (Default Add)", Float) = 0
- _StencilRefOverlay("Overlay pass stencil reference (Default 0)", Range(0, 255)) = 0
- [Enum(UnityEngine.Rendering.CompareFunction)] _StencilCompOverlay ("Overlay pass stencil comparison (Default disabled)", Int) = 0
- }
- SubShader
- {
- LOD 100
-
- HLSLINCLUDE
- HLSL code that you want to share goes here
- #pragma shader_feature_local _AREA_FACE
- #pragma shader_feature_local _AREA_HAIR
- #pragma shader_feature_local _AREA_UPPERBODY
- #pragma shader_feature_local _AREA_LOWERBODY
- #pragma shader_feature_local _OUTLINE_ON
- #pragma shader_feature_local _OUTLINE_VERTEX_COLOR_SMOOTH_NORMAL
- #pragma shader_feature_local _DRAW_OVERLAY_ON
- #pragma shader_feature_local _EMISSION_ON
- ENDHLSL
-
-
- Pass
- {
- Name "ShadowCaster"
- Tags{"LightMode" = "ShadowCaster"} // 阴影贴图
-
- ZWrite [_ZWrite]
- ZTest LEqual
- ColorMask RGBA
- Cull [_Cull]
-
- HLSLPROGRAM
- //#pragma exclude_renders gles gles3 glcore
- #pragma targe 4.5
-
- // -------------------------------------------------------------------------------------------
- // 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
- #pragma multi_compile _ DOTS_INSTANCING_ON
-
- // -------------------------------------------------------------------------------------------
- // Universial Pipeline keywords
-
- // 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
-
- #pragma vertex ShadowPassVertex
- #pragma fragment ShadowPassFragment
-
- #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
-
- ENDHLSL
- }
-
- Pass
- {
- Name "DepthOnly"
- Tags{"LightMode" = "DepthOnly" "Queue" = "Transparent" } // 深度贴图
-
- ZWrite [_ZWrite]
- ColorMask RGBA
- Cull [_Cull]
-
- HLSLPROGRAM
- //#pragma exclude_renders gles gles3 glcore
- #pragma targe 4.5
-
- // -------------------------------------------------------------------------------------------
- // 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
- #pragma multi_compile _ DOTS_INSTANCING_ON
-
- #pragma Vertex DepthOnlyVertex
- #pragma fragment DepthOnlyFragment
-
- #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
-
- ENDHLSL
- }
-
- Pass
- {
- Name "DepthNormals"
- Tags{"LightMode" = "DepthNormals"} // 向SSAO传输值
-
- ZWrite [_ZWrite]
- Cull [_Cull]
-
- HLSLPROGRAM
- //#pragma exclude_renders gles gles3 glcore
- #pragma targe 4.5
-
- // -------------------------------------------------------------------------------------------
- // Material Keywords
- #pragma shader_feature_local _NORMALMAP
- #pragma shader_feature_local _PARALLAXMAP
- #pragma shader_feature_local _ _DETAIL_MULTX2 _DETAIL_SCALED
- #pragma shader_feature_local_fragment _ALPHATEST_ON
- #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
-
- // -------------------------------------------------------------------------------------------
- // GPU Instancing
- #pragma multi_compile_instancing
- #pragma multi_compile _ DOTS_INSTANCING_ON
-
- #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl"
-
- ENDHLSL
- }
-
- Pass
- {
- Name "DrawCore"
- Tags{ "RenderPipeline" = "UniversalRenderPipeline" "RenderType" = "Opaque" "LightMode" = "SRPDefaultUnlit"}
-
- Cull [_Cull]
- Stencil{
- Ref [_StencilRef] //这是传进去的int值(默认0【0,255】注意这是二进制11111111),如果在测试就用这个值和模板值(如果没有写入过默认0)作比较,受readMask影响、如果在写入就是写入这个值,受writeMask影响
- Comp [_StencilComp] //何时通过模板测试,这个和写入没有任何关系,还有CompBack和CompFront专门针对背面和正面,如果存在Comp则会覆盖他们,值为:Never、Less、Equal、LEqual、Greater、NotEqual、GEqual、Always
- Pass [_StencilPassOp] //设置对通过模板测试的像素怎么处理,还有PassBack和PassFront专门针对背面和正面,如果存在Pass则会覆盖他们,值为:Keep(保持原值)、Zero(写入模板值0)、Replace(写入Ref值)、IncrSat(加上去但不超过255)、DecrSat(相减但不小于0)、Invert(所有位取反)、IncrWrap(加上去但超过255会从0重新开始)、DecrWrap(相减但小于0会从255重新开始)
- Fail [_StencilFailOp] //设置对未通过模板测试的像素怎么处理,还有FailBack和FailFront专门针对背面和正面,如果存在Fail则会覆盖他们,值和Pass的相同
- ZFail [_StencilZFailOp] //当像素通过模板测试但未通过深度测试时怎么处理,还有ZFailBack和ZFailFront专门针对背面和正面,如果存在ZFail则会覆盖他们,值和Pass的相同
- }
- Blend [_SrcBlendMode] [_DstBlendMode]
- BlendOp [_BlendOp]
- ZWrite [_ZWrite]
-
- HLSLPROGRAM
- //#pragma exclude_renders gles gles3 glcore
- #pragma targe 4.5
- #pragma multi_compile _MAIN_LIGHT_SHADOWS
- #pragma multi_compile _MAIN_LIGHT_SHADOWS_CASCADE
- #pragma multi_compile _SHADOW_SOFT
-
- #pragma vertex vert
- #pragma fragment frag
-
- #pragma multi_compile_fog
-
- #include "SRUniversalInput.hlsl"
- #include "SRUniversalDrawCorePass.hlsl"
-
- ENDHLSL
- }
-
- Pass
- {
- Name "DrawOutline"
- Tags{ "RenderPipeline" = "UniversalRenderPipeline" "RenderType" = "Opaque" "LightMode" = "UniversalForwardOnly" }
- Cull Front
- ZWrite[_ZWrite]
-
- HLSLPROGRAM
- #pragma vertex vert
- #pragma fragment frag
-
- #pragma multi_compile_fog
-
- #if _OUTLINE_ON
- #include "SRUniversalInput.hlsl"
- #include "SRUniversalDrawOutlinePass.hlsl"
- #else
-
- struct Attribute {};
-
- struct Varyings
- {
- float4 positionCS : SV_POSITION;
- };
-
- Varyings vert(Attribute input)
- {
- return (Varyings)0;
- }
-
- float4 frag(Varyings input) : SV_TARGET
- {
- return 0;
- }
-
- #endif
- ENDHLSL
-
- }
- }
- Fallback Off
- }

hlsl文件
SRUniversalInput
- #ifndef _SR_UNIVERSAL_INPUT_INCLUDED
- #define _SR_UNIVERSAL_INPUT_INCLUDED
-
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
- /*
- 包含VertexPositionInputs、VertexNormalInputs结构以及各种基础定义 #define TEXTURE2D_X(textureName) TEXTURE2D_ARRAY(textureName)
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
- 约定:
- unity在世界空间是左手,但是在视图空间为右手。世界到视图空间的矩阵行列式是负的
- 对于cubmap捕获(反射探针),视图空间仍是左手,行列式为正
- //WS:世界空间
- //RWS:相机相对世界空间。为了提高精度,已经减去了相机平移的空间
- //VS:视图空间
- //OS:对象空间
- //CS:同构剪辑空间
- //TS:切线空间
- //TXS:纹理空间
- 大写字母矢量都指向像素位置且归一View vector、Light vector、Light vector、Half vector
- out和inout过滤器,当声明函数的“out”参数时,它们总是最后一个
- 不要使用SetGlobalFloatArray或SetComputeFloatParams。//数组可以是hlsl中的别名。示例:uniform float4-packedArray[3];static float unpackedArray[12]=(float[12])packedArray;
- *包含非常多的常用基本函数定义PackHeightmap、GetPositionInput、SinFromCos、Orthonormalize等等*
- -----------------------------------------------------------------------------------------------------------------
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
- Unpack888UIntToFloat2(uint3 x)、Unpack8ToFloat2(float f)、PackToR5G6B5(float3 rgb) 看起来是各种格式互转的方法
- -----------------------------------------------------------------------------------------------------------------
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl"
- UNITY_VERSION宏
- -----------------------------------------------------------------------------------------------------------------
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
- InputData结构体、很多常量输入(应该是unity给值,直接拿那种)比如_MainLightPosition
- -----------------------------------------------------------------------------------------------------------------
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl"
- 各种各样的方法,GetWorldSpaceViewDir之类的获取各种输入结构、LinearDepthToEyeDepth变换方法、TransformScreenUV(inout float2 uv)甚至编码解码什么的
- */
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
- /*
- 各种光照方法LightingLambert、LightingSpecular、LightingPhysicallyBased、VertexLighting、CalculateLightingColor、CalculateBlinnPhong、UniversalFragmentPBR、UniversalFragmentBlinnPhong、UniversalFragmentBakedLit
- 结构体LightingData获取各种光照信息
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl" 光反射模型
- 结构体BRDFData、方法:InitializeBRDFData、EnvironmentBRDFSpecular、DirectBRDFSpecular
- {
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/BSDF.hlsl" 包括BRDF反射、BTDF透射、BDDF衍射
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
- 方法:ClampRoughnessForRaytracing、BlendNormal、ConvertRoughnessToAnisotropy材质属性(粗糙度)相关的
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl"
- 定义SurfaceData结构体,是物体表面的各种属性摩擦、金属、间接光遮....
- }
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
- 方法:CanDebugOverrideOutputColor、CalculateColorForDebugMaterial看起来都是debug用的方法
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
- 方法:SampleProbeVolumePixel、SampleLightmap、GlossyEnvironmentReflection、GlobalIllumination都是一些全局照明所需要的方法
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
- 定义Light结构、方法:灯光衰减DistanceAttenuation、GetMainLight等
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
- 定义AmbientOcclusionFactor结构,GetScreenSpaceAmbientOcclusion屏幕空间环境光遮挡
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl" 看起来是贴花相关的东西
- */
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
- //只是声明深度图,附带采样、读取方法SampleSceneDepth、LoadSceneDepth
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
- //阴影相关,定义ShadowSamplingData结构体,GetMainLightShadowSamplingData、GetMainLightShadowParams、SampleShadowmap、ApplyShadowBias
-
-
- /*
- 像这样做就是放在常量缓冲区,下面这种做法是unity宏,确保在支持时使用它们
- cbuffer UnityPerFrame {
- float4x4 unity_MatrixVP;
- };
- */
- CBUFFER_START(UnityPerMaterial)
- float3 _HeadForward;
- float3 _HeadRight;
-
- sampler2D _BaseMap;
- float4 _BaseMap_ST;
-
- #if _AREA_FACE
- sampler2D _FaceColorMap;
- #elif _AREA_HAIR
- sampler2D _HairColorMap;
- #elif _AREA_UPPERBODY
- sampler2D _UpperBodyColorMap;
- #elif _AREA_LOWERBODY
- sampler2D _LowerBodyColorMap;
- #endif
-
- float3 _FrontFaceTintColor;
- float3 _BackFaceTintColor;
-
- float _Alpha;
- float _AlphaClip;
-
- #if _AREA_HAIR
- sampler2D _HairLightMap;
- #elif _AREA_UPPERBODY
- sampler2D _UpperBodyLightMap;
- #elif _AREA_LOWERBODY
- sampler2D _LowerBodyLightMap;
- #endif
-
- #if _AREA_HAIR
- sampler2D _HairCoolRamp;
- sampler2D _HairWarmRamp;
- #elif _AREA_FACE || _AREA_UPPERBODY || _AREA_LOWERBODY
- sampler2D _BodyCoolRamp;
- sampler2D _BodyWarmRamp;
- #endif
-
- float _IndirectLightFlattenNormal;
- float _IndirectLightUsage;
- float _IndirectLightOcclusionUsage;
- float _IndirectLightMixBaseColor;
-
- float _MainLightColorUsage;
- float _ShadowThresholdCenter;
- float _ShadowThresholdSoftness;
- float _ShadowRampOffset;
-
- #if _AREA_FACE
- sampler2D _FaceMap;
- float _FaceShadowOffset;
- float _FaceShadowTransitionSoftness;
- #endif
-
- #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
- float _SpecularExpon;
- float _SpecularKsNonMetal;
- float _SpecularKsMetal;
- float _SpecularBrightness;
- #endif
-
- #if _AREA_UPPERBODY || _AREA_LOWERBODY
- #if _AREA_UPPERBODY
- sampler2D _UpperBodyStockings;
- #elif _AREA_LOWERBODY
- sampler2D _LowerBodyStockings;
- #endif
- float3 _StockingsDarkColor;
- float3 _StockingsLightColor;
- float3 _StockingsTransitionColor;
- float _StockingsTransitionThreshold;
- float _StockingsTransitionPower;
- float _StockingsTransitionHardness;
- float _StockingsTextureUsage;
- #endif
-
- float _RimLightWidth;
- float _RimLightThreshold;
- float _RimLightFadeout;
- float3 _RimLightTintColor;
- float _RimLightBrightness;
- float _RimLightMixAlbedo;
-
- #if _OUTLINE_ON
- float _OutlineWidth;
- float _OutlineGamma;
- #endif
-
- CBUFFER_END
-
- #endif

SRUniversalDrawOutlinePass
- struct Attributes
- {
- float3 positionOS : POSITION;
- float3 normalOS : NORMAL;
- float4 tangentOS : TANGENT;
- float4 color : COLOR;
- float4 uv : TEXCOORD0;
- };
-
- struct Varyings
- {
- float4 positionCS : SV_POSITION;
- float2 uv : TEXCOORD0;
- float fogFactor : TEXCOORD1;
- float4 color : TEXCOORD2;
-
- };
-
- float GetCameraFOV()
- {
- //https://answers.unity.com/questions/770838/how-can-i-extract-the-fov-information-from-the-pro.html
- float t = unity_CameraProjection._m11;
- float Rad2Deg = 180 / 3.1415;
- float fov = atan(1.0f / t) * 2.0 * Rad2Deg;
- return fov;
- }
- float ApplyOutlineDistanceFadeOut(float inputMulFix)
- {
- //make outline "fadeout" if character is too small in camera's view
- return saturate(inputMulFix);
- }
- float GetOutlineCameraFovAndDistanceFixMultiplier(float positionVS_Z)
- {
- float cameraMulFix;
- if(unity_OrthoParams.w == 0)
- {
-
- // Perspective camera case
-
- // keep outline similar width on screen accoss all camera distance
- cameraMulFix = abs(positionVS_Z);
- // can replace to a tonemap function if a smooth stop is needed
- cameraMulFix = ApplyOutlineDistanceFadeOut(cameraMulFix);
- // keep outline similar width on screen accoss all camera fov
- cameraMulFix *= GetCameraFOV();
- }
- else
- {
-
- // Orthographic camera case
-
- float orthoSize = abs(unity_OrthoParams.y);
- orthoSize = ApplyOutlineDistanceFadeOut(orthoSize);
- cameraMulFix = orthoSize * 50; // 50 is a magic number to match perspective camera's outline width
- }
-
- return cameraMulFix * 0.00005; // mul a const to make return result = default normal expand amount WS
- }
-
- Varyings vert(Attributes input)
- {
- Varyings output = (Varyings)0;
-
- VertexPositionInputs vertexPositionInput = GetVertexPositionInputs(input.positionOS);
- VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
-
- float width = _OutlineWidth;
- width *= GetOutlineCameraFovAndDistanceFixMultiplier(vertexPositionInput.positionVS.z);
-
- float3 positionWS = vertexPositionInput.positionWS;
- positionWS += vertexNormalInput.normalWS * width;
- output.positionCS = TransformWorldToHClip(positionWS);
-
- output.uv = TRANSFORM_TEX(input.uv, _BaseMap); // 加偏移
- output.fogFactor = ComputeFogFactor(vertexPositionInput.positionCS.z);
-
- return output;
- }
-
- float4 frag(Varyings input) : SV_TARGET
- {
- //描边加颜色,用的采样出来的Ramp
- float3 coolRamp = 0;
- float warmRamp = 0;
-
- #if _AREA_HAIR
- float2 outlineUV = float2(0, 0.5);
- coolRamp = tex2D(_HairCoolRamp, outlineUV).rgb;
- warmRamp = tex2D(_HairWarmRamp, outlineUV).rgb;
- #elif _AREA_UPPERBODY || _AREA_LOWERBODY
- float4 lightMap = 0;
- #if _AREA_UPPERBODY
- lightMap = tex2D(_UpperBodyLightMap, input.uv);
- #elif _AREA_LOWERBODY
- lightMap = tex2D(_LowerBodyLightMap, input.uv);
- #endif
- float materialEnum = lightMap.a;
- float materialEnumOffset = materialEnum + 0.0425;
- float outlineUVy = lerp(materialEnumOffset, materialEnumOffset + 0.5 > 1 ? materialEnumOffset + 0.5 - 1 : materialEnumOffset + 0.5 , fmod((round(materialEnumOffset/0.0625) - 1)/2, 2));
- float2 outlineUV = float2(0, outlineUVy);
- coolRamp = tex2D(_BodyCoolRamp, outlineUV).rgb;
- warmRamp = tex2D(_BodyWarmRamp, outlineUV).rgb;
- #elif _AREA_FACE
- float2 outlineUV = float2(0, 0.0625);
- coolRamp = tex2D(_BodyCoolRamp, outlineUV).rgb;
- warmRamp = tex2D(_BodyWarmRamp, outlineUV).rgb;
- #endif
-
- float3 ramp = lerp(coolRamp, warmRamp, 0.5);
- float3 albedo = pow(saturate(ramp), _OutlineGamma);
-
- float4 color = float4(albedo,1);
- color.rgb = MixFog(color.rgb, input.fogFactor);
-
- return color;
- }

SRUniversalDrawCorePass
- #ifndef _SR_UNIVERSAL_DRAW_CORE_PASS_INCLUDED
- #define _SR_UNIVERSAL_DRAW_CORE_PASS_INCLUDED
-
- struct Attributes
- {
- float3 positionOS : POSITION;
- half3 normalOS : NORMAL;
- half4 tangentOS : TANGENT;
- float2 uv : TEXCOORD0;
- };
-
- struct Varyings
- {
- float2 uv : TEXCOORD0;
- float4 positionWSAndFogFactor : TEXCOORD1; // xyz:positionWS, W:vertex fog factor
- float3 normalWS : TEXCOORD2;
- float3 viewDirectionWS : TEXCOORD3;
- float3 SH : TEXCOORD4;
- float4 positionCS : SV_POSITION;
- };
-
- //去饱和方法
- float3 desaturation(float3 colorIn)
- {
- float3 grayXfer = float3(0.3, 0.59, 0.11); // 心理学灰度因子
- float grayf = dot(colorIn, grayXfer);
- return float3(grayf, grayf, grayf);
- }
-
- struct Gradient
- {
- int colorsLength;
- float4 colors[8];
- };
-
- //梯度颜色
- Gradient GradientConstruct()
- {
- Gradient g;
- g.colorsLength = 2;
- g.colors[0] = float4(1,1,1,0);
- g.colors[1] = float4(1,1,1,1);
- g.colors[2] = float4(0,0,0,0);
- g.colors[3] = float4(0,0,0,0);
- g.colors[4] = float4(0,0,0,0);
- g.colors[5] = float4(0,0,0,0);
- g.colors[6] = float4(0,0,0,0);
- g.colors[7] = float4(0,0,0,0);
- return g;
- }
-
- //渐变采样方法
- float3 SampleGradient(Gradient Gradient, float Time)
- {
- float3 tempColor = Gradient.colors[0].rgb;
- for (int c = 1; c < Gradient.colorsLength; c++)
- {
- float colorPos = saturate((Time - Gradient.colors[c - 1].w) / (Gradient.colors[c].w - Gradient.colors[c - 1].w)) * step(c, Gradient.colorsLength - 1);
- tempColor = lerp(tempColor, Gradient.colors[c].rgb, colorPos);
- }
- #ifdef UNITY_COLORSPACE_GAMMA
- tempColor = LinearToSRGB(tempColor);
- #endif
- return tempColor;
- }
-
- Varyings vert(Attributes input)
- {
- Varyings output = (Varyings)0;
-
- //VertexPositionInputs和VertexNormalInputs两个结构体定义在Core.hlsl中,
- VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS);
- VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
- /*
- 这两个方法在ShaderVariablesFunctions文件中,用于获取VertexPositionInputs和VertexNormalInputs,它们包括大部分需求的信息
- struct VertexPositionInputs
- {
- float3 positionWS; // World space position
- float3 positionVS; // View space position
- float4 positionCS; // Homogeneous clip space position
- {
- input.positionCS.x:通常表示屏幕上的水平位置。其范围通常从0(屏幕的左边缘)到屏幕宽度减1(屏幕的右边缘,以像素为单位)。
- input.positionCS.y:通常表示屏幕上的垂直位置。其范围通常从0(屏幕的顶部)到屏幕高度减1(屏幕的底部,以像素为单位)。
- input.positionCS.z:通常表示片段在深度缓冲区中的深度值。其范围通常在0.0到1.0之间,表示从近裁剪平面到远裁剪平面的深度值。
- input.positionCS.w:通常表示屏幕空间中的透视除法系数。在一般情况下,你不太会直接使用它来进行计算。
- }
- float4 positionNDC;// Homogeneous normalized device coordinates
- {
- positionNDC.x:通常表示裁剪坐标系中的X坐标,其范围从-1表示裁剪体积的左侧边界,到1表示裁剪体积的右侧边界。
- positionNDC.y:通常表示裁剪坐标系中的Y坐标,其范围从-1表示裁剪体积的底部边界,到1表示裁剪体积的顶部边界。
- positionNDC.z:通常表示裁剪坐标系中的Z坐标,其范围从-1表示裁剪体积的近裁剪平面,到1表示裁剪体积的远裁剪平面。
- positionNDC.w:通常用于执行透视除法,将坐标从裁剪坐标系转换为标准化设备坐标系。它在顶点着色器中通常为非零值,但在片段着色器中可能会变为零,因为透视除法是在顶点着色器中执行的。
- }
- };
- struct VertexNormalInputs
- {
- real3 tangentWS;
- real3 bitangentWS;
- float3 normalWS;
- };
- */
- output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
- /*
- TRANSFORM_TEX这个宏定义在Macros.hlsl文件中,这个文件中还有还能多定义比如PI:3.1415926、LOG2_E:1.442695
- #define TRANSFORM_TEX(tex, name) ((tex.xy) * name##_ST.xy + name##_ST.zw) 看起来不过是添加ST控制,不需要的话不做这个操作也可以,比如这里,_BaseMap不过是个白图
- */
- output.positionWSAndFogFactor = float4(vertexInput.positionWS, ComputeFogFactor(vertexInput.positionCS.z)); // 做个组合w分量利用一下,省一点空间
- output.normalWS = vertexNormalInput.normalWS;
-
- output.viewDirectionWS = unity_OrthoParams.w == 0 ? GetCameraPositionWS() - vertexInput.positionWS : GetWorldToViewMatrix()[2].xyz;
- /*
- 如果不是ortho,直接坐标相减计算视角向量,如果是ortho,GetWorldToViewMatrix返回的是float4x4 UNITY_MATRIX_V,
- unity_OrthoParams这个量来自StdLib.hlsl文件,这里面也有关于PI的定义,看起来很多量都可以从这里拿
- float4x4 unity_CameraProjection;
- float4x4 unity_MatrixVP;
- float4x4 unity_ObjectToWorld;
- float4x4 unity_WorldToCamera;
- float3 _WorldSpaceCameraPos;
- float4 _ProjectionParams; // x: 1 (-1 flipped), y: near, z: far, w: 1/far
- float4 unity_ColorSpaceLuminance;
- float4 unity_DeltaTime; // x: dt, y: 1/dt, z: smoothDt, w: 1/smoothDt
- float4 unity_OrthoParams; // x: width, y: height, z: unused, w: ortho ? 1 : 0
- float4 _ZBufferParams; // x: 1-far/near, y: far/near, z: x/far, w: y/far or in case of a reversed depth buffer (UNITY_REVERSED_Z is 1) x = -1+far/near, y = 1, z = x/far, w = 1/far 这里看来是后者
- float4 _ScreenParams; // x: width, y: height, z: 1+1/width, w: 1+1/height
- float4 _Time; // x: t/20, y: t, z: t*2, w: t*3
- float4 _SinTime; // x: sin(t/20), y: sin(t), z: sin(t*2), w: sin(t*3)
- float4 _CosTime; // x: cos(t/20), y: cos(t), z: cos(t*2), w: cos(t*3)
- 还有一些方法GradientNoise、LinearEyeDepth。也定义了TRANSFORM_TEX,不止一个地方定义过这个呢
- */
- output.SH = SampleSH(lerp(vertexNormalInput.normalWS, float3(0,0,0), _IndirectLightFlattenNormal)); // 球谐函数,就是传入法线返回unity保存好的漫反射数据中对应位置的颜色,这里加了参数控制,因为卡渲有时不需要太多细节
- /*
- half3 SampleSH(half3 normalWS)
- {
- // LPPV is not supported in Ligthweight Pipeline
- real4 SHCoefficients[7];
- SHCoefficients[0] = unity_SHAr;
- SHCoefficients[1] = unity_SHAg;
- SHCoefficients[2] = unity_SHAb;
- SHCoefficients[3] = unity_SHBr;
- SHCoefficients[4] = unity_SHBg;
- SHCoefficients[5] = unity_SHBb;
- SHCoefficients[6] = unity_SHC;
-
- return max(half3(0, 0, 0), SampleSH9(SHCoefficients, normalWS));
- }
- */
-
- output.positionCS = vertexInput.positionCS;
-
- return output;
- }
-
- float4 frag(Varyings input, bool isFrontFace : SV_IsFrontFace): SV_TARGET
- {
- float3 positionWS = input.positionWSAndFogFactor.xyz;
- float4 shadowCoord = TransformWorldToShadowCoord(positionWS);
- Light mainLight = GetMainLight(shadowCoord);
-
- float3 lightDirectionWS = normalize(mainLight.direction);
- float3 normalWS = normalize(input.normalWS);
- float3 viewDirectionWS = normalize(input.viewDirectionWS);
-
- float3 baseColor = tex2D(_BaseMap, input.uv); // baseColor是纯白画布
- float4 areaMap = 0;
- #if _AREA_FACE
- areaMap = tex2D(_FaceColorMap, input.uv);
- #elif _AREA_HAIR
- areaMap = tex2D(_HairColorMap, input.uv);
- #elif _AREA_UPPERBODY
- areaMap = tex2D(_UpperBodyColorMap, input.uv);
- #elif _AREA_LOWERBODY
- areaMap = tex2D(_LowerBodyColorMap, input.uv);
- #endif
- baseColor = areaMap.rgb;
- //baseColor *= lerp((1,1,1), (1,1,1), 0.5);
- baseColor *= lerp(_BackFaceTintColor, _FrontFaceTintColor, isFrontFace);
-
- float4 lightMap = 0;
- #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
- {
- #if _AREA_HAIR
- lightMap = tex2D(_HairLightMap, input.uv);
- #elif _AREA_UPPERBODY
- lightMap = tex2D(_UpperBodyLightMap, input.uv);
- #elif _AREA_LOWERBODY
- lightMap = tex2D(_LowerBodyLightMap, input.uv);
- #endif
- }
- #endif
- float4 faceMap = 0;
- #if _AREA_FACE
- faceMap = tex2D(_FaceMap, input.uv);
- #endif
-
- //-----------------------------------------------------------------------------------------------------------------
- //间接光
- float3 indirectLightColor = input.SH.rgb * _IndirectLightUsage;
- // 添加光照图细节
- #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
- indirectLightColor *= lerp(1, lightMap.r, _IndirectLightOcclusionUsage);
- #elif _AREA_FACE
- indirectLightColor *= lerp(1, lerp(faceMap.g, 1, step(faceMap.r, 0.01)), _IndirectLightOcclusionUsage);
- /*
- 注意,step是后面值小于前面值,返回0,反之返回1,别想反了
- step(faceMap.r, 0.01)分出来是否受距离影响的区域 根据图片,不受距离影响的区域即r通道有值的部分:为嘴巴,眼睛,眉毛等。值为0,反之受影响的为1
- 即lerp(faceMap.g, 1, step(faceMap.r, 0.01))不受距离影响地方r通道有值的部分:用的是faceMap.g的值,受距离影响的r通道没有值的部分是1,也就是正常漫反射光
- 但是g通道有一部分本身即是1,那么根据rg通道的差异,得出的r通道覆盖的区域减去g通道覆盖的区域,也就是只有口部分是0其他部分全为1,这里做这么多只是为了筛选出口部分
- */
- #endif
- indirectLightColor *= lerp(1, baseColor, _IndirectLightMixBaseColor);
- //-----------------------------------------------------------------------------------------------------------------
- //主光
- float mainLightShadow = 1;
- float3 mainLightColor = lerp(desaturation(mainLight.color), mainLight.color, _MainLightColorUsage); // 这里做了降饱和插值提升效果,不然直接=mainLight.color;就行
- #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
- {
- float NoL = dot(normalWS, lightDirectionWS); // 计算法相和主光向量的dot [-1, 1]
- float remapNoL = NoL * 0.5 + 0.5; // [0, 1]
- mainLightShadow = smoothstep(1 - lightMap.g + _ShadowThresholdCenter - _ShadowThresholdSoftness, 1 - lightMap.g + _ShadowThresholdCenter + _ShadowThresholdSoftness, remapNoL); // 二值化朗伯特
- // 在光照图的g通道,有很多衣服上阴影的细节,接下来添加上去
- mainLightShadow *= lightMap.r;
- // 光照图的r通道,用于标识一些点不亮的也就是所谓的AO区域,直接乘上去,头发上的蝴蝶结就是点不亮的标识区域
- }
- #elif _AREA_FACE
- {
- float3 headForward = normalize(_HeadForward);
- float3 headRight = normalize(_HeadRight);
- float3 headUp = cross(headForward, headRight);
-
- float3 fixedLightDirectionWS = normalize(lightDirectionWS - dot(lightDirectionWS, headUp) * headUp); // 看起来是投影,把主光源的光照方向投影在垂直于headUp的平面上
- /*
- 投影到垂直于headUp的平面上,ws-up*(|ws.y|/|up|)
- 因为ws为单位向量,所以|ws.y| = cosθ、|up| = 1
- 所以简化为ws-up*cosθ。而cosθ= dot(lightDirectionWS, headUp)
- 故求出投影到垂直于headUp的平面上的向量
- */
- float2 sdfUV = float2(sign(dot(fixedLightDirectionWS, headRight)), 1) * float2(-1, 1) * input.uv; // 判断光照在左脸(负)还是右脸(正) float2(-1, 1)是因为sdf图应该左白右黑,所以反向
- /*
- float2(sign(dot(fixedLightDirectionWS, headRight)), 1)如果光照方向是右半就是float2(1,1),反之float2(-1,1)。只需要处理x是1还是-1,因为按照脸部中心对称
- 但是这张图是左右反过来的,所以我们再反一次* float2(-1, 1),最后* input.uv。算出脸部修正uv
- 但是在光和headRight夹角为90时,也就是光从正后方打来时,看cos曲线为0,由于sign的特性(-1,0,1),也就是说sdfUV的x永远为0
- */
- float sdfValue = tex2D(_FaceMap, sdfUV).a; // 如果是光和headRight夹角为90时,看那张图的a通道,采样的都是最左边白色,都是1,所以即使阈值是1也没办法奈何他
- // 然后用这个脸部修正uv采样sdf图获取sdf值
-
- float sdfThreshold = 1 - (dot(fixedLightDirectionWS, headForward) * 0.5 + 0.5); //主光越接近正面,阈值越接近0,阈值越低表示越容易被点亮 [0,1]
- sdfThreshold += _FaceShadowOffset; // 所以为了限制光和headRight夹角为90时sdfUV的x永远为0,采样的都是最左边白色,都是1的情况,把阈值做个小小的偏移,加上一点点0.01就好,只要超过1就行
- float sdf = smoothstep(sdfThreshold - _FaceShadowTransitionSoftness, sdfThreshold + _FaceShadowTransitionSoftness, sdfValue);
- mainLightShadow = lerp(faceMap.g, sdf, step(faceMap.r, 0.01)); // sdf不应该影响ao区域,
- }
- #endif
- //-----------------------------------------------------------------------------------------------------------------
- //Ramp
- //计算uv
- float2 rampUV;
-
- int rampRowIndex = 0;
- int rampRowNum = 1;
- #if _AREA_HAIR
- {
- rampRowIndex = 0;
- rampRowNum = 1;
- }
- #elif _AREA_UPPERBODY || _AREA_LOWERBODY
- {
- int rawIndex = (round((lightMap.a + 0.0425)/0.0625) - 1)/2;
- rampRowIndex = lerp(rawIndex, rawIndex + 4 < 8 ? rawIndex + 4 : rawIndex + 4 - 8, fmod(rawIndex, 2));
- rampRowNum = 8;
- }
- #elif _AREA_FACE
- {
- rampRowIndex = 0;
- rampRowNum = 8;
- }
- #endif
- // 使用预规定的方式计算行数,用于计算采样uv的y坐标,x坐标使用阴影值
- float rampUVy = (2 * rampRowIndex + 1) * (1.0 / (rampRowNum * 2));
- float rampUVx = mainLightShadow * (1 - _ShadowRampOffset) + _ShadowRampOffset; // 做个映射,[0.75,1]这张图在0.85左右往后就是白色,我感觉不映射直接用mainLightShadow效果差异也不大
- rampUV = float2(rampUVx, rampUVy);
- //采样
- float3 rampColor;
-
- float3 coolRamp = 1;
- float3 warmRamp = 1;
- #if _AREA_HAIR
- {
- coolRamp = tex2D(_HairCoolRamp, rampUV).rgb;
- warmRamp = tex2D(_HairWarmRamp, rampUV).rgb;
- }
- #elif _AREA_FACE || _AREA_UPPERBODY || _AREA_LOWERBODY
- {
- coolRamp = tex2D(_BodyCoolRamp, rampUV).rgb;
- warmRamp = tex2D(_BodyWarmRamp, rampUV).rgb;
- }
- #endif
- //根据白天夜晚插值冷暖色
- float isDay = lightDirectionWS.y * 0.5 + 0.5;
- rampColor = lerp(coolRamp, warmRamp, 1);
- //-----------------------------------------------------------------------------------------------------------------
- //修补主光源
- float3 fixedMainLightColor = mainLightColor * baseColor * rampColor;
- //-----------------------------------------------------------------------------------------------------------------
- //高光
- float3 specularColor = 0;
- #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
- {
- //布林冯,但是直接这样看起来太光滑
- float3 halfVectorWS = normalize(viewDirectionWS + lightDirectionWS);
- float NoH = dot(normalWS, halfVectorWS);
- float blinnPhong = pow(saturate(NoH), _SpecularExpon);
- //用光照图的蓝色通道作为阈值,超过阈值才会产生高光 这里金属和非金属分别处理
- //非金属 反射率Ks,固定0.04
- float nonMetalSpecular = step(1.0 - blinnPhong, lightMap.b) * _SpecularKsNonMetal;
- //金属 反射率都比较大且差异较大,蓝色通道控制各个金属部分差异
- float metalSpecular = blinnPhong * lightMap.b * _SpecularKsMetal;
- //得有一个lerp控制什么时候是金属什么时候是非金属,在光照图的阿尔法通道,0.52灰度值表示金属
- //找出金属部分,metallic越接近于0就越靠近金属
- float metallic = 0;
- #if _AREA_UPPERBODY || _AREA_LOWERBODY
- {
- metallic = saturate( (1 - 10 * abs(lightMap.a - 0.52)) ); // 金属影响系数,暂定10
- }
- #endif
- specularColor = lerp(nonMetalSpecular, metalSpecular * baseColor, metallic);
- specularColor *= mainLight.color;
- specularColor *= _SpecularBrightness;
- }
- #endif
- //-----------------------------------------------------------------------------------------------------------------
- //黑丝
- float3 stockingsEffect = 1;
- #if _AREA_UPPERBODY || _AREA_LOWERBODY
- {
- //红通道是遮罩,绿通道是丝的透光度,蓝通道是丝的细节,uv放大一定倍数采样可以提升细节量
- //采样
- float2 stockingsMapRG = 0;
- float stockingsMapB = 0;
- #if _AREA_UPPERBODY
- {
- stockingsMapRG = tex2D(_UpperBodyStockings, input.uv).rg;
- stockingsMapB = tex2D(_UpperBodyStockings, input.uv * 20).b;
- }
- #elif _AREA_LOWERBODY
- {
- stockingsMapRG = tex2D(_LowerBodyStockings, input.uv).rg;
- stockingsMapB = tex2D(_LowerBodyStockings, input.uv * 20).b;
- }
- #endif
-
- //混入细节
- float NoV = dot(normalWS, viewDirectionWS);
- //都不过是为了加控制
- float fac = pow(saturate(NoV), _StockingsTransitionPower);;
- fac = saturate( (fac - _StockingsTransitionHardness/2) / (1 - _StockingsTransitionHardness) );
- fac = fac * (stockingsMapB * _StockingsTextureUsage + (1 - _StockingsTextureUsage));
- fac = lerp(fac, 1, stockingsMapRG.g);
- //构造颜色曲线
- Gradient curve = GradientConstruct();
- curve.colorsLength = 3;
- curve.colors[0] = float4(_StockingsDarkColor, 0);
- curve.colors[1] = float4(_StockingsTransitionColor, _StockingsTransitionThreshold);
- curve.colors[2] = float4(_StockingsLightColor, 1);
- //采样渐变
- float3 stockingsColor = SampleGradient(curve, fac);
- //加遮罩
- stockingsEffect = lerp(1, stockingsColor, stockingsMapRG.r);
- }
- #endif
- //-----------------------------------------------------------------------------------------------------------------
- //鼻尖的描边
- float fakeOutlineEffect = 0;
- float3 fakeOutlineColor = 0;
- #if _AREA_FACE && _OUTLINE_ON
- {
- float4 faceMap = tex2D(_FaceMap, input.uv);
- float fakeOutline = faceMap.b;
- float3 headForward = normalize(_HeadForward);
- fakeOutlineEffect = smoothstep(0.0, 0.25, pow(saturate(dot(headForward, viewDirectionWS)), 20) * fakeOutline);
-
- float2 outlineUV = float2(0, 0.0625);
- float3 coolRamp = tex2D(_BodyCoolRamp, outlineUV).rgb;
- float3 warmRamp = tex2D(_BodyWarmRamp, outlineUV).rgb;
- float3 ramp = lerp(coolRamp, warmRamp, 0.5);
- fakeOutlineColor = pow(ramp, _OutlineGamma);
- }
- #endif
- //-----------------------------------------------------------------------------------------------------------------
- //边缘光 打开URP深度图
- float linearEyeDepth = LinearEyeDepth(input.positionCS.z, _ZBufferParams) / 10; // 离相机越近就越黑 正确
- float3 normalVS = mul((float3x3)UNITY_MATRIX_V, normalWS); // 正确
- float2 uvOffset = float2(sign(normalVS.x), 0) * _RimLightWidth / (1 + linearEyeDepth); // 正确
- int2 loadTexPos = input.positionCS.xy + uvOffset * _ScaledScreenParams.xy; // 正确
- float offsetSceneDepth = LoadSceneDepth(loadTexPos) * 5;
- float offsetLinearEyeDepth = LinearEyeDepth(offsetSceneDepth, _ZBufferParams);
- float rimLight = saturate(offsetLinearEyeDepth - (linearEyeDepth + _RimLightThreshold)) / _RimLightFadeout;
- //这里模型的深度图因材质问题搞不定,放置了,之后再说吧
- //-----------------------------------------------------------------------------------------------------------------
- float3 albedo = 0;
- albedo += indirectLightColor;
- albedo += fixedMainLightColor;
- albedo += specularColor;
- albedo *= stockingsEffect;
- albedo = lerp(albedo, fakeOutlineColor, fakeOutlineEffect);
-
- float alpha = _Alpha;
-
- //albedo = viewDirectionWS.rgb;
- float4 finalColor = float4(albedo, alpha);
- return finalColor;
- }
- #endif

SendVectorToShader脚本
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using Unity.Mathematics;
- using Unity.VisualScripting;
- using UnityEngine;
-
- public class SendVectorToShader : MonoBehaviour
- {
- public Transform HeadBoneTransform;
- public Transform HeadForwardTransform;
- public Transform HeadRightTransform;
-
- private Renderer[] allRenderers;
-
- private int HeadForwardID = Shader.PropertyToID("_HeadForward");
- private int HeadRightID = Shader.PropertyToID("_HeadRight");
-
- #if UNITY_EDITOR
- private void OnValidate()
- {
- LateUpdate();
- }
- #endif
- private void LateUpdate()
- {
- if(allRenderers == null)
- {
- allRenderers = GetComponentsInChildren<Renderer>(true);
- }
- Renderer tempRenderer;
- for (int i = 0; i < allRenderers.Count(); i++)
- {
- tempRenderer = allRenderers[i];
- foreach(Material tempMaterial in tempRenderer.sharedMaterials)
- {
- if (tempMaterial.shader)
- {
- if(tempMaterial.shader.name == "Unlit/SRUniversal")
- {
- tempMaterial.SetVector(HeadForwardID, HeadForwardTransform.position - HeadBoneTransform.position);
- tempMaterial.SetVector(HeadRightID, HeadRightTransform.position - HeadBoneTransform.position);
- }
-
- }
- }
- }
- }
- }

cg/hlsl语法链接:
Unity URP CG/HLSL精简规范总结_凯尔315的博客-CSDN博客
unitypackage资源链接:
https://download.csdn.net/download/qq_55895529/88370041?spm=1001.2014.3001.5503
原作视频链接:
【Unity/虚幻5/Blender】3种引擎 崩坏: 星穹铁道风格 卡通渲染 从球谐光照到眉毛透过刘海 完整流程_哔哩哔哩_bilibili
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。