OK,让我们来看看一个现实中的夜视仪效果:
从画面中我们可以看到,夜视仪(为了方便,以下简称NV)的世界是一片绿色。为了打造我们的NV世界,首先第一步当然是把画面变成绿色。方法很简单,把最终输出的颜色和一个filter过滤下就好了。下面是一个例子:
emm... 就这样就完了么?显然太简单了.呵呵,仅仅是这样,也许能满足一些场合的应用,但是对于精益求精的你,当然这是第一步.那么下面呢?
我们仔细看下第一副真实的照片,能发现图像比较模糊.所以下面我们开始模拟这个效果.怎么做呢?方法比较多,你可以自己用box或者高斯模糊,也可以用一个预渲染好的模糊纹理.本文中我选择后者,当然,您可以用您喜欢的任何一种方法,实现起来基本一样,下面是我采用的noise texture:
这一次,我们得到的图像是:
实际上他噪点是一直在动态跳动的,静态截图效果不是很好,同时,选择一个好的噪声纹理也很重要,您可以多试验几个不同的noise texture.
嗯,似乎在游戏中,到了这一步已经基本可以较好还原NV的效果了,不过,为了完整性,下面我们再做一个从NV望远镜观望的效果,以求更加逼真:
仔细看边缘,主要我没做场景,不然效果会更加好,下面特地截了张镜框图:
以上用到的所有texture都是从网上找的,如果你想用到游戏中,那么特地为你的游戏做几张精致的texture一定会使得这个NV效果比我这个好上几倍.比如除了噪点模糊,完全可以在最终帧上加一次柔和模糊,以求更接近真实的样子.
下面是比较关键的PS代码:
希望对您有所帮助,也希望大家不吝赐教,共同学习,共同进步!
1 float4 ps_main(float2 texCoord: TEXCOORD0) : COLOR
2 {
3 float2 uv;
4 uv.x = 0.4*sin(fElapsedTime*50.0);
5 uv.y = 0.4*cos(fElapsedTime*50.0);
6 float m = tex2D(Texture2, texCoord).r;
7 float3 n = tex2D(Texture1, texCoord*3.5 + uv).rgb;
8 float3 c = tex2D(Texture0, texCoord + n.xy*0.005).xyz;
9 float lum = dot(float3(0.30, 0.59, 0.11), c);
10 if(lum < 0.2)
11 c *= AmplifyFactor;
12 float3 vc = float3(0.1, 0.95, 0.2)*m;
13 return float4((c+n*0.02)*vc,1.0);
14 }
很短不是嚒?而且有待优化,原理很简单:把屏幕变绿->模糊物体->完成或者加上你想要的效果,比如狙击镜或者望远镜等等. 该特效很简单,不多说了,enjoy yourself! :)