用hlsl/glsl实现内发光效果

1近期由于工作需求,需要实现一些地球上行政区域的内发光效果,找了很多资料终于找到了一个比较好的算法,现在一步一步分享给大家

2.首先在学习shader的时候,特别是hlsl和cg语言的,我们可以使用NVIDIA FX Composer 2.5工具。在上面我们可以找到很多shader效果并可以进行调试来改造写出我们自己想要的shader效果

<1>第一步,先来采透明度

由于物体外面的透明度都是0,而我们将物体设置成透明度为1完全不透明的物体,这样就会生成透明度从物体内部到外部从1到0递减的一系列值,由于这些值都是小于1的,因此用1减去它这样就得到了物体内部从0到1一系列递增的值。

实现代码如下:

               float TexelIncrement = Stride*QuadScreenSize.x;
               float2 QuadTexelOffsets = float2(0.0,0.0);
               float2 Coord = float2(TexCoord.xy);
               float colour = tex2D(scene,float2(Coord.x + TexelIncrement, Coord.y) ).w * (0.8/WT9_NORMALIZE);
		colour += tex2D(scene, float2(Coord.x +2 * TexelIncrement, Coord.y)).w * (WT9_2/WT9_NORMALIZE);
		colour += tex2D(scene, float2(Coord.x +3 * TexelIncrement, Coord.y)).w * (WT9_3/WT9_NORMALIZE);
		colour += tex2D(scene, float2(Coord.x +4 * TexelIncrement, Coord.y)).w * (WT9_4/WT9_NORMALIZE);
		colour += tex2D(scene, float2(Coord.x, Coord.y)).w * (WT9_0/WT9_NORMALIZE);
		colour += tex2D(scene, float2(Coord.x - 1 * TexelIncrement, Coord.y)).w * (WT9_1/WT9_NORMALIZE);
		colour += tex2D(scene, float2(Coord.x - 2 * TexelIncrement, Coord.y)).w * (WT9_2/WT9_NORMALIZE);
		colour += tex2D(scene, float2(Coord.x - 3 * TexelIncrement, Coord.y)).w * (WT9_3/WT9_NORMALIZE);
		colour += tex2D(scene, float2(Coord.x - 4 * TexelIncrement, Coord.y)).w * (WT9_3/WT9_NORMALIZE);
		float col = 1.0-colour;
		//if(col < 0.01){
		//col = 0.0;
		//}
   return float4(col,col,col,col);

这样就得到了如下图这样的一个里面实体是黑色外面边缘由实到虚的一个球,外面那个边也是实现内发光的关键所在

<2>第二步:完成第一步的时候其实主要是借助透明度,第二步我们就随便采样这张图的任意一个rgba的值(因为都是一样的,比如我们用r),然后我们再采样原图的w值(透明度),由于原图物体外部w是0,因此外部的w*r=0,这样就会将物体外部虚化的边删除掉,也就只能往里面发光了。

        float TexelIncrement = Stride*QuadScreenSize.y;
        float2 Coord = float2(TexCoord.xy);
        float colour = tex2D(blurX, float2(Coord.x , Coord.y+TexelIncrement)).x * (0.8/WT9_NORMALIZE);
	colour += tex2D(blurX, float2(Coord.x, Coord.y +2 * TexelIncrement)).x* (WT9_2/WT9_NORMALIZE);
	colour += tex2D(blurX, float2(Coord.x , Coord.y+3 * TexelIncrement)).x * (WT9_3/WT9_NORMALIZE);
	colour += tex2D(blurX, float2(Coord.x , Coord.y+4 * TexelIncrement)).x * (WT9_4/WT9_NORMALIZE);
	colour += tex2D(blurX, float2(Coord.x, Coord.y)).x * (WT9_0/WT9_NORMALIZE);
	colour += tex2D(blurX, float2(Coord.x , Coord.y- 1 * TexelIncrement)).x * (WT9_1/WT9_NORMALIZE);
	colour += tex2D(blurX, float2(Coord.x, Coord.y - 2 * TexelIncrement)).x * (WT9_2/WT9_NORMALIZE);
	colour += tex2D(blurX, float2(Coord.x, Coord.y - 3 * TexelIncrement)).x* (WT9_3/WT9_NORMALIZE);
	colour += tex2D(blurX, float2(Coord.x , Coord.y- 4 * TexelIncrement)).x * (WT9_3/WT9_NORMALIZE);
	float4 glo = (Glowness * colour) * GlowColor;
        float4 OldCol = tex2D(scene, float2(Coord.x , Coord.y));
	return  float4(OldCol.w*glo.xyz,0);
结果如下:(当然我们只是把颜色设置为了绿色。 最后return我们透明度写了0,其实无所谓,因为最终输出是无法改变原来的透明度的)


3第三步,仔细一看基本上大功告成了,我们再把原图加上看看效果把


大功告成,下面再截几个实例图看看:




大家如果需要源码欢迎留言写下邮箱等联系方式,欢迎一起交流学习,转载请备注,谢谢


发布了9 篇原创文章 · 获赞 11 · 访问量 8276

猜你喜欢

转载自blog.csdn.net/zhgu1992/article/details/78883708