当前位置:   article > 正文

URP 简单卡渲_urp smooth

urp smooth

 使用unity版本为2022.2.21f1

shader文件

  1. Shader "Unlit/SRUniversal"
  2. {
  3. Properties
  4. {
  5. [KeywordEnum(None,Face,Hair,UpperBody,LowerBody)] _Area("Material area", Float) = 0
  6. [HideInInspector] _HeadForward("", Vector) = (0,0,1)
  7. [HideInInspector] _HeadRight("", Vector) = (1,0,0)
  8. [Header(Base Color)]
  9. [HideInInspector] _BaseMap("", 2D) = "white"{}
  10. [NoScaleOffset] _FaceColorMap("Face color map (Default white)", 2D) = "white"{}
  11. [NoScaleOffset] _HairColorMap("Hair color map (Default white)", 2D) = "white"{}
  12. [NoScaleOffset] _UpperBodyColorMap("Upper body color map (Default white)", 2D) = "white"{}
  13. [NoScaleOffset] _LowerBodyColorMap("Lower body color map (Default white)", 2D) = "white"{}
  14. _FrontFaceTintColor("Front face tint color (Default white)", Color) = (1,1,1)
  15. _BackFaceTintColor("Back face tint color (Default white)", Color) = (1,1,1)
  16. _Alpha("Alpha (Default 1)", Range(0, 1)) = 1
  17. _AlphaClip("Alpha clip (Default 0.333)", Range(0, 1)) = 0.333
  18. [Header(Light Map)]
  19. [NoScaleOffset] _HairLightMap("Hair light map (Default black)", 2D) = "black"{}
  20. [NoScaleOffset] _UpperBodyLightMap("Upper body light map (Default black)", 2D) = "black"{}
  21. [NoScaleOffset] _LowerBodyLightMap("Lower body light map (Default black)", 2D) = "black"{}
  22. [Header(Ramp Map)]
  23. [NoScaleOffset] _HairCoolRamp("Hair cool ramp (Default white)", 2D) = "white"{}
  24. [NoScaleOffset] _HairWarmRamp("Hair warm ramp (Default white)", 2D) = "white"{}
  25. [NoScaleOffset] _BodyCoolRamp("Body cool ramp (Default white)", 2D) = "white"{}
  26. [NoScaleOffset] _BodyWarmRamp("Body warm ramp (Default white)", 2D) = "white"{}
  27. [Header(Indirect Lighting)]
  28. _IndirectLightFlattenNormal("Indirect light flatten normal (Default 0)", Range(0, 1)) = 0
  29. _IndirectLightUsage("Indirect light usage (Default 0.5)", Range(0, 1)) = 0.5
  30. _IndirectLightOcclusionUsage("Indirect light occlusion usage (Default 0.5)", Range(0, 1)) = 0.5
  31. _IndirectLightMixBaseColor("Indirect light base color (Default 1)", Range(0, 1)) = 1
  32. [Header(Main Lighting)]
  33. _MainLightColorUsage("Main light color usage (Default 1)", Range(0, 1)) = 1
  34. _ShadowThresholdCenter("Shadow threshold center (Default 0)", Range(-1, 1)) = 0
  35. _ShadowThresholdSoftness("Shadow threshold softness (Default 0.1)", Range(0, 1)) = 0.1
  36. _ShadowRampOffset("Shadow ramp offset (Default 0.75)", Range(0, 1)) = 0.75
  37. [Header(Face)]
  38. [NoScaleOffset] _FaceMap("Face map (Default black)", 2D) = "black"{}
  39. _FaceShadowOffset("Face shadow offset (Default -0.01)", Range(-1, 1)) = -0.01
  40. _FaceShadowTransitionSoftness("Face shadow transition softness (Default 0.05)", Range(0, 1)) = 0.05
  41. [Header(Specular)]
  42. _SpecularExpon("Specular exponent (Default 50)", Range(1, 128)) = 50
  43. _SpecularKsNonMetal("Specular Ks non-metal (Default 0.04)", Range(0, 1)) = 0.04
  44. _SpecularKsMetal("Specular Ks metal (Default 1)", Range(0, 1)) = 1
  45. _SpecularBrightness("Specular brightness (Default 1)", Range(0, 10)) = 1
  46. [Header(Sockings)]
  47. [NoScaleOffset] _UpperBodyStockings("Upper body stockings (Default black)", 2D) = "black"{}
  48. [NoScaleOffset] _LowerBodyStockings("Lower body stockings (Default black)", 2D) = "black"{}
  49. _StockingsDarkColor("Stocking dark color (Default black)", Color) = (0,0,0)
  50. [HDR] _StockingsLightColor("Stocking light color (Default 1.8 1.48299 0.856821)", Color) = (1.8, 1.48299, 0.856821)
  51. [HDR] _StockingsTransitionColor("Stocking Transition color (Default 0.360381 0.242986 0.358131)", Color) = (0.360381, 0.242986, 0.358131)
  52. _StockingsTransitionThreshold("Stocking transition threshold (Default 0.58)", Range(0, 1)) = 0.58
  53. _StockingsTransitionPower("Stocking transition Power (Default 1)", Range(0.1, 50)) = 1
  54. _StockingsTransitionHardness("Stocking transition hardness (Default 0.4)", Range(0, 1)) = 0.4
  55. _StockingsTextureUsage("Stocking texture usage (Default 0.1)", Range(0, 1)) = 0.1
  56. [Header(Rim Lighting)]
  57. _RimLightWidth("Rim light width (Default 1)", Range(0, 10)) = 1
  58. _RimLightThreshold("Rim light threshold (Default 0.05)", Range(-1, 1)) = 0.05
  59. _RimLightFadeout("Rim light fadeout (Default 1)", Range(0.01, 1)) = 1
  60. [HDR] _RimLightTintColor("Rim light tint color (Default white)", Color) = (1,1,1)
  61. _RimLightBrightness("Rim light brightness (Default 1)", Range(0, 10)) = 1
  62. _RimLightMixAlbedo("Rim light mix albedo (Default 0.9)", Range(0, 1)) = 0.9
  63. [Header(Emission)]
  64. [Toggle(_EMISSION_ON)] _UseEmission("Use emission (Default False)", Float) = 0
  65. _EmissionMixBaseColor("Emission mix base color (Default 1)", Range(0, 1)) = 1
  66. _EmissionTintColor("Emission tint color (Default white)", Color) = (1,1,1)
  67. _EmissionIntensity("Emission intensity (Default 1)", Range(0, 100)) = 1
  68. [Header(Outline)]
  69. [Toggle(_OUTLINE_ON)] _UseOutline("Use outline (Default True)", Float) = 1
  70. [Toggle(_OUTLINE_VERTEX_COLOR_SMOOTH_NORMAL)] _OutlineUseVertexColorSmoothNormal("Use vertex color smooth normal (Default False)", Float) = 0
  71. _OutlineWidth("Outline width (Default 1)", Range(0, 10)) = 1
  72. _OutlineGamma("Outline gamma (Default 16)", Range(1, 255)) = 16
  73. [Header(Surface Options)]
  74. [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull (Default back)", Float) = 2
  75. [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlendMode("Src blend mode (Default One)", Float) = 1
  76. [Enum(UnityEngine.Rendering.BlendMode)] _DstBlendMode("Dst blend mode (Default Zero)", Float) = 0
  77. [Enum(UnityEngine.Rendering.BlendOp)] _BlendOp("Blend operation (Default Add)", Float) = 0
  78. [Enum(Off, 0, On, 1)] _ZWrite("ZWrite (Default On)", Float) = 1
  79. _StencilRef("Stencil reference (Default 0)", Range(0, 255)) = 0
  80. [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil comparison (Default disabled)", Int) = 0
  81. [Enum(UnityEngine.Rendering.StencilOp)] _StencilPassOp("Stencil pass operation (Default keep)", Int) = 0
  82. [Enum(UnityEngine.Rendering.StencilOp)] _StencilFailOp("Stencil fail operation (Default keep)", Int) = 0
  83. [Enum(UnityEngine.Rendering.StencilOp)] _StencilZFailOp("Stencil Z fail operation (Default keep)", Int) = 0
  84. [Header(Draw Overlay)]
  85. [Toggle(_DRAW_OVERLAY_ON)] _UseDrawOverlay("Use draw overlay (Default False)", Float) = 0
  86. [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlendModeOverlay("Overlay pass src blend mode (Default One)", Float) = 1
  87. [Enum(UnityEngine.Rendering.BlendMode)] _DstBlendModeOverlay("Overlay pass src blend mode (Default Zero)", Float) = 0
  88. [Enum(UnityEngine.Rendering.BlendOp)] _BlendOpOverlay("Overlay pass blend operation (Default Add)", Float) = 0
  89. _StencilRefOverlay("Overlay pass stencil reference (Default 0)", Range(0, 255)) = 0
  90. [Enum(UnityEngine.Rendering.CompareFunction)] _StencilCompOverlay ("Overlay pass stencil comparison (Default disabled)", Int) = 0
  91. }
  92. SubShader
  93. {
  94. LOD 100
  95. HLSLINCLUDE
  96. HLSL code that you want to share goes here
  97. #pragma shader_feature_local _AREA_FACE
  98. #pragma shader_feature_local _AREA_HAIR
  99. #pragma shader_feature_local _AREA_UPPERBODY
  100. #pragma shader_feature_local _AREA_LOWERBODY
  101. #pragma shader_feature_local _OUTLINE_ON
  102. #pragma shader_feature_local _OUTLINE_VERTEX_COLOR_SMOOTH_NORMAL
  103. #pragma shader_feature_local _DRAW_OVERLAY_ON
  104. #pragma shader_feature_local _EMISSION_ON
  105. ENDHLSL
  106. Pass
  107. {
  108. Name "ShadowCaster"
  109. Tags{"LightMode" = "ShadowCaster"} // 阴影贴图
  110. ZWrite [_ZWrite]
  111. ZTest LEqual
  112. ColorMask RGBA
  113. Cull [_Cull]
  114. HLSLPROGRAM
  115. //#pragma exclude_renders gles gles3 glcore
  116. #pragma targe 4.5
  117. // -------------------------------------------------------------------------------------------
  118. // Material Keywords
  119. #pragma shader_feature_local_fragment _ALPHATEST_ON
  120. #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
  121. // -------------------------------------------------------------------------------------------
  122. // GPU Instancing
  123. #pragma multi_compile_instancing
  124. #pragma multi_compile _ DOTS_INSTANCING_ON
  125. // -------------------------------------------------------------------------------------------
  126. // Universial Pipeline keywords
  127. // this is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
  128. #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
  129. #pragma vertex ShadowPassVertex
  130. #pragma fragment ShadowPassFragment
  131. #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
  132. #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
  133. ENDHLSL
  134. }
  135. Pass
  136. {
  137. Name "DepthOnly"
  138. Tags{"LightMode" = "DepthOnly" "Queue" = "Transparent" } // 深度贴图
  139. ZWrite [_ZWrite]
  140. ColorMask RGBA
  141. Cull [_Cull]
  142. HLSLPROGRAM
  143. //#pragma exclude_renders gles gles3 glcore
  144. #pragma targe 4.5
  145. // -------------------------------------------------------------------------------------------
  146. // Material Keywords
  147. #pragma shader_feature_local_fragment _ALPHATEST_ON
  148. #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
  149. // -------------------------------------------------------------------------------------------
  150. // GPU Instancing
  151. #pragma multi_compile_instancing
  152. #pragma multi_compile _ DOTS_INSTANCING_ON
  153. #pragma Vertex DepthOnlyVertex
  154. #pragma fragment DepthOnlyFragment
  155. #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
  156. #include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
  157. ENDHLSL
  158. }
  159. Pass
  160. {
  161. Name "DepthNormals"
  162. Tags{"LightMode" = "DepthNormals"} // 向SSAO传输值
  163. ZWrite [_ZWrite]
  164. Cull [_Cull]
  165. HLSLPROGRAM
  166. //#pragma exclude_renders gles gles3 glcore
  167. #pragma targe 4.5
  168. // -------------------------------------------------------------------------------------------
  169. // Material Keywords
  170. #pragma shader_feature_local _NORMALMAP
  171. #pragma shader_feature_local _PARALLAXMAP
  172. #pragma shader_feature_local _ _DETAIL_MULTX2 _DETAIL_SCALED
  173. #pragma shader_feature_local_fragment _ALPHATEST_ON
  174. #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
  175. // -------------------------------------------------------------------------------------------
  176. // GPU Instancing
  177. #pragma multi_compile_instancing
  178. #pragma multi_compile _ DOTS_INSTANCING_ON
  179. #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
  180. #include "Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl"
  181. ENDHLSL
  182. }
  183. Pass
  184. {
  185. Name "DrawCore"
  186. Tags{ "RenderPipeline" = "UniversalRenderPipeline" "RenderType" = "Opaque" "LightMode" = "SRPDefaultUnlit"}
  187. Cull [_Cull]
  188. Stencil{
  189. Ref [_StencilRef] //这是传进去的int值(默认00255】注意这是二进制11111111),如果在测试就用这个值和模板值(如果没有写入过默认0)作比较,受readMask影响、如果在写入就是写入这个值,受writeMask影响
  190. Comp [_StencilComp] //何时通过模板测试,这个和写入没有任何关系,还有CompBack和CompFront专门针对背面和正面,如果存在Comp则会覆盖他们,值为:Never、LessEqual、LEqual、Greater、NotEqual、GEqual、Always
  191. Pass [_StencilPassOp] //设置对通过模板测试的像素怎么处理,还有PassBack和PassFront专门针对背面和正面,如果存在Pass则会覆盖他们,值为:Keep(保持原值)、Zero(写入模板值0)、Replace(写入Ref值)、IncrSat(加上去但不超过255)、DecrSat(相减但不小于0)、Invert(所有位取反)、IncrWrap(加上去但超过255会从0重新开始)、DecrWrap(相减但小于0会从255重新开始)
  192. Fail [_StencilFailOp] //设置对未通过模板测试的像素怎么处理,还有FailBack和FailFront专门针对背面和正面,如果存在Fail则会覆盖他们,值和Pass的相同
  193. ZFail [_StencilZFailOp] //当像素通过模板测试但未通过深度测试时怎么处理,还有ZFailBack和ZFailFront专门针对背面和正面,如果存在ZFail则会覆盖他们,值和Pass的相同
  194. }
  195. Blend [_SrcBlendMode] [_DstBlendMode]
  196. BlendOp [_BlendOp]
  197. ZWrite [_ZWrite]
  198. HLSLPROGRAM
  199. //#pragma exclude_renders gles gles3 glcore
  200. #pragma targe 4.5
  201. #pragma multi_compile _MAIN_LIGHT_SHADOWS
  202. #pragma multi_compile _MAIN_LIGHT_SHADOWS_CASCADE
  203. #pragma multi_compile _SHADOW_SOFT
  204. #pragma vertex vert
  205. #pragma fragment frag
  206. #pragma multi_compile_fog
  207. #include "SRUniversalInput.hlsl"
  208. #include "SRUniversalDrawCorePass.hlsl"
  209. ENDHLSL
  210. }
  211. Pass
  212. {
  213. Name "DrawOutline"
  214. Tags{ "RenderPipeline" = "UniversalRenderPipeline" "RenderType" = "Opaque" "LightMode" = "UniversalForwardOnly" }
  215. Cull Front
  216. ZWrite[_ZWrite]
  217. HLSLPROGRAM
  218. #pragma vertex vert
  219. #pragma fragment frag
  220. #pragma multi_compile_fog
  221. #if _OUTLINE_ON
  222. #include "SRUniversalInput.hlsl"
  223. #include "SRUniversalDrawOutlinePass.hlsl"
  224. #else
  225. struct Attribute {};
  226. struct Varyings
  227. {
  228. float4 positionCS : SV_POSITION;
  229. };
  230. Varyings vert(Attribute input)
  231. {
  232. return (Varyings)0;
  233. }
  234. float4 frag(Varyings input) : SV_TARGET
  235. {
  236. return 0;
  237. }
  238. #endif
  239. ENDHLSL
  240. }
  241. }
  242. Fallback Off
  243. }

hlsl文件

SRUniversalInput

  1. #ifndef _SR_UNIVERSAL_INPUT_INCLUDED
  2. #define _SR_UNIVERSAL_INPUT_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  4. /*
  5. 包含VertexPositionInputs、VertexNormalInputs结构以及各种基础定义 #define TEXTURE2D_X(textureName) TEXTURE2D_ARRAY(textureName)
  6. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
  7. 约定:
  8. unity在世界空间是左手,但是在视图空间为右手。世界到视图空间的矩阵行列式是负的
  9. 对于cubmap捕获(反射探针),视图空间仍是左手,行列式为正
  10. //WS:世界空间
  11. //RWS:相机相对世界空间。为了提高精度,已经减去了相机平移的空间
  12. //VS:视图空间
  13. //OS:对象空间
  14. //CS:同构剪辑空间
  15. //TS:切线空间
  16. //TXS:纹理空间
  17. 大写字母矢量都指向像素位置且归一View vector、Light vector、Light vector、Half vector
  18. out和inout过滤器,当声明函数的“out”参数时,它们总是最后一个
  19. 不要使用SetGlobalFloatArray或SetComputeFloatParams。//数组可以是hlsl中的别名。示例:uniform float4-packedArray[3];static float unpackedArray[12]=(float[12])packedArray;
  20. *包含非常多的常用基本函数定义PackHeightmap、GetPositionInput、SinFromCos、Orthonormalize等等*
  21. -----------------------------------------------------------------------------------------------------------------
  22. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
  23. Unpack888UIntToFloat2(uint3 x)、Unpack8ToFloat2(float f)、PackToR5G6B5(float3 rgb) 看起来是各种格式互转的方法
  24. -----------------------------------------------------------------------------------------------------------------
  25. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl"
  26. UNITY_VERSION宏
  27. -----------------------------------------------------------------------------------------------------------------
  28. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"
  29. InputData结构体、很多常量输入(应该是unity给值,直接拿那种)比如_MainLightPosition
  30. -----------------------------------------------------------------------------------------------------------------
  31. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl"
  32. 各种各样的方法,GetWorldSpaceViewDir之类的获取各种输入结构、LinearDepthToEyeDepth变换方法、TransformScreenUV(inout float2 uv)甚至编码解码什么的
  33. */
  34. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  35. /*
  36. 各种光照方法LightingLambert、LightingSpecular、LightingPhysicallyBased、VertexLighting、CalculateLightingColor、CalculateBlinnPhong、UniversalFragmentPBR、UniversalFragmentBlinnPhong、UniversalFragmentBakedLit
  37. 结构体LightingData获取各种光照信息
  38. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl" 光反射模型
  39. 结构体BRDFData、方法:InitializeBRDFData、EnvironmentBRDFSpecular、DirectBRDFSpecular
  40. {
  41. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/BSDF.hlsl" 包括BRDF反射、BTDF透射、BDDF衍射
  42. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
  43. 方法:ClampRoughnessForRaytracing、BlendNormal、ConvertRoughnessToAnisotropy材质属性(粗糙度)相关的
  44. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceData.hlsl"
  45. 定义SurfaceData结构体,是物体表面的各种属性摩擦、金属、间接光遮....
  46. }
  47. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Debug/Debugging3D.hlsl"
  48. 方法:CanDebugOverrideOutputColor、CalculateColorForDebugMaterial看起来都是debug用的方法
  49. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
  50. 方法:SampleProbeVolumePixel、SampleLightmap、GlossyEnvironmentReflection、GlobalIllumination都是一些全局照明所需要的方法
  51. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
  52. 定义Light结构、方法:灯光衰减DistanceAttenuation、GetMainLight等
  53. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl"
  54. 定义AmbientOcclusionFactor结构,GetScreenSpaceAmbientOcclusion屏幕空间环境光遮挡
  55. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl" 看起来是贴花相关的东西
  56. */
  57. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
  58. //只是声明深度图,附带采样、读取方法SampleSceneDepth、LoadSceneDepth
  59. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
  60. //阴影相关,定义ShadowSamplingData结构体,GetMainLightShadowSamplingData、GetMainLightShadowParams、SampleShadowmap、ApplyShadowBias
  61. /*
  62. 像这样做就是放在常量缓冲区,下面这种做法是unity宏,确保在支持时使用它们
  63. cbuffer UnityPerFrame {
  64. float4x4 unity_MatrixVP;
  65. };
  66. */
  67. CBUFFER_START(UnityPerMaterial)
  68. float3 _HeadForward;
  69. float3 _HeadRight;
  70. sampler2D _BaseMap;
  71. float4 _BaseMap_ST;
  72. #if _AREA_FACE
  73. sampler2D _FaceColorMap;
  74. #elif _AREA_HAIR
  75. sampler2D _HairColorMap;
  76. #elif _AREA_UPPERBODY
  77. sampler2D _UpperBodyColorMap;
  78. #elif _AREA_LOWERBODY
  79. sampler2D _LowerBodyColorMap;
  80. #endif
  81. float3 _FrontFaceTintColor;
  82. float3 _BackFaceTintColor;
  83. float _Alpha;
  84. float _AlphaClip;
  85. #if _AREA_HAIR
  86. sampler2D _HairLightMap;
  87. #elif _AREA_UPPERBODY
  88. sampler2D _UpperBodyLightMap;
  89. #elif _AREA_LOWERBODY
  90. sampler2D _LowerBodyLightMap;
  91. #endif
  92. #if _AREA_HAIR
  93. sampler2D _HairCoolRamp;
  94. sampler2D _HairWarmRamp;
  95. #elif _AREA_FACE || _AREA_UPPERBODY || _AREA_LOWERBODY
  96. sampler2D _BodyCoolRamp;
  97. sampler2D _BodyWarmRamp;
  98. #endif
  99. float _IndirectLightFlattenNormal;
  100. float _IndirectLightUsage;
  101. float _IndirectLightOcclusionUsage;
  102. float _IndirectLightMixBaseColor;
  103. float _MainLightColorUsage;
  104. float _ShadowThresholdCenter;
  105. float _ShadowThresholdSoftness;
  106. float _ShadowRampOffset;
  107. #if _AREA_FACE
  108. sampler2D _FaceMap;
  109. float _FaceShadowOffset;
  110. float _FaceShadowTransitionSoftness;
  111. #endif
  112. #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
  113. float _SpecularExpon;
  114. float _SpecularKsNonMetal;
  115. float _SpecularKsMetal;
  116. float _SpecularBrightness;
  117. #endif
  118. #if _AREA_UPPERBODY || _AREA_LOWERBODY
  119. #if _AREA_UPPERBODY
  120. sampler2D _UpperBodyStockings;
  121. #elif _AREA_LOWERBODY
  122. sampler2D _LowerBodyStockings;
  123. #endif
  124. float3 _StockingsDarkColor;
  125. float3 _StockingsLightColor;
  126. float3 _StockingsTransitionColor;
  127. float _StockingsTransitionThreshold;
  128. float _StockingsTransitionPower;
  129. float _StockingsTransitionHardness;
  130. float _StockingsTextureUsage;
  131. #endif
  132. float _RimLightWidth;
  133. float _RimLightThreshold;
  134. float _RimLightFadeout;
  135. float3 _RimLightTintColor;
  136. float _RimLightBrightness;
  137. float _RimLightMixAlbedo;
  138. #if _OUTLINE_ON
  139. float _OutlineWidth;
  140. float _OutlineGamma;
  141. #endif
  142. CBUFFER_END
  143. #endif

 SRUniversalDrawOutlinePass

  1. struct Attributes
  2. {
  3. float3 positionOS : POSITION;
  4. float3 normalOS : NORMAL;
  5. float4 tangentOS : TANGENT;
  6. float4 color : COLOR;
  7. float4 uv : TEXCOORD0;
  8. };
  9. struct Varyings
  10. {
  11. float4 positionCS : SV_POSITION;
  12. float2 uv : TEXCOORD0;
  13. float fogFactor : TEXCOORD1;
  14. float4 color : TEXCOORD2;
  15. };
  16. float GetCameraFOV()
  17. {
  18. //https://answers.unity.com/questions/770838/how-can-i-extract-the-fov-information-from-the-pro.html
  19. float t = unity_CameraProjection._m11;
  20. float Rad2Deg = 180 / 3.1415;
  21. float fov = atan(1.0f / t) * 2.0 * Rad2Deg;
  22. return fov;
  23. }
  24. float ApplyOutlineDistanceFadeOut(float inputMulFix)
  25. {
  26. //make outline "fadeout" if character is too small in camera's view
  27. return saturate(inputMulFix);
  28. }
  29. float GetOutlineCameraFovAndDistanceFixMultiplier(float positionVS_Z)
  30. {
  31. float cameraMulFix;
  32. if(unity_OrthoParams.w == 0)
  33. {
  34. // Perspective camera case
  35. // keep outline similar width on screen accoss all camera distance
  36. cameraMulFix = abs(positionVS_Z);
  37. // can replace to a tonemap function if a smooth stop is needed
  38. cameraMulFix = ApplyOutlineDistanceFadeOut(cameraMulFix);
  39. // keep outline similar width on screen accoss all camera fov
  40. cameraMulFix *= GetCameraFOV();
  41. }
  42. else
  43. {
  44. // Orthographic camera case
  45. float orthoSize = abs(unity_OrthoParams.y);
  46. orthoSize = ApplyOutlineDistanceFadeOut(orthoSize);
  47. cameraMulFix = orthoSize * 50; // 50 is a magic number to match perspective camera's outline width
  48. }
  49. return cameraMulFix * 0.00005; // mul a const to make return result = default normal expand amount WS
  50. }
  51. Varyings vert(Attributes input)
  52. {
  53. Varyings output = (Varyings)0;
  54. VertexPositionInputs vertexPositionInput = GetVertexPositionInputs(input.positionOS);
  55. VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
  56. float width = _OutlineWidth;
  57. width *= GetOutlineCameraFovAndDistanceFixMultiplier(vertexPositionInput.positionVS.z);
  58. float3 positionWS = vertexPositionInput.positionWS;
  59. positionWS += vertexNormalInput.normalWS * width;
  60. output.positionCS = TransformWorldToHClip(positionWS);
  61. output.uv = TRANSFORM_TEX(input.uv, _BaseMap); // 加偏移
  62. output.fogFactor = ComputeFogFactor(vertexPositionInput.positionCS.z);
  63. return output;
  64. }
  65. float4 frag(Varyings input) : SV_TARGET
  66. {
  67. //描边加颜色,用的采样出来的Ramp
  68. float3 coolRamp = 0;
  69. float warmRamp = 0;
  70. #if _AREA_HAIR
  71. float2 outlineUV = float2(0, 0.5);
  72. coolRamp = tex2D(_HairCoolRamp, outlineUV).rgb;
  73. warmRamp = tex2D(_HairWarmRamp, outlineUV).rgb;
  74. #elif _AREA_UPPERBODY || _AREA_LOWERBODY
  75. float4 lightMap = 0;
  76. #if _AREA_UPPERBODY
  77. lightMap = tex2D(_UpperBodyLightMap, input.uv);
  78. #elif _AREA_LOWERBODY
  79. lightMap = tex2D(_LowerBodyLightMap, input.uv);
  80. #endif
  81. float materialEnum = lightMap.a;
  82. float materialEnumOffset = materialEnum + 0.0425;
  83. float outlineUVy = lerp(materialEnumOffset, materialEnumOffset + 0.5 > 1 ? materialEnumOffset + 0.5 - 1 : materialEnumOffset + 0.5 , fmod((round(materialEnumOffset/0.0625) - 1)/2, 2));
  84. float2 outlineUV = float2(0, outlineUVy);
  85. coolRamp = tex2D(_BodyCoolRamp, outlineUV).rgb;
  86. warmRamp = tex2D(_BodyWarmRamp, outlineUV).rgb;
  87. #elif _AREA_FACE
  88. float2 outlineUV = float2(0, 0.0625);
  89. coolRamp = tex2D(_BodyCoolRamp, outlineUV).rgb;
  90. warmRamp = tex2D(_BodyWarmRamp, outlineUV).rgb;
  91. #endif
  92. float3 ramp = lerp(coolRamp, warmRamp, 0.5);
  93. float3 albedo = pow(saturate(ramp), _OutlineGamma);
  94. float4 color = float4(albedo,1);
  95. color.rgb = MixFog(color.rgb, input.fogFactor);
  96. return color;
  97. }

SRUniversalDrawCorePass

  1. #ifndef _SR_UNIVERSAL_DRAW_CORE_PASS_INCLUDED
  2. #define _SR_UNIVERSAL_DRAW_CORE_PASS_INCLUDED
  3. struct Attributes
  4. {
  5. float3 positionOS : POSITION;
  6. half3 normalOS : NORMAL;
  7. half4 tangentOS : TANGENT;
  8. float2 uv : TEXCOORD0;
  9. };
  10. struct Varyings
  11. {
  12. float2 uv : TEXCOORD0;
  13. float4 positionWSAndFogFactor : TEXCOORD1; // xyz:positionWS, W:vertex fog factor
  14. float3 normalWS : TEXCOORD2;
  15. float3 viewDirectionWS : TEXCOORD3;
  16. float3 SH : TEXCOORD4;
  17. float4 positionCS : SV_POSITION;
  18. };
  19. //去饱和方法
  20. float3 desaturation(float3 colorIn)
  21. {
  22. float3 grayXfer = float3(0.3, 0.59, 0.11); // 心理学灰度因子
  23. float grayf = dot(colorIn, grayXfer);
  24. return float3(grayf, grayf, grayf);
  25. }
  26. struct Gradient
  27. {
  28. int colorsLength;
  29. float4 colors[8];
  30. };
  31. //梯度颜色
  32. Gradient GradientConstruct()
  33. {
  34. Gradient g;
  35. g.colorsLength = 2;
  36. g.colors[0] = float4(1,1,1,0);
  37. g.colors[1] = float4(1,1,1,1);
  38. g.colors[2] = float4(0,0,0,0);
  39. g.colors[3] = float4(0,0,0,0);
  40. g.colors[4] = float4(0,0,0,0);
  41. g.colors[5] = float4(0,0,0,0);
  42. g.colors[6] = float4(0,0,0,0);
  43. g.colors[7] = float4(0,0,0,0);
  44. return g;
  45. }
  46. //渐变采样方法
  47. float3 SampleGradient(Gradient Gradient, float Time)
  48. {
  49. float3 tempColor = Gradient.colors[0].rgb;
  50. for (int c = 1; c < Gradient.colorsLength; c++)
  51. {
  52. float colorPos = saturate((Time - Gradient.colors[c - 1].w) / (Gradient.colors[c].w - Gradient.colors[c - 1].w)) * step(c, Gradient.colorsLength - 1);
  53. tempColor = lerp(tempColor, Gradient.colors[c].rgb, colorPos);
  54. }
  55. #ifdef UNITY_COLORSPACE_GAMMA
  56. tempColor = LinearToSRGB(tempColor);
  57. #endif
  58. return tempColor;
  59. }
  60. Varyings vert(Attributes input)
  61. {
  62. Varyings output = (Varyings)0;
  63. //VertexPositionInputs和VertexNormalInputs两个结构体定义在Core.hlsl中,
  64. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS);
  65. VertexNormalInputs vertexNormalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
  66. /*
  67. 这两个方法在ShaderVariablesFunctions文件中,用于获取VertexPositionInputs和VertexNormalInputs,它们包括大部分需求的信息
  68. struct VertexPositionInputs
  69. {
  70. float3 positionWS; // World space position
  71. float3 positionVS; // View space position
  72. float4 positionCS; // Homogeneous clip space position
  73. {
  74. input.positionCS.x:通常表示屏幕上的水平位置。其范围通常从0(屏幕的左边缘)到屏幕宽度减1(屏幕的右边缘,以像素为单位)。
  75. input.positionCS.y:通常表示屏幕上的垂直位置。其范围通常从0(屏幕的顶部)到屏幕高度减1(屏幕的底部,以像素为单位)。
  76. input.positionCS.z:通常表示片段在深度缓冲区中的深度值。其范围通常在0.01.0之间,表示从近裁剪平面到远裁剪平面的深度值。
  77. input.positionCS.w:通常表示屏幕空间中的透视除法系数。在一般情况下,你不太会直接使用它来进行计算。
  78. }
  79. float4 positionNDC;// Homogeneous normalized device coordinates
  80. {
  81. positionNDC.x:通常表示裁剪坐标系中的X坐标,其范围从-1表示裁剪体积的左侧边界,到1表示裁剪体积的右侧边界。
  82. positionNDC.y:通常表示裁剪坐标系中的Y坐标,其范围从-1表示裁剪体积的底部边界,到1表示裁剪体积的顶部边界。
  83. positionNDC.z:通常表示裁剪坐标系中的Z坐标,其范围从-1表示裁剪体积的近裁剪平面,到1表示裁剪体积的远裁剪平面。
  84. positionNDC.w:通常用于执行透视除法,将坐标从裁剪坐标系转换为标准化设备坐标系。它在顶点着色器中通常为非零值,但在片段着色器中可能会变为零,因为透视除法是在顶点着色器中执行的。
  85. }
  86. };
  87. struct VertexNormalInputs
  88. {
  89. real3 tangentWS;
  90. real3 bitangentWS;
  91. float3 normalWS;
  92. };
  93. */
  94. output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
  95. /*
  96. TRANSFORM_TEX这个宏定义在Macros.hlsl文件中,这个文件中还有还能多定义比如PI:3.1415926、LOG2_E:1.442695
  97. #define TRANSFORM_TEX(tex, name) ((tex.xy) * name##_ST.xy + name##_ST.zw) 看起来不过是添加ST控制,不需要的话不做这个操作也可以,比如这里,_BaseMap不过是个白图
  98. */
  99. output.positionWSAndFogFactor = float4(vertexInput.positionWS, ComputeFogFactor(vertexInput.positionCS.z)); // 做个组合w分量利用一下,省一点空间
  100. output.normalWS = vertexNormalInput.normalWS;
  101. output.viewDirectionWS = unity_OrthoParams.w == 0 ? GetCameraPositionWS() - vertexInput.positionWS : GetWorldToViewMatrix()[2].xyz;
  102. /*
  103. 如果不是ortho,直接坐标相减计算视角向量,如果是ortho,GetWorldToViewMatrix返回的是float4x4 UNITY_MATRIX_V,
  104. unity_OrthoParams这个量来自StdLib.hlsl文件,这里面也有关于PI的定义,看起来很多量都可以从这里拿
  105. float4x4 unity_CameraProjection;
  106. float4x4 unity_MatrixVP;
  107. float4x4 unity_ObjectToWorld;
  108. float4x4 unity_WorldToCamera;
  109. float3 _WorldSpaceCameraPos;
  110. float4 _ProjectionParams; // x: 1 (-1 flipped), y: near, z: far, w: 1/far
  111. float4 unity_ColorSpaceLuminance;
  112. float4 unity_DeltaTime; // x: dt, y: 1/dt, z: smoothDt, w: 1/smoothDt
  113. float4 unity_OrthoParams; // x: width, y: height, z: unused, w: ortho ? 1 : 0
  114. 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 这里看来是后者
  115. float4 _ScreenParams; // x: width, y: height, z: 1+1/width, w: 1+1/height
  116. float4 _Time; // x: t/20, y: t, z: t*2, w: t*3
  117. float4 _SinTime; // x: sin(t/20), y: sin(t), z: sin(t*2), w: sin(t*3)
  118. float4 _CosTime; // x: cos(t/20), y: cos(t), z: cos(t*2), w: cos(t*3)
  119. 还有一些方法GradientNoise、LinearEyeDepth。也定义了TRANSFORM_TEX,不止一个地方定义过这个呢
  120. */
  121. output.SH = SampleSH(lerp(vertexNormalInput.normalWS, float3(0,0,0), _IndirectLightFlattenNormal)); // 球谐函数,就是传入法线返回unity保存好的漫反射数据中对应位置的颜色,这里加了参数控制,因为卡渲有时不需要太多细节
  122. /*
  123. half3 SampleSH(half3 normalWS)
  124. {
  125. // LPPV is not supported in Ligthweight Pipeline
  126. real4 SHCoefficients[7];
  127. SHCoefficients[0] = unity_SHAr;
  128. SHCoefficients[1] = unity_SHAg;
  129. SHCoefficients[2] = unity_SHAb;
  130. SHCoefficients[3] = unity_SHBr;
  131. SHCoefficients[4] = unity_SHBg;
  132. SHCoefficients[5] = unity_SHBb;
  133. SHCoefficients[6] = unity_SHC;
  134. return max(half3(0, 0, 0), SampleSH9(SHCoefficients, normalWS));
  135. }
  136. */
  137. output.positionCS = vertexInput.positionCS;
  138. return output;
  139. }
  140. float4 frag(Varyings input, bool isFrontFace : SV_IsFrontFace): SV_TARGET
  141. {
  142. float3 positionWS = input.positionWSAndFogFactor.xyz;
  143. float4 shadowCoord = TransformWorldToShadowCoord(positionWS);
  144. Light mainLight = GetMainLight(shadowCoord);
  145. float3 lightDirectionWS = normalize(mainLight.direction);
  146. float3 normalWS = normalize(input.normalWS);
  147. float3 viewDirectionWS = normalize(input.viewDirectionWS);
  148. float3 baseColor = tex2D(_BaseMap, input.uv); // baseColor是纯白画布
  149. float4 areaMap = 0;
  150. #if _AREA_FACE
  151. areaMap = tex2D(_FaceColorMap, input.uv);
  152. #elif _AREA_HAIR
  153. areaMap = tex2D(_HairColorMap, input.uv);
  154. #elif _AREA_UPPERBODY
  155. areaMap = tex2D(_UpperBodyColorMap, input.uv);
  156. #elif _AREA_LOWERBODY
  157. areaMap = tex2D(_LowerBodyColorMap, input.uv);
  158. #endif
  159. baseColor = areaMap.rgb;
  160. //baseColor *= lerp((1,1,1), (1,1,1), 0.5);
  161. baseColor *= lerp(_BackFaceTintColor, _FrontFaceTintColor, isFrontFace);
  162. float4 lightMap = 0;
  163. #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
  164. {
  165. #if _AREA_HAIR
  166. lightMap = tex2D(_HairLightMap, input.uv);
  167. #elif _AREA_UPPERBODY
  168. lightMap = tex2D(_UpperBodyLightMap, input.uv);
  169. #elif _AREA_LOWERBODY
  170. lightMap = tex2D(_LowerBodyLightMap, input.uv);
  171. #endif
  172. }
  173. #endif
  174. float4 faceMap = 0;
  175. #if _AREA_FACE
  176. faceMap = tex2D(_FaceMap, input.uv);
  177. #endif
  178. //-----------------------------------------------------------------------------------------------------------------
  179. //间接光
  180. float3 indirectLightColor = input.SH.rgb * _IndirectLightUsage;
  181. // 添加光照图细节
  182. #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
  183. indirectLightColor *= lerp(1, lightMap.r, _IndirectLightOcclusionUsage);
  184. #elif _AREA_FACE
  185. indirectLightColor *= lerp(1, lerp(faceMap.g, 1, step(faceMap.r, 0.01)), _IndirectLightOcclusionUsage);
  186. /*
  187. 注意,step是后面值小于前面值,返回0,反之返回1,别想反了
  188. step(faceMap.r, 0.01)分出来是否受距离影响的区域 根据图片,不受距离影响的区域即r通道有值的部分:为嘴巴,眼睛,眉毛等。值为0,反之受影响的为1
  189. 即lerp(faceMap.g, 1, step(faceMap.r, 0.01))不受距离影响地方r通道有值的部分:用的是faceMap.g的值,受距离影响的r通道没有值的部分是1,也就是正常漫反射光
  190. 但是g通道有一部分本身即是1,那么根据rg通道的差异,得出的r通道覆盖的区域减去g通道覆盖的区域,也就是只有口部分是0其他部分全为1,这里做这么多只是为了筛选出口部分
  191. */
  192. #endif
  193. indirectLightColor *= lerp(1, baseColor, _IndirectLightMixBaseColor);
  194. //-----------------------------------------------------------------------------------------------------------------
  195. //主光
  196. float mainLightShadow = 1;
  197. float3 mainLightColor = lerp(desaturation(mainLight.color), mainLight.color, _MainLightColorUsage); // 这里做了降饱和插值提升效果,不然直接=mainLight.color;就行
  198. #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
  199. {
  200. float NoL = dot(normalWS, lightDirectionWS); // 计算法相和主光向量的dot [-1, 1]
  201. float remapNoL = NoL * 0.5 + 0.5; // [0, 1]
  202. mainLightShadow = smoothstep(1 - lightMap.g + _ShadowThresholdCenter - _ShadowThresholdSoftness, 1 - lightMap.g + _ShadowThresholdCenter + _ShadowThresholdSoftness, remapNoL); // 二值化朗伯特
  203. // 在光照图的g通道,有很多衣服上阴影的细节,接下来添加上去
  204. mainLightShadow *= lightMap.r;
  205. // 光照图的r通道,用于标识一些点不亮的也就是所谓的AO区域,直接乘上去,头发上的蝴蝶结就是点不亮的标识区域
  206. }
  207. #elif _AREA_FACE
  208. {
  209. float3 headForward = normalize(_HeadForward);
  210. float3 headRight = normalize(_HeadRight);
  211. float3 headUp = cross(headForward, headRight);
  212. float3 fixedLightDirectionWS = normalize(lightDirectionWS - dot(lightDirectionWS, headUp) * headUp); // 看起来是投影,把主光源的光照方向投影在垂直于headUp的平面上
  213. /*
  214. 投影到垂直于headUp的平面上,ws-up*(|ws.y|/|up|)
  215. 因为ws为单位向量,所以|ws.y| = cosθ、|up| = 1
  216. 所以简化为ws-up*cosθ。而cosθ= dot(lightDirectionWS, headUp)
  217. 故求出投影到垂直于headUp的平面上的向量
  218. */
  219. float2 sdfUV = float2(sign(dot(fixedLightDirectionWS, headRight)), 1) * float2(-1, 1) * input.uv; // 判断光照在左脸(负)还是右脸(正) float2(-1, 1)是因为sdf图应该左白右黑,所以反向
  220. /*
  221. float2(sign(dot(fixedLightDirectionWS, headRight)), 1)如果光照方向是右半就是float2(1,1),反之float2(-1,1)。只需要处理x是1还是-1,因为按照脸部中心对称
  222. 但是这张图是左右反过来的,所以我们再反一次* float2(-1, 1),最后* input.uv。算出脸部修正uv
  223. 但是在光和headRight夹角为90时,也就是光从正后方打来时,看cos曲线为0,由于sign的特性(-1,0,1),也就是说sdfUV的x永远为0
  224. */
  225. float sdfValue = tex2D(_FaceMap, sdfUV).a; // 如果是光和headRight夹角为90时,看那张图的a通道,采样的都是最左边白色,都是1,所以即使阈值是1也没办法奈何他
  226. // 然后用这个脸部修正uv采样sdf图获取sdf值
  227. float sdfThreshold = 1 - (dot(fixedLightDirectionWS, headForward) * 0.5 + 0.5); //主光越接近正面,阈值越接近0,阈值越低表示越容易被点亮 [0,1]
  228. sdfThreshold += _FaceShadowOffset; // 所以为了限制光和headRight夹角为90时sdfUV的x永远为0,采样的都是最左边白色,都是1的情况,把阈值做个小小的偏移,加上一点点0.01就好,只要超过1就行
  229. float sdf = smoothstep(sdfThreshold - _FaceShadowTransitionSoftness, sdfThreshold + _FaceShadowTransitionSoftness, sdfValue);
  230. mainLightShadow = lerp(faceMap.g, sdf, step(faceMap.r, 0.01)); // sdf不应该影响ao区域,
  231. }
  232. #endif
  233. //-----------------------------------------------------------------------------------------------------------------
  234. //Ramp
  235. //计算uv
  236. float2 rampUV;
  237. int rampRowIndex = 0;
  238. int rampRowNum = 1;
  239. #if _AREA_HAIR
  240. {
  241. rampRowIndex = 0;
  242. rampRowNum = 1;
  243. }
  244. #elif _AREA_UPPERBODY || _AREA_LOWERBODY
  245. {
  246. int rawIndex = (round((lightMap.a + 0.0425)/0.0625) - 1)/2;
  247. rampRowIndex = lerp(rawIndex, rawIndex + 4 < 8 ? rawIndex + 4 : rawIndex + 4 - 8, fmod(rawIndex, 2));
  248. rampRowNum = 8;
  249. }
  250. #elif _AREA_FACE
  251. {
  252. rampRowIndex = 0;
  253. rampRowNum = 8;
  254. }
  255. #endif
  256. // 使用预规定的方式计算行数,用于计算采样uv的y坐标,x坐标使用阴影值
  257. float rampUVy = (2 * rampRowIndex + 1) * (1.0 / (rampRowNum * 2));
  258. float rampUVx = mainLightShadow * (1 - _ShadowRampOffset) + _ShadowRampOffset; // 做个映射,[0.75,1]这张图在0.85左右往后就是白色,我感觉不映射直接用mainLightShadow效果差异也不大
  259. rampUV = float2(rampUVx, rampUVy);
  260. //采样
  261. float3 rampColor;
  262. float3 coolRamp = 1;
  263. float3 warmRamp = 1;
  264. #if _AREA_HAIR
  265. {
  266. coolRamp = tex2D(_HairCoolRamp, rampUV).rgb;
  267. warmRamp = tex2D(_HairWarmRamp, rampUV).rgb;
  268. }
  269. #elif _AREA_FACE || _AREA_UPPERBODY || _AREA_LOWERBODY
  270. {
  271. coolRamp = tex2D(_BodyCoolRamp, rampUV).rgb;
  272. warmRamp = tex2D(_BodyWarmRamp, rampUV).rgb;
  273. }
  274. #endif
  275. //根据白天夜晚插值冷暖色
  276. float isDay = lightDirectionWS.y * 0.5 + 0.5;
  277. rampColor = lerp(coolRamp, warmRamp, 1);
  278. //-----------------------------------------------------------------------------------------------------------------
  279. //修补主光源
  280. float3 fixedMainLightColor = mainLightColor * baseColor * rampColor;
  281. //-----------------------------------------------------------------------------------------------------------------
  282. //高光
  283. float3 specularColor = 0;
  284. #if _AREA_HAIR || _AREA_UPPERBODY || _AREA_LOWERBODY
  285. {
  286. //布林冯,但是直接这样看起来太光滑
  287. float3 halfVectorWS = normalize(viewDirectionWS + lightDirectionWS);
  288. float NoH = dot(normalWS, halfVectorWS);
  289. float blinnPhong = pow(saturate(NoH), _SpecularExpon);
  290. //用光照图的蓝色通道作为阈值,超过阈值才会产生高光 这里金属和非金属分别处理
  291. //非金属 反射率Ks,固定0.04
  292. float nonMetalSpecular = step(1.0 - blinnPhong, lightMap.b) * _SpecularKsNonMetal;
  293. //金属 反射率都比较大且差异较大,蓝色通道控制各个金属部分差异
  294. float metalSpecular = blinnPhong * lightMap.b * _SpecularKsMetal;
  295. //得有一个lerp控制什么时候是金属什么时候是非金属,在光照图的阿尔法通道,0.52灰度值表示金属
  296. //找出金属部分,metallic越接近于0就越靠近金属
  297. float metallic = 0;
  298. #if _AREA_UPPERBODY || _AREA_LOWERBODY
  299. {
  300. metallic = saturate( (1 - 10 * abs(lightMap.a - 0.52)) ); // 金属影响系数,暂定10
  301. }
  302. #endif
  303. specularColor = lerp(nonMetalSpecular, metalSpecular * baseColor, metallic);
  304. specularColor *= mainLight.color;
  305. specularColor *= _SpecularBrightness;
  306. }
  307. #endif
  308. //-----------------------------------------------------------------------------------------------------------------
  309. //黑丝
  310. float3 stockingsEffect = 1;
  311. #if _AREA_UPPERBODY || _AREA_LOWERBODY
  312. {
  313. //红通道是遮罩,绿通道是丝的透光度,蓝通道是丝的细节,uv放大一定倍数采样可以提升细节量
  314. //采样
  315. float2 stockingsMapRG = 0;
  316. float stockingsMapB = 0;
  317. #if _AREA_UPPERBODY
  318. {
  319. stockingsMapRG = tex2D(_UpperBodyStockings, input.uv).rg;
  320. stockingsMapB = tex2D(_UpperBodyStockings, input.uv * 20).b;
  321. }
  322. #elif _AREA_LOWERBODY
  323. {
  324. stockingsMapRG = tex2D(_LowerBodyStockings, input.uv).rg;
  325. stockingsMapB = tex2D(_LowerBodyStockings, input.uv * 20).b;
  326. }
  327. #endif
  328. //混入细节
  329. float NoV = dot(normalWS, viewDirectionWS);
  330. //都不过是为了加控制
  331. float fac = pow(saturate(NoV), _StockingsTransitionPower);;
  332. fac = saturate( (fac - _StockingsTransitionHardness/2) / (1 - _StockingsTransitionHardness) );
  333. fac = fac * (stockingsMapB * _StockingsTextureUsage + (1 - _StockingsTextureUsage));
  334. fac = lerp(fac, 1, stockingsMapRG.g);
  335. //构造颜色曲线
  336. Gradient curve = GradientConstruct();
  337. curve.colorsLength = 3;
  338. curve.colors[0] = float4(_StockingsDarkColor, 0);
  339. curve.colors[1] = float4(_StockingsTransitionColor, _StockingsTransitionThreshold);
  340. curve.colors[2] = float4(_StockingsLightColor, 1);
  341. //采样渐变
  342. float3 stockingsColor = SampleGradient(curve, fac);
  343. //加遮罩
  344. stockingsEffect = lerp(1, stockingsColor, stockingsMapRG.r);
  345. }
  346. #endif
  347. //-----------------------------------------------------------------------------------------------------------------
  348. //鼻尖的描边
  349. float fakeOutlineEffect = 0;
  350. float3 fakeOutlineColor = 0;
  351. #if _AREA_FACE && _OUTLINE_ON
  352. {
  353. float4 faceMap = tex2D(_FaceMap, input.uv);
  354. float fakeOutline = faceMap.b;
  355. float3 headForward = normalize(_HeadForward);
  356. fakeOutlineEffect = smoothstep(0.0, 0.25, pow(saturate(dot(headForward, viewDirectionWS)), 20) * fakeOutline);
  357. float2 outlineUV = float2(0, 0.0625);
  358. float3 coolRamp = tex2D(_BodyCoolRamp, outlineUV).rgb;
  359. float3 warmRamp = tex2D(_BodyWarmRamp, outlineUV).rgb;
  360. float3 ramp = lerp(coolRamp, warmRamp, 0.5);
  361. fakeOutlineColor = pow(ramp, _OutlineGamma);
  362. }
  363. #endif
  364. //-----------------------------------------------------------------------------------------------------------------
  365. //边缘光 打开URP深度图
  366. float linearEyeDepth = LinearEyeDepth(input.positionCS.z, _ZBufferParams) / 10; // 离相机越近就越黑 正确
  367. float3 normalVS = mul((float3x3)UNITY_MATRIX_V, normalWS); // 正确
  368. float2 uvOffset = float2(sign(normalVS.x), 0) * _RimLightWidth / (1 + linearEyeDepth); // 正确
  369. int2 loadTexPos = input.positionCS.xy + uvOffset * _ScaledScreenParams.xy; // 正确
  370. float offsetSceneDepth = LoadSceneDepth(loadTexPos) * 5;
  371. float offsetLinearEyeDepth = LinearEyeDepth(offsetSceneDepth, _ZBufferParams);
  372. float rimLight = saturate(offsetLinearEyeDepth - (linearEyeDepth + _RimLightThreshold)) / _RimLightFadeout;
  373. //这里模型的深度图因材质问题搞不定,放置了,之后再说吧
  374. //-----------------------------------------------------------------------------------------------------------------
  375. float3 albedo = 0;
  376. albedo += indirectLightColor;
  377. albedo += fixedMainLightColor;
  378. albedo += specularColor;
  379. albedo *= stockingsEffect;
  380. albedo = lerp(albedo, fakeOutlineColor, fakeOutlineEffect);
  381. float alpha = _Alpha;
  382. //albedo = viewDirectionWS.rgb;
  383. float4 finalColor = float4(albedo, alpha);
  384. return finalColor;
  385. }
  386. #endif

 SendVectorToShader脚本

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Unity.Mathematics;
  5. using Unity.VisualScripting;
  6. using UnityEngine;
  7. public class SendVectorToShader : MonoBehaviour
  8. {
  9. public Transform HeadBoneTransform;
  10. public Transform HeadForwardTransform;
  11. public Transform HeadRightTransform;
  12. private Renderer[] allRenderers;
  13. private int HeadForwardID = Shader.PropertyToID("_HeadForward");
  14. private int HeadRightID = Shader.PropertyToID("_HeadRight");
  15. #if UNITY_EDITOR
  16. private void OnValidate()
  17. {
  18. LateUpdate();
  19. }
  20. #endif
  21. private void LateUpdate()
  22. {
  23. if(allRenderers == null)
  24. {
  25. allRenderers = GetComponentsInChildren<Renderer>(true);
  26. }
  27. Renderer tempRenderer;
  28. for (int i = 0; i < allRenderers.Count(); i++)
  29. {
  30. tempRenderer = allRenderers[i];
  31. foreach(Material tempMaterial in tempRenderer.sharedMaterials)
  32. {
  33. if (tempMaterial.shader)
  34. {
  35. if(tempMaterial.shader.name == "Unlit/SRUniversal")
  36. {
  37. tempMaterial.SetVector(HeadForwardID, HeadForwardTransform.position - HeadBoneTransform.position);
  38. tempMaterial.SetVector(HeadRightID, HeadRightTransform.position - HeadBoneTransform.position);
  39. }
  40. }
  41. }
  42. }
  43. }
  44. }

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/907497?site
推荐阅读
相关标签
  

闽ICP备14008679号