本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。
这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。
========================================== 分割线 ==========================================
布料(Cloth)是另一种非常常见的着色需求,在很多实时游戏中都需要它来实现更真实的交互体验。它涉及到如何让布料的纤维合适地分散整个表面的光照,使它看起来像布料一样。布料的渲染非常依赖视角的变化,因此我们将学习一些新的技巧来模拟光扫射到布料上的效果,并且那些细小的纤维还能产生与众不同的边缘光照效果。
这篇将会介绍两种新的概念:细节法线贴图(Detail normal maps)和细节贴图(Detail textures)。通过把这两种法线贴图结合到一起,我们可以得到一种更高层次的细节表现,并且可以存储在一张2048*2048的贴图中。这种技术可以帮助我们模拟表面那种非常细微层次的凹凸不平的感觉,以此来分散整个表面的高光反射。
下面显示了本节最终得到的布料着色器效果:
这个Shader需要结合3种不同类型的贴图来模拟布料效果:
Properties { _MainTint ("Global Tint", Color) = (1,1,1,1) _BumpMap ("Normal Map", 2D) = "bump" {} _DetailBump ("Detail Normal Map", 2D) = "bump" {} _DetailTex ("Fabric Weave", 2D) = "white" {} _FresnelColor ("Fresnel Color", Color) = (1,1,1,1) _FresnelPower ("Fresnel Power", Range(0, 12)) = 3 _RimPower ("Rim FallOff", Range(0, 12)) = 3 _SpecIntesity ("Specular Intensiity", Range(0, 1)) = 0.2 _SpecWidth ("Specular Width", Range(0, 1)) = 0.2 }
CGPROGRAM #pragma surface surf Velvet #pragma target 3.0
sampler2D _BumpMap; sampler2D _DetailBump; sampler2D _DetailTex; float4 _MainTint; float4 _FresnelColor; float _FresnelPower; float _RimPower; float _SpecIntesity; float _SpecWidth;
struct Input { float2 uv_BumpMap; float2 uv_DetailBump; float2 uv_DetailTex; };
inline fixed4 LightingVelvet (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten) { }
//Create lighting vectors here viewDir = normalize(viewDir); lightDir = normalize(lightDir); half3 halfVec = normalize (lightDir + viewDir); fixed NdotL = max (0, dot (s.Normal, lightDir));
//Create Specular float NdotH = max (0, dot (s.Normal, halfVec)); float spec = pow (NdotH, s.Specular*128.0) * s.Gloss;
//Create Fresnel float HdotV = pow(1-max(0, dot(halfVec, viewDir)), _FresnelPower); float NdotE = pow(1-max(0, dot(s.Normal, viewDir)), _RimPower); float finalSpecMask = NdotE * HdotV
//Output the final color fixed4 c; c.rgb = (s.Albedo * NdotL * _LightColor0.rgb) + (spec * (finalSpecMask * _FresnelColor)) * (atten * 2); c.a = 1.0; return c;
void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D (_DetailTex, IN.uv_DetailTex); fixed3 normals = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)).rgb; fixed3 detailNormals = UnpackNormal(tex2D(_DetailBump, IN.uv_DetailBump)).rgb; fixed3 finalNormals = float3(normals.x + detailNormals.x, normals.y + detailNormals.y, normals.z + detailNormals.z); o.Normal = normalize(finalNormals); o.Specular = _SpecWidth; o.Gloss = _SpecIntesity; o.Albedo = c.rgb * _MainTint; o.Alpha = c.a; }
Shader "Custom/ClothShader" { Properties { _MainTint ("Global Tint", Color) = (1,1,1,1) _BumpMap ("Normal Map", 2D) = "bump" {} _DetailBump ("Detail Normal Map", 2D) = "bump" {} _DetailTex ("Fabric Weave", 2D) = "white" {} _FresnelColor ("Fresnel Color", Color) = (1,1,1,1) _FresnelPower ("Fresnel Power", Range(0, 12)) = 3 _RimPower ("Rim FallOff", Range(0, 12)) = 3 _SpecIntesity ("Specular Intensiity", Range(0, 1)) = 0.2 _SpecWidth ("Specular Width", Range(0, 1)) = 0.2 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Velvet #pragma target 3.0 sampler2D _BumpMap; sampler2D _DetailBump; sampler2D _DetailTex; float4 _MainTint; float4 _FresnelColor; float _FresnelPower; float _RimPower; float _SpecIntesity; float _SpecWidth; struct Input { float2 uv_BumpMap; float2 uv_DetailBump; float2 uv_DetailTex; }; inline fixed4 LightingVelvet (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten) { //Create lighting vectors here viewDir = normalize(viewDir); lightDir = normalize(lightDir); half3 halfVec = normalize (lightDir + viewDir); fixed NdotL = max (0, dot (s.Normal, lightDir)); //Create Specular float NdotH = max (0, dot (s.Normal, halfVec)); float spec = pow (NdotH, s.Specular*128.0) * s.Gloss; //Create Fresnel float HdotV = pow(1-max(0, dot(halfVec, viewDir)), _FresnelPower); float NdotE = pow(1-max(0, dot(s.Normal, viewDir)), _RimPower); float finalSpecMask = NdotE * HdotV; //Output the final color fixed4 c; c.rgb = (s.Albedo * NdotL * _LightColor0.rgb) + (spec * (finalSpecMask * _FresnelColor)) * (atten * 2); c.a = 1.0; return c; } void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D (_DetailTex, IN.uv_DetailTex); fixed3 normals = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)).rgb; fixed3 detailNormals = UnpackNormal(tex2D(_DetailBump, IN.uv_DetailBump)).rgb; fixed3 finalNormals = float3(normals.x + detailNormals.x, normals.y + detailNormals.y, normals.z + detailNormals.z); o.Normal = normalize(finalNormals); o.Specular = _SpecWidth; o.Gloss = _SpecIntesity; o.Albedo = c.rgb * _MainTint; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
【Unity Shaders】Lighting Models —— 衣服着色器,布布扣,bubuko.com
【Unity Shaders】Lighting Models —— 衣服着色器
原文地址:http://blog.csdn.net/candycat1992/article/details/27361707