移動端實時陰影+自投影技術實現

說到實時陰影,現在市面上各個項目實現的實時陰影大部分都是平面陰影,比如王者榮耀實現的實時陰影以及一些RPG網絡遊戲實現實時陰影,所以項目在設計地形時都是有意迴避地形高度差的出現,儘量讓地形是平坦的。本篇博客介紹的實時陰影是可以在平面以及地形上進行的渲染。這樣實現的實時陰影就可以在不同的地形上進行投影,實現方式採用的還是比較傳統的實時陰影算法比如ShadowMap,CSM算法或者PSM算法等等都可以實現出來,另外,除了陰影投影到地面上的,我們還可以實現陰影的自投影,比如角色身上的盔甲可以投影到身體上面,類似崩壞三實現的效果。如下所示:
在這裏插入圖片描述
角色的投影地面並不是平坦的,再看一下自身投影的實現效果:
在這裏插入圖片描述
角色身上的頭髮或者裙子在自己身上投影。自身的投影實現相對來說比較耗,它要實時的計算遮擋關係。下面先給讀者介紹將投影投到任意地形上面,實現的算法可以使用CSM算法,這個也是Unity引擎使用的算法。CSM算法是通過攝像機根據距離對場景由遠及近進行劃分,近處的物體投影比較精細,遠處的物體投影相對來說比較簡陋,這樣對性能來說也是一種優化,如下所示:
在這裏插入圖片描述
攝像機生成好了後,需要加入Shader生成陰影其實簡單點說就是像素深度的判斷
代碼如下所示:

		fixed4 frag (v2f i) : COLOR
		{
			float depth = i.depth.x/i.depth.y;

		#if defined (SHADER_TARGET_GLSL) 
			depth = depth*0.5 + 0.5; //(-1, 1)-->(0, 1)
		#elif defined (UNITY_REVERSED_Z)
			depth = 1 - depth;       //(1, 0)-->(0, 1)
		#endif

			return EncodeFloatRGBA(depth);
		}

我們投影是投影到地面上或者牆上,從優化角度講,我們會選擇哪些可以接收陰影,哪些不接受陰影。這些需要接收的陰影的對象需要掛接一個Shader用於接收陰影,片段着色器代碼如下所示:

			fixed4 frag (v2f i) : COLOR0 
			{
				fixed4 weights = getCascadeWeights(i.eyeZ);
				fixed4 coord = getShadowCoord(i.worldPos, weights);
				i.shadowCoord.xy = i.shadowCoord.xy/i.shadowCoord.w;
				float2 uv = i.shadowCoord.xy;
				uv = uv*0.5 + 0.5; //(-1, 1)-->(0, 1)
				fixed4 texcol = tex2D(_MainTex, uv);

				float depth = i.shadowCoord.z / i.shadowCoord.w;

			#if defined (SHADER_TARGET_GLSL)
				depth = depth*0.5 + 0.5; //(-1, 1)-->(0, 1)
			#elif defined (UNITY_REVERSED_Z)
				depth = 1 - depth;       //(1, 0)-->(0, 1)
			#endif
				// sample depth texture
				float4 col = SampleShadowTexture(i.worldPos, weights) * texcol;
				return col;
			}	

這樣我們就完成了陰影的實現,效果如下所示:
在這裏插入圖片描述
這樣我們的角色實現了可以將陰影投影到不同的地形上,下面再看看通過設置裁剪距離實現自身投影效果,如下所示:
在這裏插入圖片描述
大家可以看到紅色方框內的陰影是角色衣服和武器投影到上面的,完美解決了該問題。

代碼後續奉上。。。。。。。。。。

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