赞
踩
(1)法线贴图使用;
(2)利用法线贴图影响表面发射计算Specular;
//切线空间和世界空间计算 法线 贴图的使用; //制作人:嘿皮土豆; //参考:《Unity Shader入门精要》 Shader "ShaderLearn/NormalMapApply" { Properties { _MainColor("MainColor",Color) = (1,1,1,1) _MainTex("MainTex",2D) = ""{} _BumpMap("NormalMap",2D) = "bump"{} _BumpScale("BumpScale",range(0,5)) = 1 _SpecularColor("SpecularColor",Color) = (1,1,1,1) _Gloss("Gloss",range(1,50)) = 0.2 } SubShader { Tags{"LightMode" = "ForwardBase"} //如果两个 Pass 的渲染效果不同可选择混合模式 //Blend SrcAlpha OneMinusSrcAlpha pass { name "TangentSpaceBumpMap" CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float4 uv : TEXCOORD0; float3 LightDir : TEXCOORD1; float3 ViewDir : TEXCOORD2; }; sampler2D _MainTex; sampler2D _BumpMap; float4 _MainTex_ST; float4 _BumpMap_ST; float4 _MainColor; fixed4 _SpecularColor; float _BumpScale; float _Gloss; v2f vert (a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex); o.uv.zw = TRANSFORM_TEX(v.texcoord, _BumpMap); //float3 binormal = cross(normalize(v.normal),normalize(v.tangent.xyz)) * v.tangent.w; //float3x3 rotation = float3x3 (v.tangent.xyz, binormal, v.normal); //或者直接使用宏; TANGENT_SPACE_ROTATION; o.LightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz; o.ViewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz; return o; } fixed4 frag (v2f i) : SV_TARGET { fixed3 TangentLightDir = normalize(i.LightDir); fixed3 TangentViewDir = normalize(i.ViewDir); //贴图转换(输入四维计算出三维) fixed3 TangentNormal = UnpackNormal(tex2D(_BumpMap,i.uv.zw)); //法线贴图强度控制; TangentNormal.xy *= _BumpScale; TangentNormal.z = sqrt(1-saturate(dot(TangentNormal.xy, TangentNormal.xy))); fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb * _MainColor.rgb; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; fixed3 diffuse = _LightColor0.rgb * albedo * (dot(TangentNormal, TangentLightDir)*0.5+0.5); fixed3 halfDir = normalize(TangentViewDir + TangentLightDir); fixed3 specular = _LightColor0.rgb * _SpecularColor.rgb * pow(saturate(dot(TangentNormal,halfDir)), _Gloss); return fixed4 (ambient + diffuse + specular, 1); } ENDCG } pass { name "WorldSpaceBumpMap" CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; float4 tangent : TANGENT; }; struct v2f { float4 vertex : SV_POSITION; float4 uv : TEXCOORD0; float3 TtoW0 : TEXCOORD1; float3 TtoW1 : TEXCOORD2; float3 TtoW2 : TEXCOORD3; }; sampler2D _MainTex; sampler2D _BumpMap; float4 _MainTex_ST; float4 _BumpMap_ST; float4 _MainColor; fixed4 _SpecularColor; float _BumpScale; float _Gloss; v2f vert (a2v v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); float3 worldNormal = UnityObjectToWorldNormal(v.normal); float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); float3 worldBinormal = cross(worldNormal, worldTangent)* v.tangent.w; o.TtoW0 = float3 (worldTangent.x, worldBinormal.x, worldNormal.x); o.TtoW1 = float3 (worldTangent.y, worldBinormal.y, worldNormal.y); o.TtoW2 = float3 (worldTangent.z, worldBinormal.z, worldNormal.z); o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex); o.uv.zw = TRANSFORM_TEX(v.uv, _BumpMap); return o; } fixed4 frag (v2f i) : SV_TARGET { float3 worldPos = mul(unity_ObjectToWorld, i.vertex).xyz; fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(worldPos)); fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos)); float3 TangentNormal = UnpackNormal(tex2D(_BumpMap,i.uv.zw)); TangentNormal.xy *= _BumpScale; TangentNormal.z = sqrt(1-saturate(dot(TangentNormal.xy, TangentNormal.xy))); fixed3 TtoWNormal = fixed3 (dot(i.TtoW0, TangentNormal), dot(i.TtoW1, TangentNormal), dot(i.TtoW2, TangentNormal)); fixed3 albedo = tex2D(_MainTex,i.uv.xy) * _MainColor; fixed3 diffuse = _LightColor0.xyz * albedo * (dot(worldLightDir, TtoWNormal)*0.5+0.5); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; fixed3 halfDir = normalize(worldViewDir + worldLightDir); fixed3 specular = _LightColor0.rgb * _SpecularColor.rgb * pow(saturate(dot(TtoWNormal,halfDir)), _Gloss); return fixed4 (ambient + diffuse + specular, 1); } ENDCG } } //Fallback "Specular" }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。