在Unity中實現屏幕空間反射Screen Space Reflection(3)


本篇講一下相交檢測的優化。有兩個措施。

線段相交檢測

之前的檢測都是檢測光線的終點是否在物體內。我們可以嘗試檢測光線的線段是否與物體相交。

比如說有一個非常薄的物體,光線差不多垂直於它的表面。如果用普通的方法的話,這個平面可能就會被光線跳過了。

我們將一個像素的厚度看做一維數軸上的一條線段,起點是其深度。同時將光線的起點、終點的深度值也用同樣的方法看做一條線段。此時我們去檢測這兩條線段是否有重合。有的話則證明相交。

用這種方法可以解決薄的物體被跳過的問題。

			bool intersect(float raya, float rayb, float2 sspt) {        //raya rayb是光線兩端的深度值,sspt是屏幕空間的坐標點。
				float screenPCameraDepth = Linear01Depth(tex2Dlod(_CameraDepthTexture, float4(sspt / 2 + 0.5, 0, 0)));
				float backZ = tex2Dlod(_BackfaceTex, float4(sspt / 2 + 0.5, 0, 0)).r;

				if (raya > rayb) {    //因為光線方向不定(可能朝向+z或者-z)需要排序
					float t = raya;
					raya = rayb;
					rayb = t;
				}
				return raya < backZ && rayb > screenPCameraDepth;
			}

為了優化效果,我們在計算光線的屏幕空間的坐標時,可以取光線兩個端點的中間點,投影到屏幕上作為采樣點。

二分搜索優化

大部分情況下,我們的每個像素的采樣次數不會很高。此時采樣的質量會比較差。我們可以引入二分搜索,當檢測到一個光線的相交時,我們在這段光線內部進行二分搜索,尋找精確的相交點。

這個圖不好截,我找了kode80博客里的一張圖進行說明。

值得注意的是,二分搜索只能對成功相交的光線進行優化,本身沒有相交的是無法進行優化的。

以下代碼中涉及到一些下篇的變量,但是大體意思很明了,即退回一段光線,然后在退回的區間中尋找相交。

if (intersect(screenPTrueDepth,prevDepth, screenPCurrent - dScreenPCurrent/2)){
#if 1  //二分搜索優化
						float gapSize = PIXEL_STRIDE;
						float2 screenPBegin = screenPCurrent - dScreenPCurrent;        //回退
						float oneOverZBegin = oneOverzCurrent - dOneOverZCurrent;
						prevDepth = 1 / oneOverZBegin / -_ProjectionParams.z;
						UNITY_LOOP
						for (int j = 0; j < 10 && gapSize > 1.0; j++) {
							gapSize /= 2;
							dScreenPCurrent /= 2;
							dOneOverZCurrent /= 2;
							screenPCurrent = screenPBegin + dScreenPCurrent;
							oneOverzCurrent = oneOverZBegin + dOneOverZCurrent;
							screenPTrueDepth = 1 / oneOverzCurrent / -_ProjectionParams.z;
							if (intersect(screenPTrueDepth, prevDepth, screenPCurrent)) {		//命中了,起點不用動。(長度縮短一半即可)

							}
							else {							//沒命中,將起點移動到中間。
								prevDepth = screenPTrueDepth;
								screenPBegin = screenPCurrent;
								oneOverZBegin = oneOverzCurrent;
							}
						}	 
#endif
						hitPixel = screenPCurrent / 2 + 0.5;
						rayPercent = (float)i / STEP_COUNT;
						return true;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM