创建一个Phong镜面类型的高光反射着色器
创建一个Phong类型类型的高光反射着色器 一个物体表面的高光,可以简单的理解为它表面的亮度。这种类型的着色器常用于视野特效(view-dependent effects)。这是因为 为了在着色器中获得贴近现实的高光效果,你需要考虑到摄像机和人的朝向因素。而 Phong 高光效果是最基础和性能较好的一种着色器效果。它根据人的朝向和光的反射方向,通过计算获得一个有方向的反射。 在应用程序中,这种高光模型非常常见,涵盖游戏行业到电影等产业。虽然它在高光反射模型的精确度上不是最接近现实的,但是在大多数情况下,它大致都能满足而且性能不赖。此外,如果你的游戏对象离摄像机很远,就没有必要在提供准确的高光,这对你的高光效果着色器来说是好事。 在这个知识点中,我们会涉及到如何使用表面着色器的 输入(Input) 结构体中的一些新参数进行逐顶点和逐像素的操作。我们会了解它们之间的区别,而且还会讨论什么时候以及为什么要用这两种不同的实现方式,来应对不同的情况。 始前准备 我们按照下面的步骤来学习这次的知识点: 分别创建一个新的着色器,材质和游戏对象,为了在后面你容易照到它们,请给它们恰当命名。 创建一个新场景,在创建一个新的游戏对象,把着色器应用到材质,然后再把材质应用到游戏对象上。 再添加一个平行光源,这是为了让我们方便看我们着色器代码的高光效果。 操作步骤 请按照下面的步骤创建一个 Phong 类型的光照模型: 此时你可能发现了一个模式,在我们开始写着色器的时候都有的步骤:着色器属性的创建。所以,让我们先在着色器中添加下面的一些属性: Properties { _MainTint ("Diffuse Tint", Color) = (1,1,1,1) _MainTex ("Base (RGB)", 2D) = "white" {} _SpecularColor ("Specular Color", Color) = (1,1,1,1) _SpecPower ("Specular Power", Range(0,30)) = 1 } 接下来在 CGPROGRAM 块中的 SubShader{} 块中,添加与之对应的一些变量: float4 _SpecularColor; sampler2D _MainTex; float4 _MainTint; float _SpecPower; 现在我们要添加我们自定义的光照模型,因为我们要计算自己的 Phong 高光。如果你现在还不能理解下面的代码也不用担心;在 原理介绍 的部分我们会解释每一行代码的作用。在着色器的 SubShader{} 中添加下述代码: fixed4 LightingPhong (SurfaceOutput s, fixed3 lightDir, half3 viewDir,fixed atten) { // Reflection float NdotL = dot(s.Normal, lightDir); float3 reflectionVector = normalize(2.0 * s.Normal * NdotL - lightDir); // Specular float spec = pow(max(0, dot(reflectionVector, viewDir)), _SpecPower); float3 finalSpec = _SpecularColor.rgb * spec; // Final effect fixed4 c; c.rgb = (s.Albedo * _LightColor0.rgb * max(0,NdotL) * atten) + (_LightColor0.rgb * finalSpec); c.a = s.Alpha; return c; } 最后,我们还要告诉 CGPROGRAM 块,需要用我们自定义的光照模型而不是Unity内建的光照模型。 按照下面的步骤修改 #pragma 指示: CPROGRAM #pragma surface surf Phong 下图演示了我们自定义的 Phong 光照模型的效果,里面的反射算法也是我们自己的: ...