找回密码
 立即注册
查看: 244|回复: 0

《Unity Shader 入门精要》从Bulit-in 到URP (HLSL)Chapter14.1-卡通风格的衬着

[复制链接]
发表于 2024-7-15 18:17 | 显示全部楼层 |阅读模式
前言:
已经进入“高级篇”啦,但愿大师多多撑持,多多存眷,这将对我发生非常愉悦的正反馈~

“《Unity Shader 入门精要》从Bulit-in 到URP”是一个辅佐Unity Shader学习者以冯乐乐女神《Unity Shader 入门精要》为基础学习用HLSL语言编写URP着色器的案例教学系列。

作者自学能力有限,抛砖引玉,如有建议和问题请各位大佬和同仁交流斧正。
Bulit-in版:
  1. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
  2. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  3. Shader ”Unity Shaders Book/Chapter 14/Toon Shading” {
  4.         Properties {
  5.                 _Color (”Color Tint”, Color) = (1, 1, 1, 1)
  6.                 _MainTex (”Main Tex”, 2D) = ”white” {}
  7.                 _Ramp (”Ramp Texture”, 2D) = ”white” {}
  8.                 _Outline (”Outline”, Range(0, 1)) = 0.1
  9.                 _OutlineColor (”Outline Color”, Color) = (0, 0, 0, 1)
  10.                 _Specular (”Specular”, Color) = (1, 1, 1, 1)
  11.                 _SpecularScale (”Specular Scale”, Range(0, 0.1)) = 0.01
  12.         }
  13.     SubShader {
  14.                 Tags { ”RenderType”=”Opaque” ”Queue”=”Geometry”}
  15.                
  16.                 Pass {
  17.                         NAME ”OUTLINE”
  18.                        
  19.                         Cull Front
  20.                        
  21.                         CGPROGRAM
  22.                        
  23.                         #pragma vertex vert
  24.                         #pragma fragment frag
  25.                        
  26.                         #include ”UnityCG.cginc”
  27.                        
  28.                         float _Outline;
  29.                         fixed4 _OutlineColor;
  30.                        
  31.                         struct a2v {
  32.                                 float4 vertex : POSITION;
  33.                                 float3 normal : NORMAL;
  34.                         };
  35.                        
  36.                         struct v2f {
  37.                             float4 pos : SV_POSITION;
  38.                         };
  39.                        
  40.                         v2f vert (a2v v) {
  41.                                 v2f o;
  42.                                
  43.                                 float4 pos = mul(UNITY_MATRIX_MV, v.vertex);
  44.                                 float3 normal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);  
  45.                                 normal.z = -0.5;
  46.                                 pos = pos + float4(normalize(normal), 0) * _Outline;
  47.                                 o.pos = mul(UNITY_MATRIX_P, pos);
  48.                                
  49.                                 return o;
  50.                         }
  51.                        
  52.                         float4 frag(v2f i) : SV_Target {
  53.                                 return float4(_OutlineColor.rgb, 1);               
  54.                         }
  55.                        
  56.                         ENDCG
  57.                 }
  58.                
  59.                 Pass {
  60.                         Tags { ”LightMode”=”ForwardBase” }
  61.                        
  62.                         Cull Back
  63.                
  64.                         CGPROGRAM
  65.                
  66.                         #pragma vertex vert
  67.                         #pragma fragment frag
  68.                        
  69.                         #pragma multi_compile_fwdbase
  70.                
  71.                         #include ”UnityCG.cginc”
  72.                         #include ”Lighting.cginc”
  73.                         #include ”AutoLight.cginc”
  74.                         #include ”UnityShaderVariables.cginc”
  75.                        
  76.                         fixed4 _Color;
  77.                         sampler2D _MainTex;
  78.                         float4 _MainTex_ST;
  79.                         sampler2D _Ramp;
  80.                         fixed4 _Specular;
  81.                         fixed _SpecularScale;
  82.                
  83.                         struct a2v {
  84.                                 float4 vertex : POSITION;
  85.                                 float3 normal : NORMAL;
  86.                                 float4 texcoord : TEXCOORD0;
  87.                                 float4 tangent : TANGENT;
  88.                         };
  89.                
  90.                         struct v2f {
  91.                                 float4 pos : POSITION;
  92.                                 float2 uv : TEXCOORD0;
  93.                                 float3 worldNormal : TEXCOORD1;
  94.                                 float3 worldPos : TEXCOORD2;
  95.                                 SHADOW_COORDS(3)
  96.                         };
  97.                        
  98.                         v2f vert (a2v v) {
  99.                                 v2f o;
  100.                                
  101.                                 o.pos = UnityObjectToClipPos( v.vertex);
  102.                                 o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
  103.                                 o.worldNormal  = UnityObjectToWorldNormal(v.normal);
  104.                                 o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  105.                                
  106.                                 TRANSFER_SHADOW(o);
  107.                                
  108.                                 return o;
  109.                         }
  110.                        
  111.                         float4 frag(v2f i) : SV_Target {
  112.                                 fixed3 worldNormal = normalize(i.worldNormal);
  113.                                 fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
  114.                                 fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
  115.                                 fixed3 worldHalfDir = normalize(worldLightDir + worldViewDir);
  116.                                
  117.                                 fixed4 c = tex2D (_MainTex, i.uv);
  118.                                 fixed3 albedo = c.rgb * _Color.rgb;
  119.                                
  120.                                 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
  121.                                
  122.                                 UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
  123.                                
  124.                                 fixed diff =  dot(worldNormal, worldLightDir);
  125.                                 diff = (diff * 0.5 + 0.5) * atten;
  126.                                
  127.                                 fixed3 diffuse = _LightColor0.rgb * albedo * tex2D(_Ramp, float2(diff, diff)).rgb;
  128.                                
  129.                                 fixed spec = dot(worldNormal, worldHalfDir);
  130.                                 fixed w = fwidth(spec) * 2.0;
  131.                                 fixed3 specular = _Specular.rgb * lerp(0, 1, smoothstep(-w, w, spec + _SpecularScale - 1)) * step(0.0001, _SpecularScale);
  132.                                
  133.                                 return fixed4(ambient + diffuse + specular, 1.0);
  134.                         }
  135.                
  136.                         ENDCG
  137.                 }
  138.         }
  139.         FallBack ”Diffuse”
  140. }
复制代码
URP版:

Unity项目源码:
  1. Shader ”Unlit/Chapter14-ToonShading”
  2. {
  3.     Properties {
  4.                 _Color (”Color Tint”, Color) = (1, 1, 1, 1)
  5.                 _MainTex (”Main Tex”, 2D) = ”white” {}
  6.                 _Ramp (”Ramp Texture”, 2D) = ”white” {}
  7.                 _Outline (”Outline”, Range(0, 1)) = 0.1
  8.                 _OutlineColor (”Outline Color”, Color) = (0, 0, 0, 1)
  9.                 _Specular (”Specular”, Color) = (1, 1, 1, 1)
  10.                 _SpecularScale (”Specular Scale”, Range(0, 0.1)) = 0.01
  11.         }
  12.     SubShader
  13.     {
  14.         Tags {”RenderPipeline” = ”UniversalPipeline” ”RenderType”=”Opaque” ”Queue”=”Geometry”}
  15.         HLSLINCLUDE
  16.         #include ”Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl”
  17.                 #include ”Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl”
  18.         CBUFFER_START(UnityPerMaterial)
  19.             float _Outline;
  20.                         half4 _OutlineColor;
  21.             half4 _Color;
  22.                         float4 _MainTex_ST;
  23.                         half4 _Specular;
  24.                         half _SpecularScale;
  25.         CBUFFER_END
  26.         ENDHLSL
  27.         UsePass ”Universal Render Pipeline/Lit/ShadowCaster”
  28.                
  29.                 Pass {
  30.                         NAME ”OUTLINE”
  31.                        
  32.                         Cull Front
  33.                        
  34.                         HLSLPROGRAM
  35.                        
  36.                         #pragma vertex vert
  37.                         #pragma fragment frag
  38.                        
  39.                         struct a2v {
  40.                                 float4 vertex : POSITION;
  41.                                 float3 normal : NORMAL;
  42.                         };
  43.                        
  44.                         struct v2f {
  45.                             float4 pos : SV_POSITION;
  46.                         };
  47.                        
  48.                         v2f vert (a2v v) {
  49.                                 v2f o;
  50.                                
  51.                                 float4 pos = mul(UNITY_MATRIX_MV, v.vertex);
  52.                                 float3 normal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);  
  53.                 //把顶点法线转换到view空间
  54.                                 normal.z = -0.5;
  55.                                 pos = pos + float4(normalize(normal), 0) * _Outline;
  56.                 //在view空间完成顶点扩张
  57.                                 o.pos = mul(UNITY_MATRIX_P, pos);
  58.                                
  59.                                 return o;
  60.                         }
  61.                        
  62.                         float4 frag(v2f i) : SV_Target {
  63.                                 return float4(_OutlineColor.rgb, 1);               
  64.                         }
  65.                        
  66.                         ENDHLSL
  67.                 }
  68.                
  69.                 Pass {
  70.                         Tags { ”LightMode”=”UniversalForward” }
  71.                        
  72.                         Cull Back
  73.                
  74.                         HLSLPROGRAM
  75.                
  76.                         #pragma vertex vert
  77.                         #pragma fragment frag
  78.             TEXTURE2D(_MainTex);       SAMPLER(sampler_MainTex);
  79.             TEXTURE2D(_Ramp);       SAMPLER(sampler_Ramp);
  80.                
  81.                         struct a2v {
  82.                                 float4 vertex : POSITION;
  83.                                 float3 normal : NORMAL;
  84.                                 float4 texcoord : TEXCOORD0;
  85.                                 //float4 tangent : TANGENT;
  86.                         };
  87.                
  88.                         struct v2f {
  89.                                 float4 pos : POSITION;
  90.                                 float2 uv : TEXCOORD0;
  91.                                 float3 worldNormal : TEXCOORD1;
  92.                                 float3 worldPos : TEXCOORD2;
  93.                         };
  94.                        
  95.                         v2f vert (a2v v) {
  96.                                 v2f o;
  97.                                
  98.                 VertexPositionInputs positionInputs = GetVertexPositionInputs(v.vertex.xyz);
  99.                                 //o.pos = TransformObjectToHClip( v.vertex);
  100.                 o.pos = positionInputs.positionCS;
  101.                                 o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
  102.                                 o.worldNormal  = TransformObjectToWorldNormal(v.normal);
  103.                                 //o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  104.                                 o.worldPos = positionInputs.positionWS;
  105.                                
  106.                                 return o;
  107.                         }
  108.                        
  109.                         float4 frag(v2f i) : SV_Target {
  110.                                 Light mainLight = GetMainLight();
  111.                                 //获取光源信息的函数
  112.                 half3 worldLightDir = normalize(TransformObjectToWorldDir(mainLight.direction));
  113.                 //half3 worldNormal = normalize(i.worldNormal);
  114.                                 //half3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
  115.                                 half3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);
  116.                                 half3 worldHalfDir = normalize(worldLightDir + worldViewDir);
  117.                                
  118.                                 half4 c = SAMPLE_TEXTURE2D (_MainTex, sampler_MainTex, i.uv);
  119.                                 half3 albedo = c.rgb * _Color.rgb;
  120.                                
  121.                                 half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) * albedo;
  122.                 half atten = mainLight.distanceAttenuation;
  123.                                
  124.                                 //UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
  125.                                
  126.                                 half diff =  dot(i.worldNormal, worldLightDir);
  127.                                 diff = (diff * 0.5 + 0.5) * atten;
  128.                                
  129.                                 half3 diffuse = mainLight.color * albedo * SAMPLE_TEXTURE2D(_Ramp, sampler_Ramp, float2(diff, diff)).rgb;
  130.                                
  131.                                 half spec = dot(i.worldNormal, worldHalfDir);
  132.                                 half w = fwidth(spec) * 2.0;
  133.                 //此函数计算以下内容: abs (ddx (x) ) + abs (ddy (x) ),即相邻像素点该数值的变化度 。
  134.                                 half3 specular = mainLight.color * _Specular.rgb * lerp(0, 1, smoothstep(-w, w, spec + _SpecularScale - 1)) * step(0.0001, _SpecularScale);
  135.                                
  136.                                 return half4(ambient + diffuse + specular, 1.0);
  137.                         }
  138.                
  139.                         ENDHLSL
  140.                 }
  141.         }
  142.         FallBack ”Packages/com.unity.render-pipelines.universal/FallbackError”
  143. }
复制代码
效果图:




如有收获,请留下“存眷”和“附和”

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 16:05 , Processed in 0.102563 second(s), 28 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表