
平行光
2D這里主要是指有高度的光,即限定了影子的長度,
Shadow Mesh
限定影子長度生成的Mesh有很多種,可以根據實際情況,選擇不同的方案,
- 平移Sprite頂點(自動生成的Sprite Vertex 或者 Custome Physics Shape 頂點),然后使用凸包形成新的影子外形,
- 使用相同的Sprite Renderer渲染影子,在Shader里進行旋轉拉伸等操作,
- 其他:直接復制平移Sprite然后顏色置黑(如浮空物體);加一個單獨的影子貼圖(如一個橢圓的影子貼圖放在物體下面);等等,
平移Sprite頂點
在c#腳本里遍歷Sprite生成Mesh資料,生成一個Mesh繪制影子,只有一個Draw Call,
- 根據選擇獲取Sprite頂點(默認或Custome Physics Shape)
- 按照光方向平移頂點

3. 使用凸包演算法獲取凸點,保存為Mesh的資料

4. 軟陰影可以在Mesh外面包一個Mesh,使用一張漸變紋理繪制軟陰影,用UV或Tangent等通道保存漸變貼圖的UV,內圍點為0,外圍點為1,


- 合并所有資料生成一個Shadow Mesh
使用Custome Physics Shape和默認頂點的結果:

Shader里進行旋轉拉伸貼圖
遍歷Srpite使用Sprite原來的Sprite Renderer加上陰影的Shader繪制陰影,每個Sprite都需要一個Draw Call,這樣做主要是因為需要使用Sprite貼圖的Alpha通道繪制影子外形,
如果合并使用一個Draw Call繪制,陰影的外形不好控制(使用默認Sprite頂點基本上效果會很差),可以使用cutom outline或者cutom physics shape生成相對細致的外形,屬于空間換時間的做法,
- C#腳本中指定Sprite Renderer(主要是需要主貼圖),旋轉所用的根頂點,旋轉弧度,拉伸長度
- 在頂點著色器里進行頂點旋轉拉伸,按任意方向拉伸演算法參考Scaling along the cardinal axes
// c#
// 旋轉所用的根頂點,取中間接近底部的頂點
// 兼容旋轉縮放
var matrix = Matrix4x4.TRS(caster.transform.position, caster.transform.rotation, caster.transform.localScale);
var rootPos = (Vector2)(matrix * new Vector4(0f, -0.45f, 0, 1));
rootPos = caster.transform.InverseTransformPoint(rootPos);
// shader
// 二維按任意方向拉伸
float2 scaleByDir(float2 p, float radian, float k){
float2 dir = float2(cos(radian), sin(radian));
float2 r1 = float2(1 + (k - 1) * dir.x * dir.x, (k - 1) * dir.x * dir.y);
float2 r2 = float2((k - 1) * dir.x * dir.y, 1 + (k - 1) * dir.y * dir.y);
return float2(r1.x * p.x + r1.y * p.y, r2.x * p.x + r2.y * p.y);
}

旋轉根部的瑕疵

解決方法可以是使用一張底部是圓形的Mask貼圖,這樣旋轉的時候就看不出來瑕疵,我覺得是一種比較好的方法,Mask貼圖還可用來做軟陰影(未驗證),
另一種是底部uv.y比較小的時候不進行旋轉拉伸,
大于180°時,下面會消失,是因為底部不旋轉,其他地方旋轉大于180°時導致三角面片反了,大于180°將底部x坐標置反即可,

但是旋轉角度接近與0°和180°時底部過小處理起來比較麻煩,除了手動加一個圓形陰影想不出來什么好的處理方法,相對來說還是使用一個陰影Mask貼圖比較方便,


陰影覆寫貼圖處理
陰影會將Sprite本身覆寫掉,

因為覆寫地方完全貼合Sprite,所以除了每個Sprite在渲染陰影后再渲一遍將覆寫地方去除,目前想不其他好的方法,
// 將alpha置反,混合時取最小即可
BlendOp Min
Blend One OneMinusDstColor
frag {
fixed alpha = tex2D(_MainTex, i.uv).a;
fixed4 col = 1 - alpha;
col.a = 1;
return col;
}

陰影衰減
簡單點計算頂點與之前旋轉用的點的距離然后使用1.0 - saturate(distance * _ShadowFalloff)求出衰減即可,

原始碼
link
參考
拉伸矩陣:https://www.mauriciopoppe.com/notes/computer-graphics/transformation-matrices/scale/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/226377.html
標籤:其他
