頭髮篇【2018.10.12】
阿新 • • 發佈:2018-12-15
帶菲尼爾的細貼圖
帶菲尼爾的細貼圖4pass的
不帶菲尼爾的細貼圖
帶菲尼爾的粗貼圖
不帶菲尼爾的粗貼圖
/*帶透明裁剪 深度寫入 陰影 菲尼爾立方體貼圖 Kajiaya 光照模型(光圈) */ Shader "Unlit/NewUnlitShader" { Properties { _Color("Color Tint", Color) = (1,1,1,1) _MainTex("MainTex", 2D) = "White" {} _Cutoff("Alpha Cutoff", Range(0,1)) = 0.5 //凹凸貼圖 _BumpMap("Normal Map",2D) = "bump"{} //整體透明度強弱 _AlphaScale("Alpha Scale",Range(0,1)) = 1 //法線紋理凹凸程度 _BumpScale("Bump Scale",Float) = 1.0 _Specular("Specular",Color) = (1,1,1,1) _Gloss("Gloss",Range(0,258)) = 1 //菲尼爾反射強度 _FresnelScale("Fresnel Scale",Range(0,1)) = 0.5 //反射顏色 _ReflectColor("Reflect Color",Color)=(1,1,1,1) //模擬反射的環境對映紋理 _Cubemap("Reflection Cubemap",Cube) = "_Skybox"{} } SubShader { Tags{ "Queue" = "AlphaTest" "IgnoreProject" = "True" "RenderType" = "TransparentCutout" } Pass { Tags{ "LightMode" = "ForwardBase" } //剔除前面 Cull Front //ZWrite off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "LIghting.cginc" #include "AutoLight.cginc" #include "UnityCG.cginc" fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; fixed _Cutoff; fixed _AlphaScale; sampler2D _BumpMap; float4 _BumpMap_ST; float _BumpScale; fixed4 _Specular; float _Gloss; fixed4 _ReflectColor; float _FresnelScale; samplerCUBE _Cubemap; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; //獲取切線 float4 tangent:TANGENT; }; struct v2f { float4 pos : SV_POSITION; float4 uv : TEXCOORD2; SHADOW_COORDS(3) float3 lightDir:TEXCOORD4; float3 viewDir:TEXCOORD5; float4 TtoW0 : TEXCOORD6; float4 TtoW1 : TEXCOORD7; float4 TtoW2 : TEXCOORD8; fixed3 worldRefl : TEXCOORD9; fixed3 worldViewDir : TEXCOORD1; }; v2f vert (a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv.xy = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw; o.uv.zw = v.texcoord.xy*_BumpMap_ST.xy + _BumpMap_ST.zw; float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); //切線 fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); //次法線 fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w; //o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); TANGENT_SPACE_ROTATION; o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz; o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz; o.worldViewDir = UnityWorldSpaceViewDir(worldPos); o.worldRefl = reflect(-o.worldViewDir, worldNormal); //切線,次法線,法線,位置 o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x); o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y); o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z); TRANSFER_SHADOW(o); return o; } //片元著色器 fixed4 frag (v2f i) : SV_Target { float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w); fixed3 tangentLightDir = normalize(i.lightDir); fixed3 tangentViewDir = normalize(i.viewDir); //凹凸貼圖 fixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv.zw)); //凹凸 bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump))); //利用tex2D對法線紋理_BumpMap進行取樣 fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw); fixed3 tangentNormal; //or mark the texture as "Normal map",ang use the built-in funciton(或者將紋理標記為“法線貼圖”,使用內建函式) tangentNormal = UnpackNormal(packedNormal); tangentNormal.xy *= _BumpScale; fixed3 worldLightDir = normalize(UnityWorldSpaceViewDir(worldPos)); fixed4 texColor = tex2D(_MainTex, i.uv); //透明度測試 clip(texColor.a - _Cutoff); fixed3 albedo = tex2D(_MainTex, i.uv).rgb*_Color.rgb; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; //fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(bump, worldLightDir)); //fixed3 diffuse = _LightColor0.rgb * albedo * sqrt(1. - abs(dot(tangentNormal.xyz, tangentLightDir.xyz))); fixed3 diffuse = _LightColor0.rgb * albedo * sqrt(1. - abs(lerp(0.25, 1.0, dot(tangentNormal.xyz, tangentLightDir.xyz)))); UNITY_LIGHT_ATTENUATION(atten, i, worldPos); fixed3 halfDir = normalize(tangentLightDir + tangentViewDir); //fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0, dot(tangentNormal, halfDir)), _Gloss); fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(sqrt(1 - abs(dot(tangentNormal, normalize(1 - tangentViewDir - tangentLightDir)))), _Gloss); //在世界空間中使用折射方向訪問立方體貼圖 fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb*_ReflectColor.rgb; //獲取歸一化的視角方向 //fixed3 worldViewDir = normalize(i.worldViewDir); i.worldViewDir = normalize(_WorldSpaceCameraPos.xyz - worldPos.xyz); //使用Schlick菲尼爾近似式計算fresnel變數 fixed fresnel = _FresnelScale + (1 - _FresnelScale)*pow(1 - dot(i.worldViewDir, bump), 5); return fixed4(ambient + lerp(diffuse, reflection, saturate(fresnel) + specular)*atten, texColor.a*_AlphaScale); //return fixed4(ambient + (lerp(diffuse, reflection, saturate(fresnel) + specular )* atten, texColor.a*_AlphaScale)); } ENDCG } Pass { Tags{ "LightMode" = "ForwardBase" } //剔除背面 Cull Back //ZWrite off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "LIghting.cginc" #include "AutoLight.cginc" #include "UnityCG.cginc" fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; fixed _Cutoff; fixed _AlphaScale; sampler2D _BumpMap; float4 _BumpMap_ST; float _BumpScale; fixed4 _Specular; float _Gloss; fixed4 _ReflectColor; float _FresnelScale; samplerCUBE _Cubemap; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; //獲取切線 float4 tangent:TANGENT; }; struct v2f { float4 pos : SV_POSITION; float4 uv : TEXCOORD2; SHADOW_COORDS(3) float3 lightDir:TEXCOORD4; float3 viewDir:TEXCOORD5; float4 TtoW0 : TEXCOORD6; float4 TtoW1 : TEXCOORD7; float4 TtoW2 : TEXCOORD8; fixed3 worldRefl : TEXCOORD9; fixed3 worldViewDir : TEXCOORD1; }; v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv.xy = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw; o.uv.zw = v.texcoord.xy*_BumpMap_ST.xy + _BumpMap_ST.zw; float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); //切線 fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); //次法線 fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w; //o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); TANGENT_SPACE_ROTATION; o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz; o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz; o.worldViewDir = UnityWorldSpaceViewDir(worldPos); o.worldRefl = reflect(-o.worldViewDir, worldNormal); //切線,次法線,法線,位置 o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x); o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y); o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z); TRANSFER_SHADOW(o); return o; } //片元著色器 fixed4 frag(v2f i) : SV_Target { float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w); fixed3 tangentLightDir = normalize(i.lightDir); fixed3 tangentViewDir = normalize(i.viewDir); //凹凸貼圖 fixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv.zw)); //凹凸 bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump))); //利用tex2D對法線紋理_BumpMap進行取樣 fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw); fixed3 tangentNormal; //or mark the texture as "Normal map",ang use the built-in funciton(或者將紋理標記為“法線貼圖”,使用內建函式) tangentNormal = UnpackNormal(packedNormal); tangentNormal.xy *= _BumpScale; fixed3 worldLightDir = normalize(UnityWorldSpaceViewDir(worldPos)); fixed4 texColor = tex2D(_MainTex, i.uv); //透明度測試 clip(texColor.a - _Cutoff); fixed3 albedo = tex2D(_MainTex, i.uv).rgb*_Color.rgb; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; //fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(bump, worldLightDir)); //fixed3 diffuse = _LightColor0.rgb * albedo * sqrt(1. - abs(dot(tangentNormal.xyz, tangentLightDir.xyz))); fixed3 diffuse = _LightColor0.rgb * albedo * sqrt(1. - abs(lerp(0.25, 1.0, dot(tangentNormal.xyz, tangentLightDir.xyz)))); UNITY_LIGHT_ATTENUATION(atten, i, worldPos); fixed3 halfDir = normalize(tangentLightDir + tangentViewDir); //fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0, dot(tangentNormal, halfDir)), _Gloss); fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(sqrt(1 - abs(dot(tangentNormal, normalize(1-tangentViewDir -tangentLightDir)))), _Gloss); //在世界空間中使用折射方向訪問立方體貼圖 fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb*_ReflectColor.rgb; //獲取歸一化的視角方向 //fixed3 worldViewDir = normalize(i.worldViewDir); i.worldViewDir = normalize(_WorldSpaceCameraPos.xyz - worldPos.xyz); //使用Schlick菲尼爾近似式計算fresnel變數 fixed fresnel = _FresnelScale + (1 - _FresnelScale)*pow(1 - dot(i.worldViewDir, bump), 5); return fixed4(ambient + lerp(diffuse, reflection, saturate(fresnel) + specular)*atten, texColor.a*_AlphaScale); //return fixed4(ambient + (lerp(diffuse, reflection, saturate(fresnel) + specular )* atten, texColor.a*_AlphaScale)); } ENDCG } } Fallback "Transparent/Cutout/VertexLit" }
/*帶透明裁剪 深度寫入 陰影 Kajiaya 光照模型(光圈) */ Shader "Unlit/HearTry" {Properties { _Color("Color Tint", Color) = (1,1,1,1) _MainTex("MainTex", 2D) = "White" {} _Cutoff("Alpha Cutoff", Range(0,1)) = 0.5 _BumpMap("Normal Map",2D) = "bump"{} //整體透明度強弱 _AlphaScale("Alpha Scale",Range(0,1)) = 1 //法線紋理凹凸程度 _BumpScale("Bump Scale",Float) = 1.0 _Specular("Specular",Color) = (1,1,1,1) _Gloss("Gloss",Range(0,256)) = 20 } SubShader { Tags{ "Queue" = "AlphaTest" "IgnoreProject" = "True" "RenderType" = "TransparentCutout" } Pass { Tags{ "LightMode" = "ForwardBase" } //剔除前面 Cull Front //ZWrite off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "LIghting.cginc" #include "AutoLight.cginc" fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; fixed _Cutoff; fixed _AlphaScale; sampler2D _BumpMap; float4 _BumpMap_ST; float _BumpScale; fixed4 _Specular; float _Gloss; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 tangent:TANGENT; }; struct v2f { float4 pos : SV_POSITION; float3 worldNormal : TEXCOORD0; float3 worldPos : TEXCOORD1; float4 uv : TEXCOORD2; SHADOW_COORDS(3) float3 lightDir:TEXCOORD4; float3 viewDir:TEXCOORD5; }; v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv.xy = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw; o.uv.zw = v.texcoord.xy*_BumpMap_ST.xy + _BumpMap_ST.zw; o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; //o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); TANGENT_SPACE_ROTATION; o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz; o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz; TRANSFER_SHADOW(o); return o; } fixed4 frag(v2f i) : SV_Target { fixed3 tangentLightDir = normalize(i.lightDir); fixed3 tangentViewDir = normalize(i.viewDir); //利用tex2D對法線紋理_BumpMap進行取樣 fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw); fixed3 tangentNormal; //or mark the texture as "Normal map",ang use the built-in funciton(或者將紋理標記為“法線貼圖”,使用內建函式) tangentNormal = UnpackNormal(packedNormal); tangentNormal.xy *= _BumpScale; fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed4 texColor = tex2D(_MainTex, i.uv); //透明度測試 clip(texColor.a - _Cutoff); fixed3 albedo = tex2D(_MainTex, i.uv).rgb*_Color.rgb; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; //fixed3 diffuse = _LightColor0.rgb * albedo * saturate(dot(worldNormal, worldLightDir)); //fixed3 diffuse = _LightColor0.rgb * albedo * sqrt(1. - abs(dot(tangentNormal.xyz, tangentLightDir.xyz))); fixed3 diffuse = _LightColor0.rgb * albedo * sqrt(1. - abs(lerp(0.25,1.0,dot(tangentNormal.xyz, tangentLightDir.xyz)))); UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); fixed3 halfDir = normalize(tangentLightDir + tangentViewDir); //fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0, dot(tangentNormal, halfDir)), _Gloss); fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(sqrt(1 - abs(dot(tangentNormal, normalize(1 - tangentViewDir - tangentLightDir)))), _Gloss); return fixed4(ambient + (diffuse + specular)* atten, texColor.a*_AlphaScale); } ENDCG } Pass { Tags{ "LightMode" = "ForwardBase" } //剔除背面 Cull Back //ZWrite off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "LIghting.cginc" #include "AutoLight.cginc" fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; fixed _Cutoff; fixed _AlphaScale; sampler2D _BumpMap; float4 _BumpMap_ST; float _BumpScale; fixed4 _Specular; float _Gloss; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 tangent:TANGENT; }; struct v2f { float4 pos : SV_POSITION; float3 worldNormal : TEXCOORD0; float3 worldPos : TEXCOORD1; float4 uv : TEXCOORD2; SHADOW_COORDS(3) float3 lightDir:TEXCOORD4; float3 viewDir:TEXCOORD5; }; v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv.xy = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw; o.uv.zw = v.texcoord.xy*_BumpMap_ST.xy + _BumpMap_ST.zw; o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; //o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); TANGENT_SPACE_ROTATION; o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz; o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz; TRANSFER_SHADOW(o); return o; } fixed4 frag(v2f i) : SV_Target { fixed3 tangentLightDir = normalize(i.lightDir); fixed3 tangentViewDir = normalize(i.viewDir); //利用tex2D對法線紋理_BumpMap進行取樣 fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw); fixed3 tangentNormal; //or mark the texture as "Normal map",ang use the built-in funciton(或者將紋理標記為“法線貼圖”,使用內建函式) tangentNormal = UnpackNormal(packedNormal); tangentNormal.xy *= _BumpScale; fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed4 texColor = tex2D(_MainTex, i.uv); //透明度測試 clip(texColor.a - _Cutoff); fixed3 albedo = tex2D(_MainTex, i.uv).rgb*_Color.rgb; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; //fixed3 diffuse = _LightColor0.rgb * albedo * saturate(dot(worldNormal, worldLightDir)); //fixed3 diffuse = _LightColor0.rgb * albedo * sqrt(1. - abs(dot(tangentNormal.xyz, tangentLightDir.xyz))); fixed3 diffuse = _LightColor0.rgb * albedo * sqrt(1. - abs(lerp(0.25, 1.0, dot(tangentNormal.xyz, tangentLightDir.xyz)))); UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); fixed3 halfDir = normalize(tangentLightDir + tangentViewDir); //fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0, dot(tangentNormal, halfDir)), _Gloss); fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(sqrt(1 - abs(dot(tangentNormal, normalize(1 - tangentViewDir - tangentLightDir)))), _Gloss); return fixed4(ambient + (diffuse + specular)* atten, texColor.a*_AlphaScale); } ENDCG } } Fallback "Transparent/Cutout/VertexLit" }
上一天沒思路,昨天大姨媽請假,今天才來繼續弄,今天找了一個頭發高光是光圈的效果的高光公式,修改了一點引數讓光圈是我想要的位置,但是整體看來還是不行,沒有質感,而且帶菲尼爾會過爆,印象高光效果,不帶還有點過硬,下週試試把菲尼爾去了,用邊緣檢測的方法試試,異性就先不搞了,男生頭髮看不出來,女生闆闆整整的頭髮效果才能看出來,
參考文章: