后處理掃光是很早之前為大場(chǎng)景制作的后處理效果西乖,也在群里吸取了很多群友的意見不斷完善顯示效果松靡。這是一個(gè)比較簡(jiǎn)單但是思想上比較基礎(chǔ)泛用的后處理效果简僧,以此舉一反三可以制作很多種類的效果。本文最終的PG路徑:雕欺。
步驟規(guī)劃
想要制作掃光后處理岛马,我們只需要做三件事情:
- 深度重建世界坐標(biāo)。
- 通過世界坐標(biāo)計(jì)算掃光的前進(jìn)軸x軸和與前進(jìn)軸垂直的等勢(shì)軸y軸屠列。
- 根據(jù)前進(jìn)軸的x軸和y軸繪制出顏色效果啦逆。
具體步驟
- 深度重建世界坐標(biāo)的過程已經(jīng)在BabylonJS后處理系列: 深度基礎(chǔ)中介紹過了,這里將在BabylonJS后處理系列: 深度基礎(chǔ)的PG的基礎(chǔ)上繼續(xù)制作笛洛。PG
- 這一步先以水平掃光舉例夏志,我們添加一個(gè)角度控制掃光的方向,然后用下列的函數(shù)變幻出前進(jìn)軸和等勢(shì)軸苛让。PG
vec2 getScanAxis(vec3 wPos){
float angle = scanAngle/180.*PI;
vec2 sPos;
sPos.x = wPos.x*cos(angle)+wPos.z*sin(angle);
sPos.y = wPos.z*cos(angle)-wPos.x*sin(angle);
return sPos;
}
3.第三步根據(jù)前進(jìn)軸進(jìn)行Remap沟蔑,然后繪制顏色。
//首先沿X軸按掃光間隔長(zhǎng)度進(jìn)行取余得到 frontLine 狱杰。
float frontLine = mod(axisPos.x-scanTime,scanLength);
//將frontLine歸1
float scanLine = frontLine/scanLength;
//根據(jù)Percent將frontLine平移縮放瘦材,使得只有Percent*長(zhǎng)度的部分在X軸的上方,然后取大于0的值仿畸。
scanLine = max((scanLine-1.+scanPercent)/scanPercent,0.);
這樣我們就獲取到了一個(gè)寬占掃光間隔長(zhǎng)度百分之N的范圍為0-1的線性帶食棕,這一條為掃光的顯示區(qū)域,我們可以以scanLine為X軸错沽,等勢(shì)軸為y軸去計(jì)算顯色區(qū)域或采樣紋理等簿晓,這個(gè)可以自由發(fā)揮。PG
//求前沿高亮部分
float frontLineStep = step(scanLength-frontLine,frontLineWidth);
vec4 finColor ;
//獲取最終顏色
finColor.rgb = mix(scanColor*scanPower,frontColor,frontLineStep);
finColor.a = scanLine;
PG:https://playground.babylonjs.com/#KZP9WM#5
添加一個(gè)自定義TransformNode去控制參數(shù)(目前PostProcess的自定義控件好像有bug不顯示甥捺,只能創(chuàng)一個(gè)TransformNode去顯示)抢蚀。詳見LightScanTransformNode。
簡(jiǎn)單拓展
vec4 getScanColor(vec2 axisPos){
float scanX = axisPos.x +50. * (cos(axisPos.y/2./100.)+cos(axisPos.y/2./50.)+cos(axisPos.y/2./25.));
float frontLine = mod(scanX-scanTime,scanLength);
.........
}
2.掃描面采樣
float scanWidth = scanLength * scanPercent * 0.5;
float scanHeight = scanWidth*4.;
vec3 scanTexColor = texture2D(scanTex,vec2(max(scanLine*2.-1.,0.),axisPos.y/scanHeight)).rgb;
finColor.rgb = max(finColor.rgb,scanTexColor);
3.以圓心擴(kuò)散掃光可以通過gizmo修改中心位置
vec2 getScanAxis(vec3 wPos){
float angle = scanAngle/180.*PI;
vec2 sPos;
// sPos.x = wPos.x*cos(angle)+wPos.z*sin(angle);
// sPos.y = wPos.z*cos(angle)-wPos.x*sin(angle);
vec2 dtPos = wPos.xz - centerTarget.xz;
sPos.x = length(dtPos);
sPos.y = atan(dtPos.y,dtPos.x);
return sPos;
}