用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第三步,仔細一看基本上大功告成了,我們再把原圖加上看看效果把


大功告成,下面再截幾個實例圖看看:




大家如果需要源碼歡迎留言寫下郵箱等聯繫方式,歡迎一起交流學習,轉載請備註,謝謝


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章