Three.js 剖切 clippingPlan

對(duì)模型剖切是通過設(shè)置scene或者material的clippingPlanes實(shí)現(xiàn)的;
如果設(shè)置了材質(zhì)的clippingPlanes,shader的頂點(diǎn)著色器和片元著色器都會(huì)加入相應(yīng)邏輯的代碼;
1、首先在頂點(diǎn)著色器里加入以下代碼,給vClipPosition賦值,并傳入片元著色器,這里用的是相機(jī)坐標(biāo)系里的值,沒有用世界坐標(biāo)系里的值,這可能是因?yàn)樽儞Q矩陣可能改變法線的朝向,因此要將法線和頂點(diǎn)都統(tǒng)一到相機(jī)坐標(biāo)系里;

#if 1 > 0 
  vClipPosition = -mvPosition.xyz;
#endif

if語句里的1表示的是clippingPlanes的個(gè)數(shù),編譯shader之前會(huì)被動(dòng)態(tài)替換;
2、到片元著色器里,有如下邏輯:

#if 1 > 0
    vec4 plane;
    
        plane = clippingPlanes[ 0 ];
        if ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;
    
    #if 1 < 1
        bool clipped = true;
        
        if ( clipped ) discard;
    #endif
#endif

同樣道理,里邊有些固定數(shù)值,其實(shí)是在shader編譯之前動(dòng)態(tài)替換的;上述代碼主要是判斷點(diǎn)落在了平面的哪一測(cè),如果不在指定的一側(cè),就discard,不繪制;

Three.js里的Plane用的是Hessian Normal Form

image.png

來描述一個(gè)明面,特別要注意,Plane的構(gòu)造方法里,傳入的距離是帶符號(hào)的,正值表示圓點(diǎn)位于法線方向指向的那一側(cè),負(fù)值表示另一側(cè),見下圖:
image.png

image.png

注意:上面頂點(diǎn)著色器里,vClipPosition = -mvPosition.xyz,之所以有個(gè)負(fù)號(hào),也是從上面Hessian Normal Form表達(dá)式得出的,NX = -P => -NX = P => N*(-X)=P,P是有符號(hào)的距離。在片元著色器里 dot( vClipPosition, plane.xyz ) > plane.w,plane.xyz和plane.w都是經(jīng)過法線矩陣變換后的值,不是構(gòu)造Plane時(shí)候傳入的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容