كتابة تظليل مع رمز في الوحدة LWRP

مقدمة


مرحبا يا حبر اليوم أريد أن أتحدث قليلاً عن كيف يمكنك بسرعة وبدون ألم (تقريبًا) البدء في كتابة تظليلات النص الكلاسيكي في الوحدة باستخدام خط أنابيب التقديم الخفيف (LWRP) - أحد الأمثلة على خط أنابيب التقديم النصي (SRP) .

ولكن ماذا عن شادر الرسم البياني؟


Shader Graph هو أداة مريحة وسريعة لنماذج أولية أو كتابة تأثيرات بسيطة. ومع ذلك ، في بعض الأحيان ، من الضروري أن تكتب شيئًا معقدًا ومعقدًا ، وبعد ذلك - يتزايد عدد العقد والوظائف المخصصة والرسوم البيانية الفرعية بشكل لا يصدق ، وهذا هو السبب في أن مبرمج الرسومات الأكثر خبرة يبدأ في الخلط في هذه الفوضى بأكملها. نحن جميعًا ندرك أن الشفرة التي تم إنشاؤها تلقائيًا لا يمكن أن تكون أفضل من الشفرة المكتوبة يدويًا - لا تحتاج إلى الذهاب بعيدًا للحصول على أمثلة ، لأن أي خطأ في تخطيط العقد يمكن أن يؤدي إلى حقيقة أن الحساب المعروف بالفعل يؤدي إلى تظليل قمة الرأس سيتم حسابه بشكل متكرر في الجزء. هناك أشخاص أكثر راحة في التعامل مع الكود ، وليس مع العقد. قد تكون الأسباب مختلفة ، ولكن الجوهر هو نفسه - مع العقد ، يعيش الكود!

2020-01-19-17-07-35

مشاكل


لذا ، ما هي مشكلة الجلوس وكتابة تظليل النص العادي تحت LWRP؟ والمشكلة هي أن أجهزة التظليل السطحي القياسية المفضلة للجميع غير مدعومة في LWRP.
عند محاولة استخدامه ، نحصل على ما يلي:

2020-01-19-17-16-16

كود شادر
Shader "Custom/NewSurfaceShader" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard fullforwardshadows // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 sampler2D _MainTex; struct Input { float2 uv_MainTex; }; half _Glossiness; half _Metallic; fixed4 _Color; // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. // #pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutputStandard o) { // Albedo comes from a texture tinted by color fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; // Metallic and smoothness come from slider variables o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = ca; } ENDCG } FallBack "Diffuse" } 


ثم يتبادر إلى الذهن لمحاولة كتابة تظليل anlite منتظم مع جزء قمة وشظية. ولحسن الحظ ، كل شيء يعمل:

2020-01-19-17-22-46

كود شادر
 Shader "Unlit/NewUnlitShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } } 


ومع ذلك ، كيف لا يمكنك أن تكون حزينًا - يبدو أننا تركنا عراة على الهامش بدون ضوء وظلال وخرائط ضوئية و PBR الحبيب ، والتي بدونها لم تكن الحياة حلوة.
بالطبع ، يمكنك كتابة كل شيء باليد:
فليكن نور!

2020-01-19-17-55-56

كود شادر
 Shader "TheProxor/Simple Lit" { Properties { _MainTex("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType" = "Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" #include "UnityLightingCommon.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; fixed4 diffuse : COLOR0; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); half3 worldNormal = UnityObjectToWorldNormal(v.normal); half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz)); o.diffuse = nl * _LightColor0; return o; } fixed4 frag(v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); col *= i.diffuse; return col; } ENDCG } } } 


يبدو أن كل شيء يعمل ، لكن هذا مجرد إضاءة منتشرة. ماذا تفعل بعد ذلك؟ يمكنك الاستمرار في إرجاع كل شيء يدويًا ، ولكنه طويل وكئيب ، ولا يمكن إرجاع PBR بأي طريقة ، ونفقد جميع شرائح LWRP. لذلك ، ليس لدينا خيار سوى اختيار LWRP لإرجاع كل شيء بضربة سحرية واحدة.

قرار


هكذا ، كما تعلمون ، تم تصميم LWRP على أساس العارض الأمامي ، مما يعني أن لديه LitForwardPass الخاص به ، والذي يجب وصفه في مكان ما. من الواضح ، في مكان ما يوجد CGInclude فيه كل هذا موصوف. هذا هو المكان الذي انطلقنا فيه في مغامرة ممتعة في:
٪ localappdata٪ \ الوحدة \ ذاكرة التخزين المؤقت \ الحزم \ الحزم. com.com \ com.unity.render-pipelines.lightweight @ (إصدار LWRP) \

في الواقع ، بعد الوصول إلى العنوان المحدد والانتقال إلى مجلد Shaders ، يمكننا العثور على تظليل واحد مثير للاهتمام يسمى Lit.shader . في الواقع ، يمكننا أن نقول أن بحثنا قد انتهى ، ها هو - التظليل المرغوب. الذهاب إلى الداخل - نجد المحتويات التالية:

Lit.shader
 Shader "Lightweight Render Pipeline/Lit" { Properties { // Specular vs Metallic workflow [HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0 [MainColor] _BaseColor("Color", Color) = (0.5,0.5,0.5,1) [MainTexture] _BaseMap("Albedo", 2D) = "white" {} _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 _Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5 _GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 _SmoothnessTextureChannel("Smoothness texture channel", Float) = 0 [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 _MetallicGlossMap("Metallic", 2D) = "white" {} _SpecColor("Specular", Color) = (0.2, 0.2, 0.2) _SpecGlossMap("Specular", 2D) = "white" {} [ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 [ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0 _BumpScale("Scale", Float) = 1.0 _BumpMap("Normal Map", 2D) = "bump" {} _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 _OcclusionMap("Occlusion", 2D) = "white" {} _EmissionColor("Color", Color) = (0,0,0) _EmissionMap("Emission", 2D) = "white" {} // Blending state [HideInInspector] _Surface("__surface", Float) = 0.0 [HideInInspector] _Blend("__blend", Float) = 0.0 [HideInInspector] _AlphaClip("__clip", Float) = 0.0 [HideInInspector] _SrcBlend("__src", Float) = 1.0 [HideInInspector] _DstBlend("__dst", Float) = 0.0 [HideInInspector] _ZWrite("__zw", Float) = 1.0 [HideInInspector] _Cull("__cull", Float) = 2.0 _ReceiveShadows("Receive Shadows", Float) = 1.0 // Editmode props [HideInInspector] _QueueOffset("Queue offset", Float) = 0.0 // ObsoleteProperties [HideInInspector] _MainTex("BaseMap", 2D) = "white" {} [HideInInspector] _Color("Base Color", Color) = (0.5, 0.5, 0.5, 1) [HideInInspector] _GlossMapScale("Smoothness", Float) = 0.0 [HideInInspector] _Glossiness("Smoothness", Float) = 0.0 [HideInInspector] _GlossyReflections("EnvironmentReflections", Float) = 0.0 } SubShader { // Lightweight Pipeline tag is required. If Lightweight render pipeline is not set in the graphics settings // this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this // material work with both Lightweight Render Pipeline and Builtin Unity Pipeline Tags{"RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" "IgnoreProjector" = "True"} LOD 300 // ------------------------------------------------------------------ // Forward pass. Shades all light in a single pass. GI + emission + Fog Pass { // Lightmode matches the ShaderPassName set in LightweightRenderPipeline.cs. SRPDefaultUnlit and passes with // no LightMode tag are also rendered by Lightweight Render Pipeline Name "ForwardLit" Tags{"LightMode" = "LightweightForward"} Blend[_SrcBlend][_DstBlend] ZWrite[_ZWrite] Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard SRP library // All shaders must be compiled with HLSLcc and currently only gles is not using HLSLcc by default #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 // ------------------------------------- // Material Keywords #pragma shader_feature _NORMALMAP #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICSPECGLOSSMAP #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _OCCLUSIONMAP #pragma shader_feature _SPECULARHIGHLIGHTS_OFF #pragma shader_feature _ENVIRONMENTREFLECTIONS_OFF #pragma shader_feature _SPECULAR_SETUP #pragma shader_feature _RECEIVE_SHADOWS_OFF // ------------------------------------- // Lightweight Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile _ _SHADOWS_SOFT #pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE // ------------------------------------- // Unity defined keywords #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile_fog //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #pragma vertex LitPassVertex #pragma fragment LitPassFragment #include "LitInput.hlsl" #include "LitForwardPass.hlsl" ENDHLSL } Pass { Name "ShadowCaster" Tags{"LightMode" = "ShadowCaster"} ZWrite On ZTest LEqual Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 // ------------------------------------- // Material Keywords #pragma shader_feature _ALPHATEST_ON //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma vertex ShadowPassVertex #pragma fragment ShadowPassFragment #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/Shaders/ShadowCasterPass.hlsl" ENDHLSL } Pass { Name "DepthOnly" Tags{"LightMode" = "DepthOnly"} ZWrite On ColorMask 0 Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 #pragma vertex DepthOnlyVertex #pragma fragment DepthOnlyFragment // ------------------------------------- // Material Keywords #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/Shaders/DepthOnlyPass.hlsl" ENDHLSL } // This pass it not used during regular rendering, only for lightmap baking. Pass { Name "Meta" Tags{"LightMode" = "Meta"} Cull Off HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma vertex LightweightVertexMeta #pragma fragment LightweightFragmentMeta #pragma shader_feature _SPECULAR_SETUP #pragma shader_feature _EMISSION #pragma shader_feature _METALLICSPECGLOSSMAP #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _SPECGLOSSMAP #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitMetaPass.hlsl" ENDHLSL } Pass { Name "Lightweight2D" Tags{ "LightMode" = "Lightweight2D" } Blend[_SrcBlend][_DstBlend] ZWrite[_ZWrite] Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma vertex vert #pragma fragment frag #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ALPHAPREMULTIPLY_ON #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/Shaders/Utils/Lightweight2D.hlsl" ENDHLSL } } FallBack "Hidden/InternalErrorShader" CustomEditor "UnityEditor.Rendering.LWRP.ShaderGUI.LitShader" } 



يبقى فقط لتوسيعه لسهولة التحرير ، والتخلص من التضمين. حسنا ، قليلا تعديل في طريقتك الخاصة.

نحصل على شيء مثل هذا:

2020-01-19-18-28-13

تظليل اوبر النهائي
 Shader "TheProxor/LWRP/Dissolve + Vertex Offset" { Properties { // Specular vs Metallic workflow [HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0 [MainColor][HideInInspector] _BaseColor("Color", Color) = (0.5,0.5,0.5,1) [MainTexture][HideInInspector] _BaseMap("Albedo", 2D) = "white" {} [HideInInspector]_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 [HideInInspector]_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5 [HideInInspector]_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 [HideInInspector]_SmoothnessTextureChannel("Smoothness texture channel", Float) = 0 [Gamma][HideInInspector] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 [HideInInspector]_MetallicGlossMap("Metallic", 2D) = "white" {} [HideInInspector]_SpecColor("Specular", Color) = (0.2, 0.2, 0.2) [HideInInspector]_SpecGlossMap("Specular", 2D) = "white" {} [HideInInspector][ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 [HideInInspector][ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0 [HideInInspector]_BumpScale("Scale", Float) = 1.0 [HideInInspector]_BumpMap("Normal Map", 2D) = "bump" {} [HideInInspector]_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 [HideInInspector]_OcclusionMap("Occlusion", 2D) = "white" {} [HDR][HideInInspector]_EmissionColor("Color", Color) = (0,0,0) [HideInInspector]_EmissionMap("Emission", 2D) = "white" {} // Blending state [HideInInspector] _Surface("__surface", Float) = 0.0 [HideInInspector] _Blend("__blend", Float) = 0.0 [HideInInspector] _AlphaClip("__clip", Float) = 0.0 [HideInInspector] _SrcBlend("__src", Float) = 1.0 [HideInInspector] _DstBlend("__dst", Float) = 0.0 [HideInInspector] _ZWrite("__zw", Float) = 1.0 [HideInInspector] _Cull("__cull", Float) = 2.0 [HideInInspector]_ReceiveShadows("Receive Shadows", Float) = 1.0 // Editmode props [HideInInspector] _QueueOffset("Queue offset", Float) = 0.0 // ObsoleteProperties [HideInInspector] _MainTex("BaseMap", 2D) = "white" {} [HideInInspector] _Color("Base Color", Color) = (0.5, 0.5, 0.5, 1) [HideInInspector] _GlossMapScale("Smoothness", Float) = 0.0 [HideInInspector] _Glossiness("Smoothness", Float) = 0.0 [HideInInspector] _GlossyReflections("EnvironmentReflections", Float) = 0.0 //    _DissolveMap("Dissolve Map", 2D) = "white" {} _DissolveFactor("Dissolve Factor", Range(0, 1)) = 0.0 _DissolveWidth("Dissolve Width", Range(0, 1)) = 0.0 [HDR]_DissolveColor("Color", Color) = (1,1,0) } SubShader { // Lightweight Pipeline tag is required. If Lightweight render pipeline is not set in the graphics settings // this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this // material work with both Lightweight Render Pipeline and Builtin Unity Pipeline Tags{"RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" "IgnoreProjector" = "True"} LOD 300 // ------------------------------------------------------------------ // Forward pass. Shades all light in a single pass. GI + emission + Fog Pass { // Lightmode matches the ShaderPassName set in LightweightRenderPipeline.cs. SRPDefaultUnlit and passes with // no LightMode tag are also rendered by Lightweight Render Pipeline Name "ForwardLit" Tags{"LightMode" = "LightweightForward"} Blend[_SrcBlend][_DstBlend] ZWrite[_ZWrite] Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard SRP library // All shaders must be compiled with HLSLcc and currently only gles is not using HLSLcc by default #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 // ------------------------------------- // Material Keywords #pragma shader_feature _NORMALMAP #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICSPECGLOSSMAP #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _OCCLUSIONMAP #pragma shader_feature _SPECULARHIGHLIGHTS_OFF #pragma shader_feature _ENVIRONMENTREFLECTIONS_OFF #pragma shader_feature _SPECULAR_SETUP #pragma shader_feature _RECEIVE_SHADOWS_OFF // ------------------------------------- // Lightweight Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile _ _SHADOWS_SOFT #pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE // ------------------------------------- // Unity defined keywords #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile_fog //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #pragma vertex LitPassVertex #pragma fragment LitPassFragment #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/SurfaceInput.hlsl" #ifdef _SPECULAR_SETUP #define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv) #else #define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv) #endif struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; float2 texcoord : TEXCOORD0; float2 lightmapUV : TEXCOORD1; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float2 uv : TEXCOORD0; DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1); #ifdef _ADDITIONAL_LIGHTS float3 positionWS : TEXCOORD2; #endif #ifdef _NORMALMAP half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z #else half3 normalWS : TEXCOORD3; half3 viewDirWS : TEXCOORD4; #endif half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light #ifdef _MAIN_LIGHT_SHADOWS float4 shadowCoord : TEXCOORD7; #endif float4 positionCS : SV_POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO float3 uvDissolve : TEXCOORD8; }; CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; half4 _BaseColor; half4 _SpecColor; half4 _EmissionColor; half _Cutoff; half _Smoothness; half _Metallic; half _BumpScale; half _OcclusionStrength; float4 _DissolveMap_ST; //    _DissolveMap float _DissolveFactor; float _DissolveWidth; float4 _DissolveColor; CBUFFER_END TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap); TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap); TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap); TEXTURE2D(_DissolveMap); SAMPLER(sampler_DissolveMap); half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha) { half4 specGloss; #ifdef _METALLICSPECGLOSSMAP specGloss = SAMPLE_METALLICSPECULAR(uv); #ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A specGloss.a = albedoAlpha * _Smoothness; #else specGloss.a *= _Smoothness; #endif #else // _METALLICSPECGLOSSMAP #if _SPECULAR_SETUP specGloss.rgb = _SpecColor.rgb; #else specGloss.rgb = _Metallic.rrr; #endif #ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A specGloss.a = albedoAlpha * _Smoothness; #else specGloss.a = _Smoothness; #endif #endif return specGloss; } half SampleOcclusion(float2 uv) { #ifdef _OCCLUSIONMAP // TODO: Controls things like these by exposing SHADER_QUALITY levels (low, medium, high) #if defined(SHADER_API_GLES) return SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g; #else half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g; return LerpWhiteTo(occ, _OcclusionStrength); #endif #else return 1.0; #endif } inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData) { half4 albedoAlpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); // half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)); outSurfaceData.alpha = Alpha(albedoAlpha.a, _BaseColor, _Cutoff); half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a); outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb; #if _SPECULAR_SETUP outSurfaceData.metallic = 1.0h; outSurfaceData.specular = specGloss.rgb; #else outSurfaceData.metallic = specGloss.r; outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h); #endif outSurfaceData.smoothness = specGloss.a; outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale); outSurfaceData.occlusion = SampleOcclusion(uv); outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap)); // outSurfaceData.emission = _EmissionColor.rgb * SAMPLE_TEXTURE2D(_EmissionMap, sampler_EmissionMap, uv); } void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData) { inputData = (InputData)0; #ifdef _ADDITIONAL_LIGHTS inputData.positionWS = input.positionWS; #endif #ifdef _NORMALMAP half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); #else half3 viewDirWS = input.viewDirWS; inputData.normalWS = input.normalWS; #endif inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; #if defined(_MAIN_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF) inputData.shadowCoord = input.shadowCoord; #else inputData.shadowCoord = float4(0, 0, 0, 0); #endif inputData.fogCoord = input.fogFactorAndVertexLight.x; inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS); } /////////////////////////////////////////////////////////////////////////////// // Vertex and Fragment functions // /////////////////////////////////////////////////////////////////////////////// //Standard (Physically Based) shader Varyings LitPassVertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_TRANSFER_INSTANCE_ID(input, output); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); input.positionOS.xyz += normalize(input.positionOS.xyz) * sin(input.positionOS.x) * sin(_Time.x * 100); VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); half3 viewDirWS = GetCameraPositionWS() - vertexInput.positionWS; half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS); half fogFactor = ComputeFogFactor(vertexInput.positionCS.z); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); #ifdef _NORMALMAP output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z); #else output.normalWS = NormalizeNormalPerVertex(normalInput.normalWS); output.viewDirWS = viewDirWS; #endif OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV); OUTPUT_SH(output.normalWS.xyz, output.vertexSH); output.fogFactorAndVertexLight = half4(fogFactor, vertexLight); #ifdef _ADDITIONAL_LIGHTS output.positionWS = vertexInput.positionWS; #endif #if defined(_MAIN_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF) output.shadowCoord = GetShadowCoord(vertexInput); #endif output.positionCS = vertexInput.positionCS; return output; } // Used in Standard (Physically Based) shader half4 LitPassFragment(Varyings input) : SV_Target { input.uv += _Time.x * 10; UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); SurfaceData surfaceData; InitializeStandardLitSurfaceData(input.uv, surfaceData); InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); float4 mask = SAMPLE_TEXTURE2D(_DissolveMap, sampler_DissolveMap, input.uv); if (mask.r > _DissolveFactor) discard; bool outline = mask.r > _DissolveFactor - _DissolveWidth; surfaceData.emission *= outline * _DissolveColor; half4 color = LightweightFragmentPBR(inputData, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha); color *= lerp(1, _DissolveColor, outline); color.rgb = MixFog(color.rgb, inputData.fogCoord); return color; } ENDHLSL } // Pass { Name "ShadowCaster" Tags{"LightMode" = "ShadowCaster"} ZWrite On ZTest LEqual Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 // ------------------------------------- // Material Keywords #pragma shader_feature _ALPHATEST_ON //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma vertex ShadowPassVertex #pragma fragment ShadowPassFragment #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Shadows.hlsl" float3 _LightDirection; struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float2 uv : TEXCOORD0; float4 positionCS : SV_POSITION; }; CBUFFER_START(UnityPerMaterial) float4 _DissolveMap_ST; //    _DissolveMap float _DissolveFactor; CBUFFER_END TEXTURE2D(_DissolveMap); SAMPLER(sampler_DissolveMap); float4 GetShadowPositionHClip(Attributes input) { float3 positionWS = TransformObjectToWorld(input.positionOS.xyz); float3 normalWS = TransformObjectToWorldNormal(input.normalOS); float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, _LightDirection)); #if UNITY_REVERSED_Z positionCS.z = min(positionCS.z, positionCS.w * UNITY_NEAR_CLIP_VALUE); #else positionCS.z = max(positionCS.z, positionCS.w * UNITY_NEAR_CLIP_VALUE); #endif return positionCS; } Varyings ShadowPassVertex(Attributes input) { Varyings output; input.positionOS.xyz += normalize(input.positionOS.xyz) * sin(input.positionOS.x) * sin(_Time.x * 100); UNITY_SETUP_INSTANCE_ID(input); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); output.positionCS = GetShadowPositionHClip(input); return output; } half4 ShadowPassFragment(Varyings input) : SV_TARGET { float4 mask = SAMPLE_TEXTURE2D(_DissolveMap, sampler_DissolveMap, input.uv); if (mask.r > _DissolveFactor) discard; Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); return 0; } ENDHLSL } Pass { Name "DepthOnly" Tags{"LightMode" = "DepthOnly"} ZWrite On ColorMask 0 Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 #pragma vertex DepthOnlyVertex #pragma fragment DepthOnlyFragment // ------------------------------------- // Material Keywords #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl" #ifndef LIGHTWEIGHT_DEPTH_ONLY_PASS_INCLUDED #define LIGHTWEIGHT_DEPTH_ONLY_PASS_INCLUDED struct Attributes { float4 position : POSITION; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float2 uv : TEXCOORD0; float4 positionCS : SV_POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; Varyings DepthOnlyVertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); input.position.xyz += normalize(input.position.xyz) * sin(input.position.x) * sin(_Time.x * 100); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); output.positionCS = TransformObjectToHClip(input.position.xyz); return output; } half4 DepthOnlyFragment(Varyings input) : SV_TARGET { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); return 0; } #endif ENDHLSL } // Pass { Name "Meta" Tags{"LightMode" = "Meta"} Cull Off HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma vertex LightweightVertexMeta #pragma fragment LightweightFragmentMeta #pragma shader_feature _SPECULAR_SETUP #pragma shader_feature _EMISSION #pragma shader_feature _METALLICSPECGLOSSMAP #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _SPECGLOSSMAP #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/MetaInput.hlsl" #ifndef LIGHTWEIGHT_LIT_META_PASS_INCLUDED #define LIGHTWEIGHT_LIT_META_PASS_INCLUDED Varyings LightweightVertexMeta(Attributes input) { Varyings output; output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2, unity_LightmapST, unity_DynamicLightmapST); output.uv = TRANSFORM_TEX(input.uv0, _BaseMap); return output; } half4 LightweightFragmentMeta(Varyings input) : SV_Target { SurfaceData surfaceData; InitializeStandardLitSurfaceData(input.uv, surfaceData); BRDFData brdfData; InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData); MetaInput metaInput; metaInput.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5; metaInput.SpecularColor = surfaceData.specular; metaInput.Emission = surfaceData.emission; return MetaFragment(metaInput); } #endif ENDHLSL } Pass { Name "Lightweight2D" Tags{ "LightMode" = "Lightweight2D" } Blend[_SrcBlend][_DstBlend] ZWrite[_ZWrite] Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma vertex vert #pragma fragment frag #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ALPHAPREMULTIPLY_ON #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/Shaders/Utils/Lightweight2D.hlsl" ENDHLSL } } FallBack "Hidden/InternalErrorShader" CustomEditor "UnityEditor.Rendering.LWRP.ShaderGUI.LitShaderEditor" } 


بادئ ذي بدء ، تحتاج إلى معرفة ما في التظليل الناتج. أولاً ، نحن مهتمون بالخط:

 CustomEditor "UnityEditor.Rendering.LWRP.ShaderGUI.LitShaderEditor" 

والتي ، كما نتذكر ، في الأصل كانت كما يلي:

 CustomEditor "UnityEditor.Rendering.LWRP.ShaderGUI.LitShader" 

إذن ما هذا ولماذا؟ إجابة هذا السؤال بسيطة للغاية - إذا نظرت عن كثب ، فإن جهاز التظليل يحتوي على عدد كبير من الأنواع المختلفة من التعريفات ، والتي من الغريب أنها تحتاج إلى التنشيط وإلغاء تنشيطها ، وهذا ، للحظة ، يجب القيام به من التعليمات البرمجية ، وهذا هو سبب حاجتنا إلى مفتش مخصص. علاوة على ذلك ، ينبغي أن يتيح لنا المفتش المخصص فرصة تحرير ليس فقط الخصائص المضمنة ، ولكن أيضًا تلك التي قد نحتاجها في تظليلنا. يحتوي التظليل الأصلي بالفعل على مفتش مخصص ، لذلك نحن بالتأكيد ندوسه من خلال البحث عنه على طول المسار التالي:
٪ localappdata٪ \ الوحدة \ ذاكرة التخزين المؤقت \ الحزم \ package.unity.com \ com.unity.render-pipelines.lightweight@6.9.2 \ Editor \ ShaderGUI \ Shaders \
في الواقع ، نحن مهتمون بملف LitShader.cs ، الموروث من BaseShaderGUI:

 internal class LitShader : BaseShaderGUI { ... } 

يتم إجراء الدُفعة الرئيسية تمامًا في BaseShaderGUI.cs ، والتي يمكن العثور عليها في المجلد بمستوى أعلى:

 public abstract class BaseShaderGUI : ShaderGUI { ... } 

Editor ( — , , UnityEditor ). , , - SavedBool , bool. . , .

:

 SavedBool m_SurfaceOptionsFoldout; SavedBool m_SurfaceInputsFoldout; SavedBool m_AdvancedFoldout; 

:

 AnimatedValues.AnimBool m_SurfaceOptionsFoldout; AnimatedValues.AnimBool m_SurfaceInputsFoldout; AnimatedValues.AnimBool m_AdvancedFoldout; 

:

 AnimatedValues.AnimBool m_OtherFoldout; 

, :

 protected class Styles { // Catergories ... public static readonly GUIContent OtherOptions = new GUIContent("Your own options", "You own custom options"); } 

حسنًا ، دعنا الآن نفعل خدعة صغيرة. كما ترون ، بالنسبة لجميع الخصائص القياسية ، أقوم بتعيين سمة HideInInspector ، التي تشير مباشرةً إلى أن هذه الخاصية ستكون مخفية في المفتش. ومع ذلك ، هذا هو ذات الصلة فقط للمفتش القياسية للمواد ، ولكن أي واحد؟ هذا صحيح ، مخصص! هذا يعني أن جميع الخصائص المدمجة لدينا يتم تقديمها بأي شكل من الأشكال. لذلك دعونا نخفيهم:

 ... [MainColor][HideInInspector] _BaseColor("Color", Color) = (0.5,0.5,0.5,1) [MainTexture][HideInInspector] _BaseMap("Albedo", 2D) = "white" {} [HideInInspector]_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 [HideInInspector]_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5 [HideInInspector]_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 [HideInInspector]_SmoothnessTextureChannel("Smoothness texture channel", Float) = 0 ... 

وداخل رمز المحرر المخصص ، ندعو ببساطة إلى تقديم المفتش القياسي:

 public override void OnGUI(...) { ... m_OtherFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_OtherFoldout.value, Styles.OtherOptions); if (m_OtherFoldout.value) { base.OnGUI(materialEditorIn, properties); EditorGUILayout.Space(); } EditorGUILayout.EndFoldoutHeaderGroup(); ... } 

والنتيجة واضحة: وهنا رمز لكلا النصين:

2020-01-19-22-58-23



BaseShaderEditor.cs
 using System; using UnityEngine; using UnityEngine.Rendering; using UnityEditor.Rendering; namespace UnityEditor { public abstract class BaseShaderEditor : ShaderGUI { #region EnumsAndClasses public enum SurfaceType { Opaque, Transparent } public enum BlendMode { Alpha, // Old school alpha-blending mode, fresnel does not affect amount of transparency Premultiply, // Physically plausible transparency mode, implemented as alpha pre-multiply Additive, Multiply } public enum SmoothnessSource { BaseAlpha, SpecularAlpha } public enum RenderFace { Front = 2, Back = 1, Both = 0 } protected class Styles { // Catergories public static readonly GUIContent SurfaceOptions = new GUIContent("Surface Options", "Controls how LWRP renders the Material on a screen."); public static readonly GUIContent SurfaceInputs = new GUIContent("Surface Inputs", "These settings describe the look and feel of the surface itself."); public static readonly GUIContent AdvancedLabel = new GUIContent("Advanced", "These settings affect behind-the-scenes rendering and underlying calculations."); public static readonly GUIContent surfaceType = new GUIContent("Surface Type", "Select a surface type for your texture. Choose between Opaque or Transparent."); public static readonly GUIContent blendingMode = new GUIContent("Blending Mode", "Controls how the color of the Transparent surface blends with the Material color in the background."); public static readonly GUIContent cullingText = new GUIContent("Render Face", "Specifies which faces to cull from your geometry. Front culls front faces. Back culls backfaces. None means that both sides are rendered."); public static readonly GUIContent alphaClipText = new GUIContent("Alpha Clipping", "Makes your Material act like a Cutout shader. Use this to create a transparent effect with hard edges between opaque and transparent areas."); public static readonly GUIContent alphaClipThresholdText = new GUIContent("Threshold", "Sets where the Alpha Clipping starts. The higher the value is, the brighter the effect is when clipping starts."); public static readonly GUIContent receiveShadowText = new GUIContent("Receive Shadows", "When enabled, other GameObjects can cast shadows onto this GameObject."); public static readonly GUIContent baseMap = new GUIContent("Base Map", "Specifies the base Material and/or Color of the surface. If you've selected Transparent or Alpha Clipping under Surface Options, your Material uses the Texture's alpha channel or color."); public static readonly GUIContent emissionMap = new GUIContent("Emission Map", "Sets a Texture map to use for emission. You can also select a color with the color picker. Colors are multiplied over the Texture."); public static readonly GUIContent normalMapText = new GUIContent("Normal Map", "Assigns a tangent-space normal map."); public static readonly GUIContent bumpScaleNotSupported = new GUIContent("Bump scale is not supported on mobile platforms"); public static readonly GUIContent fixNormalNow = new GUIContent("Fix now", "Converts the assigned texture to be a normal map format."); public static readonly GUIContent queueSlider = new GUIContent("Priority", "Determines the chronological rendering order for a Material. High values are rendered first."); public static readonly GUIContent OtherOptions = new GUIContent("Your own options", "You own custom options"); } #endregion #region Variables protected MaterialEditor materialEditor { get; set; } protected MaterialProperty surfaceTypeProp { get; set; } protected MaterialProperty blendModeProp { get; set; } protected MaterialProperty cullingProp { get; set; } protected MaterialProperty alphaClipProp { get; set; } protected MaterialProperty alphaCutoffProp { get; set; } protected MaterialProperty receiveShadowsProp { get; set; } // Common Surface Input properties protected MaterialProperty baseMapProp { get; set; } protected MaterialProperty baseColorProp { get; set; } protected MaterialProperty emissionMapProp { get; set; } protected MaterialProperty emissionColorProp { get; set; } protected MaterialProperty queueOffsetProp { get; set; } public bool m_FirstTimeApply = true; private const string k_KeyPrefix = "LightweightRP:Material:UI_State:"; private string m_HeaderStateKey = null; // Header foldout states AnimatedValues.AnimBool m_SurfaceOptionsFoldout; AnimatedValues.AnimBool m_SurfaceInputsFoldout; AnimatedValues.AnimBool m_AdvancedFoldout; AnimatedValues.AnimBool m_OtherFoldout; #endregion private const int queueOffsetRange = 50; //////////////////////////////////// // General Functions // //////////////////////////////////// #region GeneralFunctions public abstract void MaterialChanged(Material material); public virtual void FindProperties(MaterialProperty[] properties) { surfaceTypeProp = FindProperty("_Surface", properties); blendModeProp = FindProperty("_Blend", properties); cullingProp = FindProperty("_Cull", properties); alphaClipProp = FindProperty("_AlphaClip", properties); alphaCutoffProp = FindProperty("_Cutoff", properties); receiveShadowsProp = FindProperty("_ReceiveShadows", properties, false); baseMapProp = FindProperty("_BaseMap", properties, false); baseColorProp = FindProperty("_BaseColor", properties, false); emissionMapProp = FindProperty("_EmissionMap", properties, false); emissionColorProp = FindProperty("_EmissionColor", properties, false); queueOffsetProp = FindProperty("_QueueOffset", properties, false); } public override void OnGUI(MaterialEditor materialEditorIn, MaterialProperty[] properties) { if (materialEditorIn == null) throw new ArgumentNullException("materialEditorIn"); FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly materialEditor = materialEditorIn; Material material = materialEditor.target as Material; // Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing // material to a lightweight shader. if (m_FirstTimeApply) { OnOpenGUI(material, materialEditorIn); m_FirstTimeApply = false; } ShaderPropertiesGUI(material); m_OtherFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_OtherFoldout.value, Styles.OtherOptions); if (m_OtherFoldout.value) { base.OnGUI(materialEditorIn, properties); EditorGUILayout.Space(); } EditorGUILayout.EndFoldoutHeaderGroup(); foreach (var obj in materialEditor.targets) MaterialChanged((Material)obj); } public virtual void OnOpenGUI(Material material, MaterialEditor materialEditor) { // Foldout states m_HeaderStateKey = k_KeyPrefix + material.shader.name; // Create key string for editor prefs m_SurfaceOptionsFoldout = new AnimatedValues.AnimBool(true); m_SurfaceInputsFoldout = new AnimatedValues.AnimBool(true); m_AdvancedFoldout = new AnimatedValues.AnimBool(true); m_OtherFoldout = new AnimatedValues.AnimBool(true); foreach (var obj in materialEditor.targets) MaterialChanged((Material)obj); } public void ShaderPropertiesGUI(Material material) { if (material == null) throw new ArgumentNullException("material"); EditorGUI.BeginChangeCheck(); m_SurfaceOptionsFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SurfaceOptionsFoldout.value, Styles.SurfaceOptions); if (m_SurfaceOptionsFoldout.value) { DrawSurfaceOptions(material); EditorGUILayout.Space(); } EditorGUILayout.EndFoldoutHeaderGroup(); m_SurfaceInputsFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SurfaceInputsFoldout.value, Styles.SurfaceInputs); if (m_SurfaceInputsFoldout.value) { DrawSurfaceInputs(material); EditorGUILayout.Space(); } EditorGUILayout.EndFoldoutHeaderGroup(); m_AdvancedFoldout.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_AdvancedFoldout.value, Styles.AdvancedLabel); if (m_AdvancedFoldout.value) { DrawAdvancedOptions(material); EditorGUILayout.Space(); } EditorGUILayout.EndFoldoutHeaderGroup(); DrawAdditionalFoldouts(material); if (EditorGUI.EndChangeCheck()) { foreach (var obj in materialEditor.targets) MaterialChanged((Material)obj); } } #endregion //////////////////////////////////// // Drawing Functions // //////////////////////////////////// #region DrawingFunctions public virtual void DrawSurfaceOptions(Material material) { DoPopup(Styles.surfaceType, surfaceTypeProp, Enum.GetNames(typeof(SurfaceType))); if ((SurfaceType)material.GetFloat("_Surface") == SurfaceType.Transparent) DoPopup(Styles.blendingMode, blendModeProp, Enum.GetNames(typeof(BlendMode))); EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = cullingProp.hasMixedValue; var culling = (RenderFace)cullingProp.floatValue; culling = (RenderFace)EditorGUILayout.EnumPopup(Styles.cullingText, culling); if (EditorGUI.EndChangeCheck()) { materialEditor.RegisterPropertyChangeUndo(Styles.cullingText.text); cullingProp.floatValue = (float)culling; material.doubleSidedGI = (RenderFace)cullingProp.floatValue != RenderFace.Front; } EditorGUI.showMixedValue = false; EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = alphaClipProp.hasMixedValue; var alphaClipEnabled = EditorGUILayout.Toggle(Styles.alphaClipText, alphaClipProp.floatValue == 1); if (EditorGUI.EndChangeCheck()) alphaClipProp.floatValue = alphaClipEnabled ? 1 : 0; EditorGUI.showMixedValue = false; if (alphaClipProp.floatValue == 1) materialEditor.ShaderProperty(alphaCutoffProp, Styles.alphaClipThresholdText, 1); if (receiveShadowsProp != null) { EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = receiveShadowsProp.hasMixedValue; var receiveShadows = EditorGUILayout.Toggle(Styles.receiveShadowText, receiveShadowsProp.floatValue == 1.0f); if (EditorGUI.EndChangeCheck()) receiveShadowsProp.floatValue = receiveShadows ? 1.0f : 0.0f; EditorGUI.showMixedValue = false; } } public virtual void DrawSurfaceInputs(Material material) { DrawBaseProperties(material); } public virtual void DrawAdvancedOptions(Material material) { materialEditor.EnableInstancingField(); if (queueOffsetProp != null) { EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = queueOffsetProp.hasMixedValue; var queue = EditorGUILayout.IntSlider(Styles.queueSlider, (int)queueOffsetProp.floatValue, -queueOffsetRange, queueOffsetRange); if (EditorGUI.EndChangeCheck()) queueOffsetProp.floatValue = queue; EditorGUI.showMixedValue = false; } } public virtual void DrawAdditionalFoldouts(Material material) { } public virtual void DrawBaseProperties(Material material) { if (baseMapProp != null && baseColorProp != null) // Draw the baseMap, most shader will have at least a baseMap { materialEditor.TexturePropertySingleLine(Styles.baseMap, baseMapProp, baseColorProp); // TODO Temporary fix for lightmapping, to be replaced with attribute tag. if (material.HasProperty("_MainTex")) { material.SetTexture("_MainTex", baseMapProp.textureValue); var baseMapTiling = baseMapProp.textureScaleAndOffset; material.SetTextureScale("_MainTex", new Vector2(baseMapTiling.x, baseMapTiling.y)); material.SetTextureOffset("_MainTex", new Vector2(baseMapTiling.z, baseMapTiling.w)); } } } protected virtual void DrawEmissionProperties(Material material, bool keyword) { var emissive = true; var hadEmissionTexture = emissionMapProp.textureValue != null; if (!keyword) { materialEditor.TexturePropertyWithHDRColor(Styles.emissionMap, emissionMapProp, emissionColorProp, false); } else { // Emission for GI? emissive = materialEditor.EmissionEnabledProperty(); EditorGUI.BeginDisabledGroup(!emissive); { // Texture and HDR color controls materialEditor.TexturePropertyWithHDRColor(Styles.emissionMap, emissionMapProp, emissionColorProp, false); } EditorGUI.EndDisabledGroup(); } // If texture was assigned and color was black set color to white var brightness = emissionColorProp.colorValue.maxColorComponent; if (emissionMapProp.textureValue != null && !hadEmissionTexture && brightness <= 0f) emissionColorProp.colorValue = Color.white; // LW does not support RealtimeEmissive. We set it to bake emissive and handle the emissive is black right. if (emissive) { material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive; if (brightness <= 0f) material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; } } public static void DrawNormalArea(MaterialEditor materialEditor, MaterialProperty bumpMap, MaterialProperty bumpMapScale = null) { if (bumpMapScale != null) { materialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap, bumpMap.textureValue != null ? bumpMapScale : null); if (bumpMapScale.floatValue != 1 && UnityEditorInternal.InternalEditorUtility.IsMobilePlatform( EditorUserBuildSettings.activeBuildTarget)) if (materialEditor.HelpBoxWithButton(Styles.bumpScaleNotSupported, Styles.fixNormalNow)) bumpMapScale.floatValue = 1; } else { materialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMap); } } protected static void DrawTileOffset(MaterialEditor materialEditor, MaterialProperty textureProp) { materialEditor.TextureScaleOffsetProperty(textureProp); } #endregion //////////////////////////////////// // Material Data Functions // //////////////////////////////////// #region MaterialDataFunctions public static void SetMaterialKeywords(Material material, Action<Material> shadingModelFunc = null, Action<Material> shaderFunc = null) { // Clear all keywords for fresh start material.shaderKeywords = null; // Setup blending - consistent across all LWRP shaders SetupMaterialBlendMode(material); // Receive Shadows if (material.HasProperty("_ReceiveShadows")) CoreUtils.SetKeyword(material, "_RECEIVE_SHADOWS_OFF", material.GetFloat("_ReceiveShadows") == 0.0f); // Emission if (material.HasProperty("_EmissionColor")) MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; if (material.HasProperty("_EmissionEnabled") && !shouldEmissionBeEnabled) shouldEmissionBeEnabled = material.GetFloat("_EmissionEnabled") >= 0.5f; CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); // Normal Map if (material.HasProperty("_BumpMap")) CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap")); // Shader specific keyword functions shadingModelFunc?.Invoke(material); shaderFunc?.Invoke(material); } public static void SetupMaterialBlendMode(Material material) { if (material == null) throw new ArgumentNullException("material"); bool alphaClip = material.GetFloat("_AlphaClip") == 1; if (alphaClip) { material.EnableKeyword("_ALPHATEST_ON"); } else { material.DisableKeyword("_ALPHATEST_ON"); } var queueOffset = 0; // queueOffsetRange; if (material.HasProperty("_QueueOffset")) queueOffset = queueOffsetRange - (int)material.GetFloat("_QueueOffset"); SurfaceType surfaceType = (SurfaceType)material.GetFloat("_Surface"); if (surfaceType == SurfaceType.Opaque) { if (alphaClip) { material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest; material.SetOverrideTag("RenderType", "TransparentCutout"); } else { material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry; material.SetOverrideTag("RenderType", "Opaque"); } material.renderQueue += queueOffset; material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.SetShaderPassEnabled("ShadowCaster", true); } else { BlendMode blendMode = (BlendMode)material.GetFloat("_Blend"); var queue = (int)UnityEngine.Rendering.RenderQueue.Transparent; // Specific Transparent Mode Settings switch (blendMode) { case BlendMode.Alpha: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); break; case BlendMode.Premultiply: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); break; case BlendMode.Additive: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); break; case BlendMode.Multiply: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.EnableKeyword("_ALPHAMODULATE_ON"); break; } // General Transparent Material Settings material.SetOverrideTag("RenderType", "Transparent"); material.SetInt("_ZWrite", 0); material.renderQueue = queue + queueOffset; material.SetShaderPassEnabled("ShadowCaster", false); } } #endregion //////////////////////////////////// // Helper Functions // //////////////////////////////////// #region HelperFunctions public static void TwoFloatSingleLine(GUIContent title, MaterialProperty prop1, GUIContent prop1Label, MaterialProperty prop2, GUIContent prop2Label, MaterialEditor materialEditor, float labelWidth = 30f) { EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = prop1.hasMixedValue || prop2.hasMixedValue; Rect rect = EditorGUILayout.GetControlRect(); EditorGUI.PrefixLabel(rect, title); var indent = EditorGUI.indentLevel; var preLabelWidth = EditorGUIUtility.labelWidth; EditorGUI.indentLevel = 0; EditorGUIUtility.labelWidth = labelWidth; Rect propRect1 = new Rect(rect.x + preLabelWidth, rect.y, (rect.width - preLabelWidth) * 0.5f, EditorGUIUtility.singleLineHeight); var prop1val = EditorGUI.FloatField(propRect1, prop1Label, prop1.floatValue); Rect propRect2 = new Rect(propRect1.x + propRect1.width, rect.y, propRect1.width, EditorGUIUtility.singleLineHeight); var prop2val = EditorGUI.FloatField(propRect2, prop2Label, prop2.floatValue); EditorGUI.indentLevel = indent; EditorGUIUtility.labelWidth = preLabelWidth; if (EditorGUI.EndChangeCheck()) { materialEditor.RegisterPropertyChangeUndo(title.text); prop1.floatValue = prop1val; prop2.floatValue = prop2val; } EditorGUI.showMixedValue = false; } public void DoPopup(GUIContent label, MaterialProperty property, string[] options) { DoPopup(label, property, options, materialEditor); } public static void DoPopup(GUIContent label, MaterialProperty property, string[] options, MaterialEditor materialEditor) { if (property == null) throw new ArgumentNullException("property"); EditorGUI.showMixedValue = property.hasMixedValue; var mode = property.floatValue; EditorGUI.BeginChangeCheck(); mode = EditorGUILayout.Popup(label, (int)mode, options); if (EditorGUI.EndChangeCheck()) { materialEditor.RegisterPropertyChangeUndo(label.text); property.floatValue = mode; } EditorGUI.showMixedValue = false; } // Helper to show texture and color properties public static Rect TextureColorProps(MaterialEditor materialEditor, GUIContent label, MaterialProperty textureProp, MaterialProperty colorProp, bool hdr = false) { Rect rect = EditorGUILayout.GetControlRect(); EditorGUI.showMixedValue = textureProp.hasMixedValue; materialEditor.TexturePropertyMiniThumbnail(rect, textureProp, label.text, label.tooltip); EditorGUI.showMixedValue = false; if (colorProp != null) { EditorGUI.BeginChangeCheck(); EditorGUI.showMixedValue = colorProp.hasMixedValue; int indentLevel = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; Rect rectAfterLabel = new Rect(rect.x + EditorGUIUtility.labelWidth, rect.y, EditorGUIUtility.fieldWidth, EditorGUIUtility.singleLineHeight); var col = EditorGUI.ColorField(rectAfterLabel, GUIContent.none, colorProp.colorValue, true, false, hdr); EditorGUI.indentLevel = indentLevel; if (EditorGUI.EndChangeCheck()) { materialEditor.RegisterPropertyChangeUndo(colorProp.displayName); colorProp.colorValue = col; } EditorGUI.showMixedValue = false; } return rect; } // Copied from shaderGUI as it is a protected function in an abstract class, unavailable to others public new static MaterialProperty FindProperty(string propertyName, MaterialProperty[] properties) { return FindProperty(propertyName, properties, true); } // Copied from shaderGUI as it is a protected function in an abstract class, unavailable to others public new static MaterialProperty FindProperty(string propertyName, MaterialProperty[] properties, bool propertyIsMandatory) { for (int index = 0; index < properties.Length; ++index) { if (properties[index] != null && properties[index].name == propertyName) return properties[index]; } if (propertyIsMandatory) throw new ArgumentException("Could not find MaterialProperty: '" + propertyName + "', Num properties: " + (object)properties.Length); return null; } #endregion } } 


LitShaderEditor.cs
 using System; using UnityEngine; using UnityEngine.Rendering; using UnityEditor.Rendering.LWRP; namespace UnityEditor.Rendering.LWRP.ShaderGUI { internal class LitShaderEditor : BaseShaderEditor { // Properties private LitGUI.LitProperties litProperties; // collect properties from the material properties public override void FindProperties(MaterialProperty[] properties) { base.FindProperties(properties); litProperties = new LitGUI.LitProperties(properties); } // material changed check public override void MaterialChanged(Material material) { if (material == null) throw new ArgumentNullException("material"); SetMaterialKeywords(material, LitGUI.SetMaterialKeywords); } // material main surface options public override void DrawSurfaceOptions(Material material) { if (material == null) throw new ArgumentNullException("material"); // Use default labelWidth EditorGUIUtility.labelWidth = 0f; // Detect any changes to the material EditorGUI.BeginChangeCheck(); if (litProperties.workflowMode != null) { DoPopup(LitGUI.Styles.workflowModeText, litProperties.workflowMode, Enum.GetNames(typeof(LitGUI.WorkflowMode))); } if (EditorGUI.EndChangeCheck()) { foreach (var obj in blendModeProp.targets) MaterialChanged((Material)obj); } base.DrawSurfaceOptions(material); } // material main surface inputs public override void DrawSurfaceInputs(Material material) { base.DrawSurfaceInputs(material); LitGUI.Inputs(litProperties, materialEditor, material); DrawEmissionProperties(material, true); DrawTileOffset(materialEditor, baseMapProp); } // material main advanced options public override void DrawAdvancedOptions(Material material) { if (litProperties.reflections != null && litProperties.highlights != null) { EditorGUI.BeginChangeCheck(); { materialEditor.ShaderProperty(litProperties.highlights, LitGUI.Styles.highlightsText); materialEditor.ShaderProperty(litProperties.reflections, LitGUI.Styles.reflectionsText); EditorGUI.BeginChangeCheck(); } } base.DrawAdvancedOptions(material); } public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader) { if (material == null) throw new ArgumentNullException("material"); // _Emission property is lost after assigning Standard shader to the material // thus transfer it before assigning the new shader if (material.HasProperty("_Emission")) { material.SetColor("_EmissionColor", material.GetColor("_Emission")); } base.AssignNewShaderToMaterial(material, oldShader, newShader); if (oldShader == null || !oldShader.name.Contains("Legacy Shaders/")) { SetupMaterialBlendMode(material); return; } SurfaceType surfaceType = SurfaceType.Opaque; BlendMode blendMode = BlendMode.Alpha; if (oldShader.name.Contains("/Transparent/Cutout/")) { surfaceType = SurfaceType.Opaque; material.SetFloat("_AlphaClip", 1); } else if (oldShader.name.Contains("/Transparent/")) { // NOTE: legacy shaders did not provide physically based transparency // therefore Fade mode surfaceType = SurfaceType.Transparent; blendMode = BlendMode.Alpha; } material.SetFloat("_Surface", (float)surfaceType); material.SetFloat("_Blend", (float)blendMode); if (oldShader.name.Equals("Standard (Specular setup)")) { material.SetFloat("_WorkflowMode", (float)LitGUI.WorkflowMode.Specular); Texture texture = material.GetTexture("_SpecGlossMap"); if (texture != null) material.SetTexture("_MetallicSpecGlossMap", texture); } else { material.SetFloat("_WorkflowMode", (float)LitGUI.WorkflowMode.Metallic); Texture texture = material.GetTexture("_MetallicGlossMap"); if (texture != null) material.SetTexture("_MetallicSpecGlossMap", texture); } MaterialChanged(material); } } } 


الآن دعونا ننظر إلى الدواخل من تظليل.

أول شيء يجب الانتباه إليه هو أنه لا يوجد سوى خمس تمريرات في التظليل. دعنا نتناولها قليلاً:

  1. ForwardLit: تمرير إلى الأمام ، وهنا نعتبر الضوء ، PBR والضباب.
  2. ShadowCaster: هنا هو حساب الظلال.
  3. DepthOnly: العمق (Z-Buffer).
  4. الفوقية: ضوء خبز (lightmaps).
  5. Lightweight2D: العفاريت واجهة المستخدم.

علاوة على ذلك ، لدى Unity عدة برامج تجميع تظليل مختلفة ومقاطع متقاطعة. يتطلب SRP HLSLcc. في الأنظمة الأساسية التي تستخدم API OpenGL ES للرسومات (مثل Android) ، لا يتم استخدام HLSLcc افتراضيًا.

لذلك ، نجبرها على الاتصال:

 #pragma prefer_hlslcc gles 

لكن DirectX 9 غير مدعوم ، لذا قم بتعطيله بالقوة:

 #pragma exclude_renderers d3d11_9x 

من حيث كتابة الكود نفسه ، لم يتغير أي شيء باستثناء أننا نكتب الآن ليس في CG ، ولكن في HLSL الخالص ، وبالتالي فإن نص برنامج التظليل سيبدو كما يلي:

 HLSLPROGRAM ... ENDHLSL 

- _Time , _ScreenParams _WorldSpaceCameraPos . , UnityCG.cginc . , , UnityObjectToClipPos(POSITION) TransformWorldToHClip(POSITION) , — UNITY_APPLY_FOG(fogCoord, color) MixFog(color, fogCoord) .

, Core.hlsl:
٪ localappdata٪ \ الوحدة \ ذاكرة التخزين المؤقت \ الحزم \ package.unity.com \ com.unity.render-pipelines.lightweight @ (إصدار LWRP) \ ShaderLibrary \ Core.hlsl

يمكننا العثور على قائمة كاملة من الميزات المتاحة.

تجدر الإشارة أيضًا إلى وجود مخازن مؤقتة (CBUFFER) و UnityPerMaterial. تستخدم المخازن المؤقتة الثابتة لتخزين البيانات التي نادراً ما تتغير على وحدة معالجة الرسومات ، على التوالي ، يمكن استخدامها لتخزين متغيرات التظليل. للقيام بذلك ، ما عليك سوى الاتصال بوحدات الماكرو
CBUFFER_START و CBUFFER_END :

 CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; half4 _BaseColor; half4 _SpecColor; half4 _EmissionColor; half _Cutoff; half _Smoothness; half _Metallic; half _BumpScale; half _OcclusionStrength; CBUFFER_END 

يتم الإعلان عن المتغيرات العامة أو المتغيرات المحددة بشكل بارز (من الكود أو الرسوم المتحركة ، على سبيل المثال) بالطريقة القديمة داخل جسم برنامج تظليل.

يستخدم LWRP نوعين من المخازن المؤقتة الثابتة - UnityPerObject و UnityPerMaterial . يتم ربط هذه المخازن المؤقتة مرة واحدة بحيث يمكن استخدامها أثناء التقديم. بمعنى تقريبي ، هذا يعني أنه أثناء العرض ، لن يتم إعادة تعزيز المخازن المؤقتة الثابتة أو لن يتم استدعاء setpass للمواد. يكون ذلك مفيدًا عندما تشترك تظليلات متعددة في نفس المخزن المؤقت الثابت ، حيث يمكن لـ LWRP تعبئة مواد مختلفة لهذا الغرض.

في الواقع ، إذا قمت بدراسة بنية التظليل بعناية ، يمكنك أن تجد أن معظم البيانات القياسية تستخدم فقط مخازن مؤقتة ثابتة في كل مكان.

بمزيد من التفصيل ، حول جميع الاختلافات ، ولكن باللغة الإنجليزية ، يمكنك قراءة هنا .

بالمناسبة ، إذا نظرت عن قرب إلى SurfaceData:
 SurfaceData surfaceData; 

قد تجد أن هذا هو PBR Master العزيزة من ShaderGraph .

مثال



لذا ، أصبحت أيدينا الآن غير مقيدة تمامًا ، مما يعني أن الوقت قد حان
لترتيب ملفوف! دعنا نضيف Vertex Displacement و Dissolve Effect كمثال ، والسماح للباقي بالرقص. من المريح جدًا أن تكون جميع التمريرات أمام أعيننا ويمكننا تعديل كل شيء بشكل شامل. دعونا وصف الخصائص:

LVRP_TextShaders_2020-01-20_21-08-42.gif





 Properties { ... _DissolveMap("Dissolve Map", 2D) = "white" {} _DissolveFactor("Dissolve Factor", Range(0, 1)) = 0.0 _DissolveWidth("Dissolve Width", Range(0, 1)) = 0.0 [HDR]_DissolveColor("Color", Color) = (1,1,0) } 

والتي ستظهر بلا شك في علامة التبويب الخاصة بنا والحبيبة في المفتش: إضافة المتغيرات:
2020-01-20_22-55-14.png



 CBUFFER_START(UnityPerMaterial) ... float4 _DissolveMap_ST; //    _DissolveMap CBUFFER_END TEXTURE2D(_DissolveMap); SAMPLER(sampler_DissolveMap); float _DissolveFactor; float _DissolveWidth; float4 _DissolveColor; 

أولاً ، أرسل الهندسة إلى ذهول مخمور:

 Varyings LitPassVertex(Attributes input) { ... input.positionOS.xyz += normalize(input.positionOS.xyz) * sin(input.positionOS.x) * sin(_Time.x * 100); ... } 

ثم الظل:
 Varyings ShadowPassVertex(Attributes input) { ... input.positionOS.xyz += normalize(input.positionOS.xyz) * sin(input.positionOS.x) * sin(_Time.x * 100); ... } 

عمق:

 Varyings DepthOnlyVertex(Attributes input) { ... input.position.xyz += normalize(input.position.xyz) * sin(input.position.x) * sin(_Time.x * 100); ... } 

حسنًا ، قم الآن بحل الوقت والحركة:

 half4 LitPassFragment(Varyings input) : SV_Target { ... // UV   input.uv += _Time.x * 10; //     Dissolve  float4 mask = SAMPLE_TEXTURE2D(_DissolveMap, sampler_DissolveMap, input.uv); if (mask.r > _DissolveFactor) discard; //  bool outline = mask.r > _DissolveFactor - _DissolveWidth; //    surfaceData.emission *= outline * _DissolveColor; //,    PBR-  half4 color = LightweightFragmentPBR(inputData, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha); //      color *= lerp(1, _DissolveColor, outline); ... } 

يمكنك أيضًا إدخال Dissolve في الظل ، ثم بنقرة من الرسغ ، سيكون لدينا الظل الصحيح ، وهو أمر صعب للغاية تحقيقه في Shader Graph ، وهنا فقط بضعة أسطر من التعليمات البرمجية.

 half4 ShadowPassFragment(Varyings input) : SV_TARGET { ... float4 mask = SAMPLE_TEXTURE2D(_DissolveMap, sampler_DissolveMap, input.uv); if (mask.r > _DissolveFactor) discard; ... } 

حسنا ، رمز التظليل النهائي:

SimpleDissolve
 Shader "TheProxor/LWRP/Dissolve + Vertex Offset" { Properties { // Specular vs Metallic workflow [HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0 [MainColor][HideInInspector] _BaseColor("Color", Color) = (0.5,0.5,0.5,1) [MainTexture][HideInInspector] _BaseMap("Albedo", 2D) = "white" {} [HideInInspector]_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 [HideInInspector]_Smoothness("Smoothness", Range(0.0, 1.0)) = 0.5 [HideInInspector]_GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 [HideInInspector]_SmoothnessTextureChannel("Smoothness texture channel", Float) = 0 [Gamma][HideInInspector] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 [HideInInspector]_MetallicGlossMap("Metallic", 2D) = "white" {} [HideInInspector]_SpecColor("Specular", Color) = (0.2, 0.2, 0.2) [HideInInspector]_SpecGlossMap("Specular", 2D) = "white" {} [HideInInspector][ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 [HideInInspector][ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0 [HideInInspector]_BumpScale("Scale", Float) = 1.0 [HideInInspector]_BumpMap("Normal Map", 2D) = "bump" {} [HideInInspector]_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 [HideInInspector]_OcclusionMap("Occlusion", 2D) = "white" {} [HDR][HideInInspector]_EmissionColor("Color", Color) = (0,0,0) [HideInInspector]_EmissionMap("Emission", 2D) = "white" {} // Blending state [HideInInspector] _Surface("__surface", Float) = 0.0 [HideInInspector] _Blend("__blend", Float) = 0.0 [HideInInspector] _AlphaClip("__clip", Float) = 0.0 [HideInInspector] _SrcBlend("__src", Float) = 1.0 [HideInInspector] _DstBlend("__dst", Float) = 0.0 [HideInInspector] _ZWrite("__zw", Float) = 1.0 [HideInInspector] _Cull("__cull", Float) = 2.0 [HideInInspector]_ReceiveShadows("Receive Shadows", Float) = 1.0 // Editmode props [HideInInspector] _QueueOffset("Queue offset", Float) = 0.0 // ObsoleteProperties [HideInInspector] _MainTex("BaseMap", 2D) = "white" {} [HideInInspector] _Color("Base Color", Color) = (0.5, 0.5, 0.5, 1) [HideInInspector] _GlossMapScale("Smoothness", Float) = 0.0 [HideInInspector] _Glossiness("Smoothness", Float) = 0.0 [HideInInspector] _GlossyReflections("EnvironmentReflections", Float) = 0.0 // _DissolveMap("Dissolve Map", 2D) = "white" {} _DissolveFactor("Dissolve Factor", Range(0, 1)) = 0.0 _DissolveWidth("Dissolve Width", Range(0, 1)) = 0.0 [HDR]_DissolveColor("Color", Color) = (1,1,0) } SubShader { // Lightweight Pipeline tag is required. If Lightweight render pipeline is not set in the graphics settings // this Subshader will fail. One can add a subshader below or fallback to Standard built-in to make this // material work with both Lightweight Render Pipeline and Builtin Unity Pipeline Tags{"RenderType" = "Opaque" "RenderPipeline" = "LightweightPipeline" "IgnoreProjector" = "True"} LOD 300 // ------------------------------------------------------------------ // Forward pass. Shades all light in a single pass. GI + emission + Fog Pass { // Lightmode matches the ShaderPassName set in LightweightRenderPipeline.cs. SRPDefaultUnlit and passes with // no LightMode tag are also rendered by Lightweight Render Pipeline Name "ForwardLit" Tags{"LightMode" = "LightweightForward"} Blend[_SrcBlend][_DstBlend] ZWrite[_ZWrite] Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard SRP library // All shaders must be compiled with HLSLcc and currently only gles is not using HLSLcc by default #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 // ------------------------------------- // Material Keywords #pragma shader_feature _NORMALMAP #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICSPECGLOSSMAP #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _OCCLUSIONMAP #pragma shader_feature _SPECULARHIGHLIGHTS_OFF #pragma shader_feature _ENVIRONMENTREFLECTIONS_OFF #pragma shader_feature _SPECULAR_SETUP #pragma shader_feature _RECEIVE_SHADOWS_OFF // ------------------------------------- // Lightweight Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile _ _SHADOWS_SOFT #pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE // ------------------------------------- // Unity defined keywords #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ LIGHTMAP_ON #pragma multi_compile_fog //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #pragma vertex LitPassVertex #pragma fragment LitPassFragment #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/SurfaceInput.hlsl" #ifdef _SPECULAR_SETUP #define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv) #else #define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv) #endif struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; float2 texcoord : TEXCOORD0; float2 lightmapUV : TEXCOORD1; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float2 uv : TEXCOORD0; DECLARE_LIGHTMAP_OR_SH(lightmapUV, vertexSH, 1); #ifdef _ADDITIONAL_LIGHTS float3 positionWS : TEXCOORD2; #endif #ifdef _NORMALMAP half4 normalWS : TEXCOORD3; // xyz: normal, w: viewDir.x half4 tangentWS : TEXCOORD4; // xyz: tangent, w: viewDir.y half4 bitangentWS : TEXCOORD5; // xyz: bitangent, w: viewDir.z #else half3 normalWS : TEXCOORD3; half3 viewDirWS : TEXCOORD4; #endif half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light #ifdef _MAIN_LIGHT_SHADOWS float4 shadowCoord : TEXCOORD7; #endif float4 positionCS : SV_POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO float3 uvDissolve : TEXCOORD8; }; CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; half4 _BaseColor; half4 _SpecColor; half4 _EmissionColor; half _Cutoff; half _Smoothness; half _Metallic; half _BumpScale; half _OcclusionStrength; float4 _DissolveMap_ST; //    _DissolveMap CBUFFER_END TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap); TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap); TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap); TEXTURE2D(_DissolveMap); SAMPLER(sampler_DissolveMap); float _DissolveFactor; float _DissolveWidth; float4 _DissolveColor; half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha) { half4 specGloss; #ifdef _METALLICSPECGLOSSMAP specGloss = SAMPLE_METALLICSPECULAR(uv); #ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A specGloss.a = albedoAlpha * _Smoothness; #else specGloss.a *= _Smoothness; #endif #else // _METALLICSPECGLOSSMAP #if _SPECULAR_SETUP specGloss.rgb = _SpecColor.rgb; #else specGloss.rgb = _Metallic.rrr; #endif #ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A specGloss.a = albedoAlpha * _Smoothness; #else specGloss.a = _Smoothness; #endif #endif return specGloss; } half SampleOcclusion(float2 uv) { #ifdef _OCCLUSIONMAP // TODO: Controls things like these by exposing SHADER_QUALITY levels (low, medium, high) #if defined(SHADER_API_GLES) return SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g; #else half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g; return LerpWhiteTo(occ, _OcclusionStrength); #endif #else return 1.0; #endif } inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData) { half4 albedoAlpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv); // half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)); outSurfaceData.alpha = Alpha(albedoAlpha.a, _BaseColor, _Cutoff); half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a); outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb; #if _SPECULAR_SETUP outSurfaceData.metallic = 1.0h; outSurfaceData.specular = specGloss.rgb; #else outSurfaceData.metallic = specGloss.r; outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h); #endif outSurfaceData.smoothness = specGloss.a; outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale); outSurfaceData.occlusion = SampleOcclusion(uv); outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap)); // outSurfaceData.emission = _EmissionColor.rgb * SAMPLE_TEXTURE2D(_EmissionMap, sampler_EmissionMap, uv); } void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData) { inputData = (InputData)0; #ifdef _ADDITIONAL_LIGHTS inputData.positionWS = input.positionWS; #endif #ifdef _NORMALMAP half3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w); inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)); #else half3 viewDirWS = input.viewDirWS; inputData.normalWS = input.normalWS; #endif inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS); viewDirWS = SafeNormalize(viewDirWS); inputData.viewDirectionWS = viewDirWS; #if defined(_MAIN_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF) inputData.shadowCoord = input.shadowCoord; #else inputData.shadowCoord = float4(0, 0, 0, 0); #endif inputData.fogCoord = input.fogFactorAndVertexLight.x; inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS); } /////////////////////////////////////////////////////////////////////////////// // Vertex and Fragment functions // /////////////////////////////////////////////////////////////////////////////// //Standard (Physically Based) shader Varyings LitPassVertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_TRANSFER_INSTANCE_ID(input, output); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); input.positionOS.xyz += sin(input.positionOS.x) * sin(_Time.x * 100); VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS); half3 viewDirWS = GetCameraPositionWS() - vertexInput.positionWS; half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS); half fogFactor = ComputeFogFactor(vertexInput.positionCS.z); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); #ifdef _NORMALMAP output.normalWS = half4(normalInput.normalWS, viewDirWS.x); output.tangentWS = half4(normalInput.tangentWS, viewDirWS.y); output.bitangentWS = half4(normalInput.bitangentWS, viewDirWS.z); #else output.normalWS = NormalizeNormalPerVertex(normalInput.normalWS); output.viewDirWS = viewDirWS; #endif OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV); OUTPUT_SH(output.normalWS.xyz, output.vertexSH); output.fogFactorAndVertexLight = half4(fogFactor, vertexLight); #ifdef _ADDITIONAL_LIGHTS output.positionWS = vertexInput.positionWS; #endif #if defined(_MAIN_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF) output.shadowCoord = GetShadowCoord(vertexInput); #endif output.positionCS = vertexInput.positionCS; return output; } // Used in Standard (Physically Based) shader half4 LitPassFragment(Varyings input) : SV_Target { input.uv += _Time.x * 10; UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); SurfaceData surfaceData; InitializeStandardLitSurfaceData(input.uv, surfaceData); InputData inputData; InitializeInputData(input, surfaceData.normalTS, inputData); float4 mask = SAMPLE_TEXTURE2D(_DissolveMap, sampler_DissolveMap, input.uv); if (mask.r > _DissolveFactor) discard; bool outline = mask.r > _DissolveFactor - _DissolveWidth; surfaceData.emission *= outline * _DissolveColor; half4 color = LightweightFragmentPBR(inputData, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha); color *= lerp(1, _DissolveColor, outline); color.rgb = MixFog(color.rgb, inputData.fogCoord); return color; } ENDHLSL } // Pass { Name "ShadowCaster" Tags{"LightMode" = "ShadowCaster"} ZWrite On ZTest LEqual Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 // ------------------------------------- // Material Keywords #pragma shader_feature _ALPHATEST_ON //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma vertex ShadowPassVertex #pragma fragment ShadowPassFragment #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Shadows.hlsl" float3 _LightDirection; struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float2 uv : TEXCOORD0; float4 positionCS : SV_POSITION; }; CBUFFER_START(UnityPerMaterial) float4 _DissolveMap_ST; //    _DissolveMap float _DissolveFactor; CBUFFER_END TEXTURE2D(_DissolveMap); SAMPLER(sampler_DissolveMap); float4 GetShadowPositionHClip(Attributes input) { float3 positionWS = TransformObjectToWorld(input.positionOS.xyz); float3 normalWS = TransformObjectToWorldNormal(input.normalOS); float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, _LightDirection)); #if UNITY_REVERSED_Z positionCS.z = min(positionCS.z, positionCS.w * UNITY_NEAR_CLIP_VALUE); #else positionCS.z = max(positionCS.z, positionCS.w * UNITY_NEAR_CLIP_VALUE); #endif return positionCS; } Varyings ShadowPassVertex(Attributes input) { Varyings output; input.positionOS.xyz += normalize(input.positionOS.xyz) * sin(input.positionOS.x) * sin(_Time.x * 100); UNITY_SETUP_INSTANCE_ID(input); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); output.positionCS = GetShadowPositionHClip(input); return output; } half4 ShadowPassFragment(Varyings input) : SV_TARGET { float4 mask = SAMPLE_TEXTURE2D(_DissolveMap, sampler_DissolveMap, input.uv); if (mask.r > _DissolveFactor) discard; Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); return 0; } ENDHLSL } Pass { Name "DepthOnly" Tags{"LightMode" = "DepthOnly"} ZWrite On ColorMask 0 Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma target 2.0 #pragma vertex DepthOnlyVertex #pragma fragment DepthOnlyFragment // ------------------------------------- // Material Keywords #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl" #ifndef LIGHTWEIGHT_DEPTH_ONLY_PASS_INCLUDED #define LIGHTWEIGHT_DEPTH_ONLY_PASS_INCLUDED struct Attributes { float4 position : POSITION; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float2 uv : TEXCOORD0; float4 positionCS : SV_POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; Varyings DepthOnlyVertex(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); input.position.xyz += normalize(input.position.xyz) * sin(input.position.x) * sin(_Time.x * 100); output.uv = TRANSFORM_TEX(input.texcoord, _BaseMap); output.positionCS = TransformObjectToHClip(input.position.xyz); return output; } half4 DepthOnlyFragment(Varyings input) : SV_TARGET { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); return 0; } #endif ENDHLSL } // Pass { Name "Meta" Tags{"LightMode" = "Meta"} Cull Off HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma vertex LightweightVertexMeta #pragma fragment LightweightFragmentMeta #pragma shader_feature _SPECULAR_SETUP #pragma shader_feature _EMISSION #pragma shader_feature _METALLICSPECGLOSSMAP #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _SPECGLOSSMAP #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/MetaInput.hlsl" #ifndef LIGHTWEIGHT_LIT_META_PASS_INCLUDED #define LIGHTWEIGHT_LIT_META_PASS_INCLUDED Varyings LightweightVertexMeta(Attributes input) { Varyings output; output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2, unity_LightmapST, unity_DynamicLightmapST); output.uv = TRANSFORM_TEX(input.uv0, _BaseMap); return output; } half4 LightweightFragmentMeta(Varyings input) : SV_Target { SurfaceData surfaceData; InitializeStandardLitSurfaceData(input.uv, surfaceData); BRDFData brdfData; InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData); MetaInput metaInput; metaInput.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5; metaInput.SpecularColor = surfaceData.specular; metaInput.Emission = surfaceData.emission; return MetaFragment(metaInput); } #endif ENDHLSL } Pass { Name "Lightweight2D" Tags{ "LightMode" = "Lightweight2D" } Blend[_SrcBlend][_DstBlend] ZWrite[_ZWrite] Cull[_Cull] HLSLPROGRAM // Required to compile gles 2.0 with standard srp library #pragma prefer_hlslcc gles #pragma exclude_renderers d3d11_9x #pragma vertex vert #pragma fragment frag #pragma shader_feature _ALPHATEST_ON #pragma shader_feature _ALPHAPREMULTIPLY_ON #include "Packages/com.unity.render-pipelines.lightweight/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.lightweight/Shaders/Utils/Lightweight2D.hlsl" ENDHLSL } } FallBack "Hidden/InternalErrorShader" CustomEditor "UnityEditor.Rendering.LWRP.ShaderGUI.LitShaderEditor" } 

استنتاج


حسنًا ، حان الوقت للتقييم. كما أصبح واضحًا ، في LWRP ، من الممكن وحتى الضروري كتابة تظليل مع الكود ، لأنه يحرر يديك بشكل كبير ، مما يساعد على كتابة أشياء رائعة دون عكازات ، على سبيل المثال ، نظام الإضاءة لديك. بالطبع ، لا يمكن مقارنتها مع Standard Surface Shader المألوف والمريح ، ولكن ربما سأحصل في يوم من الأيام على الكتابة التماثلية المريحة لـ LWRP و HDRP ، ولكن المزيد حول ذلك في وقت آخر.

روابط مفيدة:

مستودع مع جميع المواد من المادة
وجدت هذا أثناء إعداد المواد ، وثائق غير رسمية وثائق
LWRP

Source: https://habr.com/ru/post/ar485018/


All Articles