Shader Forge这个组件使用起来非常方便,尤其是哪些对Shader编程不是很理解的开发者,使用Shader Forge可以快速的搭建出一个Shader,这个跟虚幻的UE4引擎编辑器很类似,尤其做次世代游戏非常好。下面给读者展示一下Shader Forge的威力,效果图如下所示:

泰课在线

看一下上图展示的效果,它就是用Shader Forge搭建出来的,使用了Diffuse,Normal,Gloss,Emisson等,不对比不知道,我们看一下使用Unity3D引擎自带的Shade效果如下所示:

泰课在线

这个是同样的环境下使用Unity3D引擎自带的standardShader的效果,它的设置界面如下所示:

泰课在线

既然Unity3D引擎自带的Shader无法满足我们的需求,那就使用Shader Forge解决问题,Shader Forge提供了一个编辑器,在上篇博客中给读者介绍过关于材质之间的操作,Shader Forge编辑器也是利用这个原理操作的,效果如下:

泰课在线

在Unity3D编辑器中的表现如下图所示:

泰课在线

参数的调整自己可以根据效果随意调整,这个模型就实现了高光,法线以及自发光等效果,通过Shader Forge生成的Shader代码使用的是顶点着色器和片段着色器,将上图转化成Shader后,核心代码如下所示:

  1. <span style="white-space:pre">    VertexOutput vert (VertexInput v) {  
  2.                 VertexOutput o = (VertexOutput)0;  
  3.                 o.uv0 = v.texcoord0;  
  4.                 o.normalDir = UnityObjectToWorldNormal(v.normal);  
  5.                 o.tangentDir = normalize( mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );  
  6.                 o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);  
  7.                 o.posWorld = mul(unity_ObjectToWorld, v.vertex);  
  8.                 float3 lightColor = _LightColor0.rgb;  
  9.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex );  
  10.                 UNITY_TRANSFER_FOG(o,o.pos);  
  11.                 TRANSFER_VERTEX_TO_FRAGMENT(o)  
  12.                 return o;  
  13.             }  
  14.             float4 frag(VertexOutput i) : COLOR {  
  15.                 i.normalDir = normalize(i.normalDir);  
  16.                 float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);  
  17.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);  
  18.                 float3 _normal_var = UnpackNormal(tex2D(_normal,TRANSFORM_TEX(i.uv0, _normal)));  
  19.                 float3 normalLocal = _normal_var.rgb;  
  20.                 float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals  
  21.                 float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);  
  22.                 float3 lightColor = _LightColor0.rgb;  
  23.                 float3 halfDirection = normalize(viewDirection+lightDirection);  
  24. ////// Lighting:  
  25.                 float attenuation = LIGHT_ATTENUATION(i);  
  26.                 float3 attenColor = attenuation * _LightColor0.xyz;  
  27. ///////// Gloss:  
  28.                 float4 _gloss_diffuse_var = tex2D(_gloss_diffuse,TRANSFORM_TEX(i.uv0, _gloss_diffuse));  
  29.                 float gloss = (_gloss_diffuse_var.r*_gloss);  
  30.                 float specPow = exp2( gloss * 10.0+1.0);  
  31. ////// Specular:  
  32.                 float NdotL = max(0, dot( normalDirection, lightDirection ));  
  33.                 float4 _light_var = tex2D(_light,TRANSFORM_TEX(i.uv0, _light));  
  34.                 float3 specularColor = (_light_var.rgb*_light_slider);  
  35.                 float3 directSpecular = (floor(attenuation) * _LightColor0.xyz) * pow(max(0,dot(halfDirection,normalDirection)),specPow)*specularColor;  
  36.                 float3 specular = directSpecular;  
  37. /////// Diffuse:  
  38.                 NdotL = max(0.0,dot( normalDirection, lightDirection ));  
  39.                 float3 directDiffuse = max( 0.0, NdotL) * attenColor;  
  40.                 float3 indirectDiffuse = float3(0,0,0);  
  41.                 indirectDiffuse += UNITY_LIGHTMODEL_AMBIENT.rgb; // Ambient Light  
  42.                 float4 _df_var = tex2D(_df,TRANSFORM_TEX(i.uv0, _df));  
  43.                 float3 diffuseColor = (_df_var.rgb*_df_Color.rgb);  
  44.                 float3 diffuse = (directDiffuse + indirectDiffuse) * diffuseColor;  
  45. ////// Emissive:  
  46.                 float4 _Emission_color_var = tex2D(_Emission_color,TRANSFORM_TEX(i.uv0, _Emission_color));  
  47.                 float3 emissive = (_Emission_color_var.rgb*_Emission_slider);  
  48. /// Final Color:  
  49.                 float3 finalColor = diffuse + specular + emissive;  
  50.                 fixed4 finalRGBA = fixed4(finalColor,1);  
  51.                 UNITY_APPLY_FOG(i.fogCoord, finalRGBA);  
  52.                 return finalRGBA;  
  53.             }  

这样我们就实现了次世代效果渲染,是不是非常酷?很多人担心其性能,其实在IOS端帧率还是可以的,满帧30的情况下,能跑到25帧左右。