Unity URP之通過Feature實現毛皮效果

以下代碼來源於第三方插件。

Feature代碼:

  1 using System.Collections.Generic;
  2 using UnityEngine;
  3 using UnityEngine.Experimental.Rendering.Universal;
  4 using UnityEngine.Rendering;
  5 using UnityEngine.Rendering.Universal;
  6 
  7 //[ExecuteInEditMode]
  8 public class FurRenderFeature : ScriptableRendererFeature
  9 {
 10     [System.Serializable]
 11     public class FilterSettings
 12     {
 13         // TODO: expose opaque, transparent, all ranges as drop down
 14         public RenderQueueType RenderQueueType;
 15         public LayerMask LayerMask = 1;
 16         public string[] PassNames;
 17 
 18         public FilterSettings()
 19         {
 20             RenderQueueType = RenderQueueType.Opaque;
 21             LayerMask =  ~0;
 22             PassNames = new string[] {"FurRendererBase", "FurRendererLayer"};
 23         }
 24     }
 25 
 26     public static FurRenderFeature instance;
 27     
 28     /// <summary>
 29     /// This function is called when the object becomes enable and active.
 30     /// </summary>
 31     ///
 32     [System.Serializable]
 33     public class PassSettings
 34     {
 35         public string passTag = "FurRenderer";
 36         [Header("Settings")]
 37         public bool ShouldRender = true;
 38         [Tooltip("Set Layer Num")]
 39         [Range(1, 200)]public int PassLayerNum = 20;
 40         [Range(1000, 5000)] public int QueueMin = 2000;
 41         [Range(1000, 5000)] public int QueueMax = 5000;
 42         public RenderPassEvent PassEvent = RenderPassEvent.AfterRenderingSkybox;
 43 
 44         public FilterSettings filterSettings = new FilterSettings();
 45     }
 46 
 47     public class FurRenderPass : ScriptableRenderPass
 48     {
 49         string m_ProfilerTag;
 50         RenderQueueType renderQueueType;
 51         private PassSettings settings;
 52         private FurRenderFeature furRenderFeature = null;
 53         public List<ShaderTagId> m_ShaderTagIdList = new List<ShaderTagId>();
 54         private ShaderTagId shadowCasterSTI = new ShaderTagId("ShadowCaster");
 55         private FilteringSettings filter;
 56         public Material overrideMaterial { get; set; }
 57         public int overrideMaterialPassIndex { get; set; }
 58 
 59         public FurRenderPass(PassSettings setting, FurRenderFeature render,FilterSettings filterSettings)
 60         {
 61             m_ProfilerTag = setting.passTag;
 62             string[] shaderTags = filterSettings.PassNames;
 63             this.settings = setting;
 64             this.renderQueueType = filterSettings.RenderQueueType;
 65             furRenderFeature = render;
 66             //過濾設定
 67             RenderQueueRange queue = new RenderQueueRange();
 68             queue.lowerBound = setting.QueueMin;
 69             queue.upperBound = setting.QueueMax;
 70             filter = new FilteringSettings(queue,filterSettings.LayerMask);
 71             if (shaderTags != null && shaderTags.Length > 0)
 72             {
 73                 foreach (var passName in shaderTags)
 74                     m_ShaderTagIdList.Add(new ShaderTagId(passName));
 75             }
 76         }
 77 
 78         // This method is called before executing the render pass.
 79         // It can be used to configure render targets and their clear state. Also to create temporary render target textures.
 80         // When empty this render pass will render to the active camera render target.
 81         // You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
 82         // The render pipeline will ensure target setup and clearing happens in an performance manner.
 83         public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
 84         {
 85         }
 86 
 87         // Here you can implement the rendering logic.
 88         // Use <c>ScriptableRenderContext</c> to issue drawing commands or execute command buffers
 89         // https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html
 90         // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline.
 91         public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
 92         {
 93             SortingCriteria sortingCriteria = (renderQueueType == RenderQueueType.Transparent)
 94                 ? SortingCriteria.CommonTransparent
 95                 : renderingData.cameraData.defaultOpaqueSortFlags;
 96             CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);
 97             //=============================================================
 98             //draw objects(e.g. reflective wet ground plane) with lightmode "MobileSSPRWater", which will sample _MobileSSPR_ColorRT
 99             DrawingSettings baseDrawingSetting, layerDrawingSetting;
100             //BaseLayer DrawingSetting
101             if (m_ShaderTagIdList.Count > 0)
102                 baseDrawingSetting = CreateDrawingSettings(m_ShaderTagIdList[0], ref renderingData,
103                     renderingData.cameraData.defaultOpaqueSortFlags);
104             else return;
105             if(m_ShaderTagIdList.Count > 1)
106             layerDrawingSetting = CreateDrawingSettings(m_ShaderTagIdList[1], ref renderingData,
107                 renderingData.cameraData.defaultOpaqueSortFlags);
108             else return;
109             float inter = 1.0f / settings.PassLayerNum;
110             //BaseLayer
111             cmd.Clear();
112             cmd.SetGlobalFloat("_FUR_OFFSET", 0);
113             context.ExecuteCommandBuffer(cmd);
114             context.DrawRenderers(renderingData.cullResults,ref baseDrawingSetting,ref filter);
115             //TransparentLayer
116             for(int i = 1; i < settings.PassLayerNum; i++)
117             {
118                 cmd.Clear();
119                 cmd.SetGlobalFloat("_FUR_OFFSET", i * inter);
120                 context.ExecuteCommandBuffer(cmd);
121                 context.DrawRenderers(renderingData.cullResults,ref layerDrawingSetting,ref filter);
122             }
123             CommandBufferPool.Release(cmd);
124         }
125 
126         /// Cleanup any allocated resources that were created during the execution of this render pass.
127         public override void FrameCleanup(CommandBuffer cmd)
128         {
129         }
130     }
131     public PassSettings settings = new PassSettings();
132     FurRenderPass m_ScriptablePass;
133 
134     public override void Create()
135     {
136         instance = this;
137         FilterSettings filter = settings.filterSettings;
138         m_ScriptablePass = new FurRenderPass(settings, this, filter);
139         // Configures where the render pass should be injected.
140         m_ScriptablePass.renderPassEvent = settings.PassEvent;
141     }
142 
143     // Here you can inject one or multiple render passes in the renderer.
144     // This method is called when setting up the renderer once per-camera.
145     public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
146     {
147         renderer.EnqueuePass(m_ScriptablePass);
148     }
149 }
View Code

毛皮shader:

  1 Shader "LXShader/Other/MultiPassFurModified"
  2 {
  3     Properties
  4     {
  5        [Header(Macro)]
  6         [Toggle(_TANGENT_TO_WORLD)] _TangentToWorld("Tangent To World", Float) = 0
  7         [Toggle(_GI_ON)] _GI_ON("GIOn", Float) = 0
  8         [Toggle(_RECEIVE_SHADOWS)] _RECEIVE_SHADOWS("Receive Shadow", Float) = 0
  9         [KeywordEnum(On,Off)] _NORMALMAP_URP("Mormal Map", Float) = 0
 10         [Header(Main)]
 11         [MainColor]_Color("Color", Color) = (1,1,1,1)
 12         _MainTex("Albedo", 2D) = "white" {}
 13 
 14         _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5
 15 
 16         _BumpScale("Noramal Scale", Range(0,1)) = 1.0
 17         _BumpMap("Normal Map", 2D) = "bump" {}
 18 
 19         [Enum(UV0,0,UV1,1)] _UVSec("UV Set for secondary textures", Float) = 0
 20 
 21         [Space(20)]
 22         _FabricScatterColor("Fabric Scatter Color", Color) = (1,1,1,1)
 23         _FabricScatterScale("Fabric Scatter Scale", Range(0, 1)) = 0
 24         
 25         [Space(20)]
 26         _LayerTex("Layer", 2D) = "white" {}
 27         _FurLength("Fur Length", Range(.0002, 10)) = .25
 28         _Cutoff("Alpha Cutoff", Range(0,1)) = 0.5 // how "thick"
 29         _CutoffEnd("Alpha Cutoff end", Range(0,1)) = 0.5 // how thick they are at the end
 30         _EdgeFade("Edge Fade", Range(0,1)) = 0.4
 31         _Gravity("Gravity Direction", Vector) = (0,-1,0,0)
 32         _GravityStrength("Gravity Strength", Range(0,1)) = 0.25
 33         _FlowMap("Flow Map", 2D) = "gray"{}
 34         _UVOffset("UVOffset",Range(0,1))=0
 35         [Header(Shadow)]
 36         _ShadowColor("Shadow Color", Color) = (0,0,0,0)
 37         _ShadowLerp("Shadow AO",Range(0,1)) = 1
 38         // Blending state
 39         [Header(Settings)]
 40         _Mode("__mode", Float) = 0.0
 41         [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend Mode", Float) = 5
 42         [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend Mode", Float) = 10
 43         [Toggle]_ZWrite("__zw", Float) = 1.0
 44         [Toggle(_ALPHATEST_ON)]_ALPHATEST_ON("_ALPHATEST_ON",Float) =1
 45     }
 46     SubShader
 47     {
 48         Tags { "RenderType"="Opaque"  "PerformanceChecks" = "False"}
 49 
 50         LOD 100
 51         HLSLINCLUDE
 52         #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 53         #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
 54         #define UNITY_SETUP_BRDF_INPUT MetallicSetup
 55         #define _NORMALMAP_URP 1
 56         #define _FABRIC_URP 1
 57         #define _FUR_URP 1
 58 
 59         sampler2D _LayerTex;
 60         sampler2D   _BumpMap;
 61         sampler2D _FlowMap;
 62         sampler2D _MainTex;
 63         sampler2D   _OcclusionMap;
 64 
 65         CBUFFER_START(UnityPerMaterial)
 66         half _UVOffset;
 67         half3 _FabricScatterColor;
 68         half  _FabricScatterScale;
 69         float4 _MainTex_ST;
 70         float4 _LayerTex_ST;
 71         half _Glossiness;
 72         half _FurLength;
 73         half _GravityStrength;
 74         half4 _Color;
 75         half3 _Gravity;
 76         half _CutoffEnd;
 77         half _EdgeFade;
 78         half        _OcclusionStrength;
 79         half        _Cutoff;
 80         half        _BumpScale;
 81         float _Metallic;
 82 
 83         // //PBR
 84         float3 _Albedo;
 85         
 86         float3 _Specular;
 87         float _Smoothness;
 88         float _Occlusion;
 89         float3 _Emission;
 90         float _Alpha;
 91         float4 _ShadowColor;
 92         half _ShadowLerp;
 93         CBUFFER_END
 94         half _FUR_OFFSET;
 95 
 96         //
 97         ENDHLSL
 98         
 99         Pass
100         {
101            Name "FurRender"
102             Tags{ "LightMode" = "FurRendererBase"}
103             //Blend[_SrcBlend][_DstBlend]
104             ZWrite[_ZWrite]
105             HLSLPROGRAM
106             // make fog work
107             #pragma multi_compile_fog
108             #pragma shader_feature _ _TANGENT_TO_WORLD
109             //#pragma shader_feature _ _PARALLAXMAP
110             #pragma shader_feature _ _GI_ON
111             #pragma multi_compile _ LIGHTMAP_ON
112             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
113             #pragma shader_feature _NORMALMAP
114             #pragma shader_feature _ _RECEIVE_SHADOWS
115             //#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
116             #pragma shader_feature _EMISSION
117             #pragma shader_feature _METALLICGLOSSMAP
118             #pragma shader_feature ___ _DETAIL_MULX2
119             #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
120             #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
121             #pragma shader_feature _ _GLOSSYREFLECTIONS_OFF
122             #pragma shader_feature _NORMALMAP_URP_ON _NORMALMAP_URP_OFF
123             // #define SHADER_TARGET 100
124             
125             #pragma vertex vert_LayerBase
126             #pragma fragment frag_LayerBase
127 
128             #include "FurCoreData.hlsl"
129 
130             ENDHLSL
131         }
132         Pass
133         {
134            Name "FurRender"
135             Tags{ "LightMode" = "FurRendererLayer"}
136             Blend[_SrcBlend][_DstBlend]
137             ZWrite[_ZWrite]
138             HLSLPROGRAM
139             // make fog work
140             #pragma multi_compile_fog
141             #pragma shader_feature _ _TANGENT_TO_WORLD
142             //#pragma shader_feature _ _PARALLAXMAP
143             #pragma shader_feature _ _GI_ON
144             #pragma multi_compile _ LIGHTMAP_ON
145             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
146             #pragma shader_feature _NORMALMAP
147             #pragma shader_feature _ _RECEIVE_SHADOWS
148             //#pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
149             #pragma shader_feature _EMISSION
150             #pragma shader_feature _METALLICGLOSSMAP
151             #pragma shader_feature ___ _DETAIL_MULX2
152             #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
153             #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF
154             #pragma shader_feature _ _GLOSSYREFLECTIONS_OFF
155             #pragma shader_feature _NORMALMAP_URP_ON _NORMALMAP_URP_OFF
156             
157             #pragma vertex vert_LayerBase
158             #pragma fragment frag_LayerBase
159 
160             #include "FurCoreData.hlsl"
161 
162             ENDHLSL
163         }
164         Pass
165         {
166             
167             Name "ShadowCaster"
168             Tags { "LightMode"="ShadowCaster" }
169 
170             ZWrite On
171             ZTest LEqual
172 
173             HLSLPROGRAM
174             #define ASE_SRP_VERSION 70301
175 
176             #pragma prefer_hlslcc gles
177             #pragma exclude_renderers d3d11_9x
178 
179             #pragma vertex vert
180             #pragma fragment frag
181 
182             #define SHADERPASS_SHADOWCASTER
183 
184             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
185             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
186             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
187             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
188 
189             
190 
191             struct VertexInput
192             {
193                 float4 vertex : POSITION;
194                 float3 ase_normal : NORMAL;
195                 
196                 UNITY_VERTEX_INPUT_INSTANCE_ID
197             };
198 
199             struct VertexOutput
200             {
201                 float4 clipPos : SV_POSITION;
202                 #if defined(ASE_NEEDS_FRAG_WORLD_POSITION)
203                 float3 worldPos : TEXCOORD0;
204                 #endif
205                 #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) && defined(ASE_NEEDS_FRAG_SHADOWCOORDS)
206                 float4 shadowCoord : TEXCOORD1;
207                 #endif
208                 
209                 UNITY_VERTEX_INPUT_INSTANCE_ID
210                 UNITY_VERTEX_OUTPUT_STEREO
211             };
212 
213             CBUFFER_START(UnityPerMaterial)
214                         #ifdef _TRANSMISSION_ASE
215                 float _TransmissionShadow;
216             #endif
217             #ifdef _TRANSLUCENCY_ASE
218                 float _TransStrength;
219                 float _TransNormal;
220                 float _TransScattering;
221                 float _TransDirect;
222                 float _TransAmbient;
223                 float _TransShadow;
224             #endif
225             #ifdef TESSELLATION_ON
226                 float _TessPhongStrength;
227                 float _TessValue;
228                 float _TessMin;
229                 float _TessMax;
230                 float _TessEdgeLength;
231                 float _TessMaxDisp;
232             #endif
233             CBUFFER_END
234             
235 
236             
237             float3 _LightDirection;
238 
239             VertexOutput VertexFunction( VertexInput v )
240             {
241                 VertexOutput o;
242                 UNITY_SETUP_INSTANCE_ID(v);
243                 UNITY_TRANSFER_INSTANCE_ID(v, o);
244                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( o );
245 
246                 
247                 #ifdef ASE_ABSOLUTE_VERTEX_POS
248                     float3 defaultVertexValue = v.vertex.xyz;
249                 #else
250                     float3 defaultVertexValue = float3(0, 0, 0);
251                 #endif
252                 float3 vertexValue = defaultVertexValue;
253                 #ifdef ASE_ABSOLUTE_VERTEX_POS
254                     v.vertex.xyz = vertexValue;
255                 #else
256                     v.vertex.xyz += vertexValue;
257                 #endif
258 
259                 v.ase_normal = v.ase_normal;
260 
261                 float3 positionWS = TransformObjectToWorld( v.vertex.xyz );
262                 #if defined(ASE_NEEDS_FRAG_WORLD_POSITION)
263                 o.worldPos = positionWS;
264                 #endif
265                 float3 normalWS = TransformObjectToWorldDir(v.ase_normal);
266 
267                 float4 clipPos = TransformWorldToHClip( ApplyShadowBias( positionWS, normalWS, _LightDirection ) );
268 
269                 #if UNITY_REVERSED_Z
270                     clipPos.z = min(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
271                 #else
272                     clipPos.z = max(clipPos.z, clipPos.w * UNITY_NEAR_CLIP_VALUE);
273                 #endif
274                 #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) && defined(ASE_NEEDS_FRAG_SHADOWCOORDS)
275                     VertexPositionInputs vertexInput = (VertexPositionInputs)0;
276                     vertexInput.positionWS = positionWS;
277                     vertexInput.positionCS = clipPos;
278                     o.shadowCoord = GetShadowCoord( vertexInput );
279                 #endif
280                 o.clipPos = clipPos;
281                 return o;
282             }
283 
284             #if defined(TESSELLATION_ON)
285             struct VertexControl
286             {
287                 float4 vertex : INTERNALTESSPOS;
288                 float3 ase_normal : NORMAL;
289                 
290                 UNITY_VERTEX_INPUT_INSTANCE_ID
291             };
292 
293             struct TessellationFactors
294             {
295                 float edge[3] : SV_TessFactor;
296                 float inside : SV_InsideTessFactor;
297             };
298 
299             VertexControl vert ( VertexInput v )
300             {
301                 VertexControl o;
302                 UNITY_SETUP_INSTANCE_ID(v);
303                 UNITY_TRANSFER_INSTANCE_ID(v, o);
304                 o.vertex = v.vertex;
305                 o.ase_normal = v.ase_normal;
306                 
307                 return o;
308             }
309 
310             TessellationFactors TessellationFunction (InputPatch<VertexControl,3> v)
311             {
312                 TessellationFactors o;
313                 float4 tf = 1;
314                 float tessValue = _TessValue; float tessMin = _TessMin; float tessMax = _TessMax;
315                 float edgeLength = _TessEdgeLength; float tessMaxDisp = _TessMaxDisp;
316                 #if defined(ASE_FIXED_TESSELLATION)
317                 tf = FixedTess( tessValue );
318                 #elif defined(ASE_DISTANCE_TESSELLATION)
319                 tf = DistanceBasedTess(v[0].vertex, v[1].vertex, v[2].vertex, tessValue, tessMin, tessMax, GetObjectToWorldMatrix(), _WorldSpaceCameraPos );
320                 #elif defined(ASE_LENGTH_TESSELLATION)
321                 tf = EdgeLengthBasedTess(v[0].vertex, v[1].vertex, v[2].vertex, edgeLength, GetObjectToWorldMatrix(), _WorldSpaceCameraPos, _ScreenParams );
322                 #elif defined(ASE_LENGTH_CULL_TESSELLATION)
323                 tf = EdgeLengthBasedTessCull(v[0].vertex, v[1].vertex, v[2].vertex, edgeLength, tessMaxDisp, GetObjectToWorldMatrix(), _WorldSpaceCameraPos, _ScreenParams, unity_CameraWorldClipPlanes );
324                 #endif
325                 o.edge[0] = tf.x; o.edge[1] = tf.y; o.edge[2] = tf.z; o.inside = tf.w;
326                 return o;
327             }
328 
329             [domain("tri")]
330             [partitioning("fractional_odd")]
331             [outputtopology("triangle_cw")]
332             [patchconstantfunc("TessellationFunction")]
333             [outputcontrolpoints(3)]
334             VertexControl HullFunction(InputPatch<VertexControl, 3> patch, uint id : SV_OutputControlPointID)
335             {
336                return patch[id];
337             }
338 
339             [domain("tri")]
340             VertexOutput DomainFunction(TessellationFactors factors, OutputPatch<VertexControl, 3> patch, float3 bary : SV_DomainLocation)
341             {
342                 VertexInput o = (VertexInput) 0;
343                 o.vertex = patch[0].vertex * bary.x + patch[1].vertex * bary.y + patch[2].vertex * bary.z;
344                 o.ase_normal = patch[0].ase_normal * bary.x + patch[1].ase_normal * bary.y + patch[2].ase_normal * bary.z;
345                 
346                 #if defined(ASE_PHONG_TESSELLATION)
347                 float3 pp[3];
348                 for (int i = 0; i < 3; ++i)
349                     pp[i] = o.vertex.xyz - patch[i].ase_normal * (dot(o.vertex.xyz, patch[i].ase_normal) - dot(patch[i].vertex.xyz, patch[i].ase_normal));
350                 float phongStrength = _TessPhongStrength;
351                 o.vertex.xyz = phongStrength * (pp[0]*bary.x + pp[1]*bary.y + pp[2]*bary.z) + (1.0f-phongStrength) * o.vertex.xyz;
352                 #endif
353                 UNITY_TRANSFER_INSTANCE_ID(patch[0], o);
354                 return VertexFunction(o);
355             }
356             #else
357             VertexOutput vert ( VertexInput v )
358             {
359                 return VertexFunction( v );
360             }
361             #endif
362 
363             half4 frag(VertexOutput IN  ) : SV_TARGET
364             {
365                 UNITY_SETUP_INSTANCE_ID( IN );
366                 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX( IN );
367                 
368                 #if defined(ASE_NEEDS_FRAG_WORLD_POSITION)
369                 float3 WorldPosition = IN.worldPos;
370                 #endif
371                 float4 ShadowCoords = float4( 0, 0, 0, 0 );
372 
373                 #if defined(ASE_NEEDS_FRAG_SHADOWCOORDS)
374                     #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
375                         ShadowCoords = IN.shadowCoord;
376                     #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
377                         ShadowCoords = TransformWorldToShadowCoord( WorldPosition );
378                     #endif
379                 #endif
380 
381                 
382                 float Alpha = 1;
383                 float AlphaClipThreshold = 0.5;
384 
385                 #ifdef _ALPHATEST_ON
386                     clip(Alpha - AlphaClipThreshold);
387                 #endif
388 
389                 #ifdef LOD_FADE_CROSSFADE
390                     LODDitheringTransition( IN.clipPos.xyz, unity_LODFade.x );
391                 #endif
392                 return 0;
393             }
394 
395             ENDHLSL
396         }    
397         Pass
398         {
399             
400             Name "DepthOnly"
401             Tags { "LightMode"="DepthOnly" }
402 
403             ZWrite On
404             ColorMask 0
405 
406             HLSLPROGRAM
407             #define ASE_SRP_VERSION 70301
408 
409             #pragma prefer_hlslcc gles
410             #pragma exclude_renderers d3d11_9x
411 
412             #pragma vertex vert
413             #pragma fragment frag
414 
415             #define SHADERPASS_DEPTHONLY
416 
417             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
418             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
419             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
420             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
421 
422             
423 
424             struct VertexInput
425             {
426                 float4 vertex : POSITION;
427                 float3 ase_normal : NORMAL;
428                 
429                 UNITY_VERTEX_INPUT_INSTANCE_ID
430             };
431 
432             struct VertexOutput
433             {
434                 float4 clipPos : SV_POSITION;
435                 #if defined(ASE_NEEDS_FRAG_WORLD_POSITION)
436                 float3 worldPos : TEXCOORD0;
437                 #endif
438                 #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) && defined(ASE_NEEDS_FRAG_SHADOWCOORDS)
439                 float4 shadowCoord : TEXCOORD1;
440                 #endif
441                 
442                 UNITY_VERTEX_INPUT_INSTANCE_ID
443                 UNITY_VERTEX_OUTPUT_STEREO
444             };
445 
446             CBUFFER_START(UnityPerMaterial)
447                         #ifdef _TRANSMISSION_ASE
448                 float _TransmissionShadow;
449             #endif
450             #ifdef _TRANSLUCENCY_ASE
451                 float _TransStrength;
452                 float _TransNormal;
453                 float _TransScattering;
454                 float _TransDirect;
455                 float _TransAmbient;
456                 float _TransShadow;
457             #endif
458             #ifdef TESSELLATION_ON
459                 float _TessPhongStrength;
460                 float _TessValue;
461                 float _TessMin;
462                 float _TessMax;
463                 float _TessEdgeLength;
464                 float _TessMaxDisp;
465             #endif
466             CBUFFER_END
467             
468 
469             
470             VertexOutput VertexFunction( VertexInput v  )
471             {
472                 VertexOutput o = (VertexOutput)0;
473                 UNITY_SETUP_INSTANCE_ID(v);
474                 UNITY_TRANSFER_INSTANCE_ID(v, o);
475                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
476 
477                 
478                 #ifdef ASE_ABSOLUTE_VERTEX_POS
479                     float3 defaultVertexValue = v.vertex.xyz;
480                 #else
481                     float3 defaultVertexValue = float3(0, 0, 0);
482                 #endif
483                 float3 vertexValue = defaultVertexValue;
484                 #ifdef ASE_ABSOLUTE_VERTEX_POS
485                     v.vertex.xyz = vertexValue;
486                 #else
487                     v.vertex.xyz += vertexValue;
488                 #endif
489 
490                 v.ase_normal = v.ase_normal;
491                 float3 positionWS = TransformObjectToWorld( v.vertex.xyz );
492                 float4 positionCS = TransformWorldToHClip( positionWS );
493 
494                 #if defined(ASE_NEEDS_FRAG_WORLD_POSITION)
495                 o.worldPos = positionWS;
496                 #endif
497 
498                 #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR) && defined(ASE_NEEDS_FRAG_SHADOWCOORDS)
499                     VertexPositionInputs vertexInput = (VertexPositionInputs)0;
500                     vertexInput.positionWS = positionWS;
501                     vertexInput.positionCS = positionCS;
502                     o.shadowCoord = GetShadowCoord( vertexInput );
503                 #endif
504                 o.clipPos = positionCS;
505                 return o;
506             }
507 
508             #if defined(TESSELLATION_ON)
509             struct VertexControl
510             {
511                 float4 vertex : INTERNALTESSPOS;
512                 float3 ase_normal : NORMAL;
513                 
514                 UNITY_VERTEX_INPUT_INSTANCE_ID
515             };
516 
517             struct TessellationFactors
518             {
519                 float edge[3] : SV_TessFactor;
520                 float inside : SV_InsideTessFactor;
521             };
522 
523             VertexControl vert ( VertexInput v )
524             {
525                 VertexControl o;
526                 UNITY_SETUP_INSTANCE_ID(v);
527                 UNITY_TRANSFER_INSTANCE_ID(v, o);
528                 o.vertex = v.vertex;
529                 o.ase_normal = v.ase_normal;
530                 
531                 return o;
532             }
533 
534             TessellationFactors TessellationFunction (InputPatch<VertexControl,3> v)
535             {
536                 TessellationFactors o;
537                 float4 tf = 1;
538                 float tessValue = _TessValue; float tessMin = _TessMin; float tessMax = _TessMax;
539                 float edgeLength = _TessEdgeLength; float tessMaxDisp = _TessMaxDisp;
540                 #if defined(ASE_FIXED_TESSELLATION)
541                 tf = FixedTess( tessValue );
542                 #elif defined(ASE_DISTANCE_TESSELLATION)
543                 tf = DistanceBasedTess(v[0].vertex, v[1].vertex, v[2].vertex, tessValue, tessMin, tessMax, GetObjectToWorldMatrix(), _WorldSpaceCameraPos );
544                 #elif defined(ASE_LENGTH_TESSELLATION)
545                 tf = EdgeLengthBasedTess(v[0].vertex, v[1].vertex, v[2].vertex, edgeLength, GetObjectToWorldMatrix(), _WorldSpaceCameraPos, _ScreenParams );
546                 #elif defined(ASE_LENGTH_CULL_TESSELLATION)
547                 tf = EdgeLengthBasedTessCull(v[0].vertex, v[1].vertex, v[2].vertex, edgeLength, tessMaxDisp, GetObjectToWorldMatrix(), _WorldSpaceCameraPos, _ScreenParams, unity_CameraWorldClipPlanes );
548                 #endif
549                 o.edge[0] = tf.x; o.edge[1] = tf.y; o.edge[2] = tf.z; o.inside = tf.w;
550                 return o;
551             }
552 
553             [domain("tri")]
554             [partitioning("fractional_odd")]
555             [outputtopology("triangle_cw")]
556             [patchconstantfunc("TessellationFunction")]
557             [outputcontrolpoints(3)]
558             VertexControl HullFunction(InputPatch<VertexControl, 3> patch, uint id : SV_OutputControlPointID)
559             {
560                return patch[id];
561             }
562 
563             [domain("tri")]
564             VertexOutput DomainFunction(TessellationFactors factors, OutputPatch<VertexControl, 3> patch, float3 bary : SV_DomainLocation)
565             {
566                 VertexInput o = (VertexInput) 0;
567                 o.vertex = patch[0].vertex * bary.x + patch[1].vertex * bary.y + patch[2].vertex * bary.z;
568                 o.ase_normal = patch[0].ase_normal * bary.x + patch[1].ase_normal * bary.y + patch[2].ase_normal * bary.z;
569                 
570                 #if defined(ASE_PHONG_TESSELLATION)
571                 float3 pp[3];
572                 for (int i = 0; i < 3; ++i)
573                     pp[i] = o.vertex.xyz - patch[i].ase_normal * (dot(o.vertex.xyz, patch[i].ase_normal) - dot(patch[i].vertex.xyz, patch[i].ase_normal));
574                 float phongStrength = _TessPhongStrength;
575                 o.vertex.xyz = phongStrength * (pp[0]*bary.x + pp[1]*bary.y + pp[2]*bary.z) + (1.0f-phongStrength) * o.vertex.xyz;
576                 #endif
577                 UNITY_TRANSFER_INSTANCE_ID(patch[0], o);
578                 return VertexFunction(o);
579             }
580             #else
581             VertexOutput vert ( VertexInput v )
582             {
583                 return VertexFunction( v );
584             }
585             #endif
586 
587             half4 frag(VertexOutput IN  ) : SV_TARGET
588             {
589                 UNITY_SETUP_INSTANCE_ID(IN);
590                 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX( IN );
591 
592                 #if defined(ASE_NEEDS_FRAG_WORLD_POSITION)
593                 float3 WorldPosition = IN.worldPos;
594                 #endif
595                 float4 ShadowCoords = float4( 0, 0, 0, 0 );
596 
597                 #if defined(ASE_NEEDS_FRAG_SHADOWCOORDS)
598                     #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
599                         ShadowCoords = IN.shadowCoord;
600                     #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
601                         ShadowCoords = TransformWorldToShadowCoord( WorldPosition );
602                     #endif
603                 #endif
604 
605                 
606                 float Alpha = 1;
607                 float AlphaClipThreshold = 0.5;
608 
609                 #ifdef _ALPHATEST_ON
610                     clip(Alpha - AlphaClipThreshold);
611                 #endif
612 
613                 #ifdef LOD_FADE_CROSSFADE
614                     LODDitheringTransition( IN.clipPos.xyz, unity_LODFade.x );
615                 #endif
616                 return 0;
617             }
618             ENDHLSL
619         }
620     }
621 }
View Code
  1 struct Attributes
  2 {
  3     float4 positionOS: POSITION;
  4     float2 uv        : TEXCOORD0;
  5     half2 lightmapUV : TEXCOORD1;
  6     float4 tangent   : TANGENT;
  7     float3 normal    : NORMAL;
  8 };
  9 
 10 struct Varyings
 11 {
 12     float4 positionHCS                   : SV_POSITION;
 13     float4 uv                            : TEXCOORD0;
 14     float3 posWS                         : TEXCOORD1;
 15     float3 eyeVec                        : TEXCOORD2;
 16     float4 tangentToWorldAndPackedData[3]: TEXCOORD3;
 17     half4  ambientOrLightmapUV           : TEXCOORD6;
 18     float3 normalWS                      : TEXCOORD7;
 19     float4 shadowCoord                   : TEXCOORD8;
 20     float4 lightmapUVOrVertexSH          : TEXCOORD9;
 21     float3 viewWS                        : TEXCOORD10;
 22     half4 fogFactorAndVertexLight        : TEXCOORD11;
 23     float4 screenPos                     : TEXCOORD12;
 24     //TODO
 25     //     UNITY_SHADOW_COORDS(6)
 26     //     UNITY_FOG_COORDS(7)
 27     // #else
 28     //     UNITY_LIGHTING_COORDS(6,7)
 29     //     UNITY_FOG_COORDS(8)
 30 };
 31 
 32 
 33 
 34 #include "UtilsInclude.hlsl"
 35 // #define DIRLIGHTMAP_COMBINED
 36 
 37 
 38 Varyings vert (Attributes IN, half FUR_OFFSET =0)
 39 {
 40     UNITY_SETUP_INSTANCE_ID(IN);
 41     Varyings OUT;
 42     OUT = (Varyings)0;
 43     UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
 44     
 45     //Transform vertexPos by normal
 46     //短絨毛
 47     half3 direction = lerp(IN.normal, _Gravity * _GravityStrength + IN.normal * (1 - _GravityStrength), _FUR_OFFSET);
 48     //長毛
 49     // half3 direction = lerp(IN.normal, _Gravity * _GravityStrength + IN.normal, _FUR_OFFSET);
 50     IN.positionOS.xyz += direction * _FurLength * _FUR_OFFSET;
 51     OUT.posWS = TransformObjectToWorld(IN.positionOS.xyz);
 52     float3 positionWS = TransformObjectToWorld( IN.positionOS.xyz );
 53     float4 positionCS = TransformWorldToHClip( positionWS );
 54     OUT.screenPos = ComputeScreenPos(positionCS);
 55     
 56     OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
 57     OUT.uv.xy = TRANSFORM_TEX(IN.uv, _MainTex);
 58     OUT.viewWS = normalize( _WorldSpaceCameraPos - OUT.posWS);
 59     VertexNormalInputs normalInput = GetVertexNormalInputs( IN.normal, IN.tangent );
 60     half3 vertexLight = VertexLighting( positionWS, normalInput.normalWS );
 61     half fogFactor = ComputeFogFactor( positionCS.z );
 62     OUT.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
 63     OUT.eyeVec = NormalizePerVertexNormal(OUT.posWS.xyz - _WorldSpaceCameraPos);
 64     half3 normalWS = TransformObjectToWorldNormal(IN.normal);
 65     OUT.normalWS = normalWS;
 66     #ifdef _TANGENT_TO_WORLD
 67         float4 tangentWorld = float4(TransformObjectToWorldDir(IN.tangent.xyz), IN.tangent.w);
 68         float3x3 tangentToWorld = CreateTangentToWorldPerVertex(normalWS, tangentWorld.xyz, tangentWorld.w);
 69         OUT.tangentToWorldAndPackedData[0].xyz = tangentToWorld[0];
 70         OUT.tangentToWorldAndPackedData[1].xyz = tangentToWorld[1];
 71         OUT.tangentToWorldAndPackedData[2].xyz = tangentToWorld[2];
 72     #else
 73         OUT.tangentToWorldAndPackedData[0].xyz = 0;
 74         OUT.tangentToWorldAndPackedData[1].xyz = 0;
 75         OUT.tangentToWorldAndPackedData[2].xyz = normalWS;
 76     #endif
 77 
 78     #ifdef _PARALLAXMAP
 79         TANGENT_SPACE_ROTATION;
 80         half3 viewDirForParallax = mul (rotation, ObjSpaceViewDir(IN.positionOS));
 81         OUT.tangentToWorldAndPackedData[0].w = viewDirForParallax.x;
 82         OUT.tangentToWorldAndPackedData[1].w = viewDirForParallax.y;
 83         OUT.tangentToWorldAndPackedData[2].w = viewDirForParallax.z;
 84     #endif
 85 
 86     VertexPositionInputs vertexInput = (VertexPositionInputs)0;
 87     vertexInput.positionWS = positionWS;
 88     vertexInput.positionCS = positionCS;
 89     OUTPUT_LIGHTMAP_UV(IN.lightmapUV, unity_LightmapST, OUT.lightmapUVOrVertexSH.xy);
 90     OUTPUT_SH(normalWS, OUT.lightmapUVOrVertexSH.xyz);
 91 
 92     OUT.ambientOrLightmapUV = VertexGIForward(IN, OUT.posWS, normalWS);
 93     //TODO Fog
 94     //TODO Shadow
 95     OUT.shadowCoord = GetShadowCoord( vertexInput );
 96     OUT.shadowCoord = TransformWorldToShadowCoord(positionWS);
 97 
 98     return OUT;
 99 }
100 
101 half4 frag (Varyings IN, half FUR_OFFSET = 0) : SV_Target
102 {
103     //Data
104     float3 Albedo = float3(0.5, 0.5, 0.5);
105     float Metallic = 0;
106     float3 Specular = 0.5;
107     float Smoothness = 0.5;
108     float Occlusion = 1;
109     float3 Emission = 0;
110     float Alpha = 1;
111     float3 BakedGI = 0;
112 
113     InputData inputData;
114     inputData.positionWS = IN.posWS;
115     inputData.viewDirectionWS = IN.viewWS;
116     inputData.shadowCoord = IN.shadowCoord;
117     inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;
118     inputData.normalWS = IN.normalWS;
119     inputData.fogCoord = IN.fogFactorAndVertexLight.x;
120     inputData.bakedGI = 0;
121     #ifdef _GI_ON
122     inputData.bakedGI = SAMPLE_GI( IN.lightmapUVOrVertexSH.xy, IN.lightmapUVOrVertexSH.xyz, IN.normalWS );
123     #endif
124 
125     half4 color = UniversalFragmentPBR(
126     inputData, 
127     _Albedo, 
128     _Metallic, 
129     _Specular, 
130     _Smoothness, 
131     _Occlusion, 
132     _Emission, 
133     _Alpha);
134 
135     #ifdef _REFRACTION_ASE
136         float4 projScreenPos = ScreenPos / ScreenPos.w;
137         float3 refractionOffset = ( RefractionIndex - 1.0 ) * mul( UNITY_MATRIX_V, WorldNormal ).xyz * ( 1.0 - dot( WorldNormal, WorldViewDirection ) );
138         projScreenPos.xy += refractionOffset.xy;
139         float3 refraction = SHADERGRAPH_SAMPLE_SCENE_COLOR( projScreenPos ) * RefractionColor;
140         color.rgb = lerp( refraction, color.rgb, color.a );
141         color.a = 1;
142     #endif
143 
144     #ifdef ASE_FOG
145         #ifdef TERRAIN_SPLAT_ADDPASS
146             color.rgb = MixFogColor(color.rgb, half3( 0, 0, 0 ), IN.fogFactorAndVertexLight.x );
147         #else
148             color.rgb = MixFog(color.rgb, IN.fogFactorAndVertexLight.x);
149         #endif
150     #endif
151 
152     //
153     //Dither
154     //UnityApplyDitherCrossFade(IN.positionHCS.xy);
155     half facing = dot(-IN.eyeVec, IN.tangentToWorldAndPackedData[2].xyz);
156     facing = saturate(ceil(facing)) * 2 - 1;
157 
158     FRAGMENT_SETUP(s)
159     UNITY_SETUP_INSTANCE_ID(IN);
160     UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);
161 
162     Light mainLight = GetMainLight (IN.shadowCoord);
163     half occlusion = CalOcclusion(IN.uv.xy);
164 
165     // #ifdef _GI_ON
166     // inputData.bakedGI = SAMPLE_GI(IN.lightmapUVOrVertexSH.xy, IN.lightmapUVOrVertexSH.xyz, IN.normalWS);
167     // #endif
168     //PBR
169     BRDFData brdfData;
170     half3 albedo = 0.5;
171     half3 specular = .5;
172     half brdfAlpha = 1;
173     InitializeBRDFData(albedo,0,specular,0.5, brdfAlpha, brdfData);
174     #ifdef _RECEIVE_SHADOWS
175     half lightAttenuation = mainLight.distanceAttenuation * mainLight.shadowAttenuation;
176     #else
177     half lightAttenuation = 1;
178     #endif
179     half NdotL = saturate(dot(inputData.normalWS, mainLight.direction));
180     half3 radiance = mainLight.color * (lightAttenuation * NdotL);
181     // half3 GIcolor = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);
182     // half3 BRDFColor = LightingPhysicallyBased(brdfData, mainLight, inputData.normalWS, inputData.viewDirectionWS);
183     //
184 
185     half4 c = FABRIC_BRDF_PBS(s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, mainLight, inputData, lightAttenuation);
186 
187     c.rgb += CalEmission(IN.uv.xy);
188 
189     //UNITY_APPLY_FOG(i.fogCoord, c.rgb);
190     // half alpha = tex2D(_LayerTex, TRANSFORM_TEX(IN.uv.xy, _LayerTex)).r;
191     float2 uvoffset = tex2D(_FlowMap, IN.uv.xy).rg*2-1;
192     // return tex2D(_FlowMap, IN.uv);
193     half alpha = tex2D(_LayerTex, TRANSFORM_TEX(IN.uv.xy, _LayerTex) + _UVOffset * uvoffset * _FUR_OFFSET).r;
194     alpha = step(lerp(0, _CutoffEnd, _FUR_OFFSET), alpha);
195     c.a = 1 - _FUR_OFFSET * _FUR_OFFSET;
196     c.a += dot(-s.eyeVec, s.normalWorld) - _EdgeFade;
197     c.a = max(0, c.a);
198     c.a *= alpha;
199     c = half4(c.rgb * lerp(lerp(_ShadowColor.rgb, 1, _FUR_OFFSET), 1, _ShadowLerp), c.a);
200     // float3 mainAtten = mainLight.color * mainLight.distanceAttenuation;
201     // mainAtten = lerp( mainAtten, mainAtten * mainLight.shadowAttenuation, shadow );
202 
203     // return half4(GIcolor+BRDFColor,1);
204     // return half4(mainLight.color * mainLight.distanceAttenuation,1);
205     // #ifdef MAIN_LIGHT_CALCULATE_SHADOWS
206     // return 1;
207     // #else 
208     // return 0;
209     
210     // #endif
211     return c;
212 }
213 Varyings vert_LayerBase(Attributes IN)
214 {
215     return vert(IN, 0);
216 }
217 Varyings vert_Layer(Attributes IN)
218 {
219     return vert(IN, .1);
220 }
221 half4 frag_LayerBase(Varyings IN) : SV_Target
222 {
223     return frag(IN, .0);
224 }
225 half4 frag_Layer(Varyings IN) : SV_Target
226 {
227     return frag(IN, .1);
228 }
View Code

效果:

 轉載請註明出處:https://www.cnblogs.com/jietian331/p/17330302.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章