我們的策劃想要讓原本的假陰影做乙個漸變的效果並且想要讓邊緣模糊。原本的效果時這樣的
可以看到陰影就是乙個黑影並且邊緣有很多鋸齒。
首先來分析兩個事情,乙個是鋸齒,乙個時漸變陰影。
一:陰影鋸齒
陰影的鋸齒主要是因為畫素不足導致的,這個情況下如果是用shadowmap的話我們可以考慮用pcf等方法處理。市面上也有很多處理陰影鋸齒的方法。
但是我們這個陰影並不是用shadowmap實現的,是直接壓扁放到角色腳底實現的。這樣就會導致鋸齒只能全屏處理,比如msaa,taa等全屏操作。沒辦法在這個pass中直接解決。
然後基於獲取陰影之後做抗鋸齒的操作考慮有兩種:
一種是陰影的pass之後每個角色執行多乙個pass,在那個pass中解決抗鋸齒。但是這樣就會導致每個角色都多乙個pass。效能消耗多一倍。
一種是把角色的陰影渲染到一張圖上,最後對這張圖做模糊處理。這樣的好處是不用每個角色多乙個pass處理。但他也有不好的地方,主要是需要截圖然後做模糊,這裡也會有一些消耗,特別是模糊的時候,需要多取樣。
我用的是後面的這種方式:
首先需要保證角色都是在不透明渲染中執行的,然後我們可以用commandbuffer執行在不透明渲染之後執行一次截圖(相當於urp裡的opaquetexture)
void onprerender()
這裡是說把相機的內容放到copyopaquetexture裡去。
當然如果只是做這步我們能獲取到不透明物體的所有角色,但是我們在上想要出現的只是陰影的效果,不是想要角色本身的效果。
如果有角色本身的效果的話後面做模糊處理會影響到角色的顯示,比如效果會是這樣:
那麼我們可以利用不透明渲染的乙個特點,就是我們處理alpha值對角色本身是不會有影響的,也就是他始終全部顏色都會顯示。不會理會alpha值。而我們寫到上時alpha資訊時存在的,利用這個特性我們就能根據alpha提取出陰影資訊了。
也就是說不透明渲染的shader把角色渲染的地方設定alpha值為0(渲染陰影的shader還是要正常的alpha):
這樣就能得到陰影資訊了:
得到後我們需要在透明渲染階段對這個陰影圖做模糊處理,一開始我時考慮用乙個commandbuffer來讓他在透明渲染後執行,但後來法線他會擋著透明渲染裡的物品,不太符合要求。所以就讓這個渲染直接在transparent下執行了。
那麼就相當於建立乙個gameobject,然後設定正確的材質給他,這樣來渲染:
commandbuffer copycmb;
material shadowblur_material;
rendertexture copyopaquetexture;
void awake()
}copycmb = new commandbuffer();
copycmb.name = "copy texture";
maincamera.addcommandbuffer(cameraevent.afterimageeffectsopaque, copycmb);
shadowblur_material = new material(shader.find("diablolite v2/moster_plus_shadow_blur"));
gameobject go = gameobject.createprimitive(primitivetype.quad);
go.transform.setparent(maincamera.transform);
go.transform.localposition = new vector3(0, 0, 1);
float cameraheight = maincamera.orthographicsize * 2;
float percent = (float)maincamera.pixelwidth / (float)maincamera.pixelheight;
go.transform.localscale = new vector3(cameraheight * percent, cameraheight, 1);
go.transform.localrotation = quaternion.identity;
var collider = go.getcomponent();
component.destroy(collider);
var renderer = go.getcomponent();
renderer.sharedmaterial = shadowblur_material;
copyopaquetexture, shadowblur_material, 0);
}void onprerender()
然後我們需要做模糊,模糊有很多中,其中這裡已經寫得很清楚了。然後我用的時高斯模糊:
sampler2d _cameracolor;
float4 _cameracolor_st;
float4 _cameracolor_texelsize;
uniform half _actoralpha;
;struct v2f
;float4 frag(v2f i) : sv_target
這裡要注意這個quad要根據我們相機的大小來設定,我的是正交相機,所以我用size去處理
二:陰影漸變
解決了鋸齒效果後就是漸變效果了,在現實生活中的漸變效果有乙個特點,就是邊緣模糊和離地面越近越深的顏色,越遠越淡顏色。這也是因為兩物體離得近時得到間接光照效果會逐漸減弱,合併在一起基本就沒了(當然不是絕對的沒有了)。
所以我們可以考慮根據角色離中心點的距離來設定他的透明度。
half perx = i.modelvertex.z < 0 ? (_actoralpha + i.modelvertex.z * inteval) : (i.modelvertex.z > 0 ? (_actoralpha - i.modelvertex.z * inteval) : _actoralpha);
half pery = i.modelvertex.y < 0 ? (_actoralpha + i.modelvertex.y * inteval) : (i.modelvertex.y > 0 ? (_actoralpha - i.modelvertex.y * inteval) : _actoralpha);
color.a *= perx;
color.a *= pery;
最終就可以得到比較柔和的陰影了 anroid邊框陰影 圓角陰影 漸變陰影
anroid給邊框加陰影只能對內陰影,沒有給邊框對外加陰影,在自定義shape中增加一層或多層,並錯開,即可 顯示陰影效果。給邊框加陰影可使用 1.圓角陰影效果 內陰影 不加漸變色,第一層漸變色其實沒啥用,是對整個邊框漸變,2dp的陰影還是乙個顏色。android centerx 0.5 andro...
文字陰影效果
關於android文字陰影,共有四個屬性可以設定 android shadowcolor 陰影顏色 android shadowdx 陰影x方向位移 android shadowdy 陰影y方向位移 android shadowradius 陰影的半徑 注意 陰影的半徑必須設,為0時沒有效果。下面為...
Qt陰影效果
1.widget.h ifndef widget h define widget h include include include namespace uiclass widget public qwidget endif widget h2.widget.cpp include widget.h...