自定義裁切面在shader中有clipping_planes_pars_vertex、clipping_planes_vertex、clipping_planes_pars_fragment、clipping_planes_fragment這幾個定義。裁切面又分爲全局裁切、自定義裁切,全局裁切面是對所有的物體進行裁切,在
WebGLRender中定義,自定義裁切是在物體的材質中定義的,
clipping_planes_pars_vertex的代碼如下
#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )
varying vec3 vViewPosition; //定義傳遞到片元着色器的頂點,這個頂點是相機空間中的頂點
#endif
clipping_planes_vertex的代碼如下
#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )
vViewPosition = - mvPosition.xyz; //傳遞到片元着色器(裁切面的法線方向導致此處頂點的負數)
#endif
clipping_planes_pars_fragment的代碼如下
#if NUM_CLIPPING_PLANES > 0
#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )
varying vec3 vViewPosition; //接收到頂點着色器傳過來的相機空間的頂點位置(光柵化插值後)
#endif
uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ]; //裁切面數組
#endif
clipping_planes_fragment的代碼如下
#if NUM_CLIPPING_PLANES > 0
vec4 plane;
//自定義裁切 物體的材質中定義裁切面
#pragma unroll_loop //目的是將下面的循環展開爲一段段的代碼,空間換時間
for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {
//獲取一個裁切面
plane = clippingPlanes[ i ];
//dot計算頂點在平面法線上的投影,w爲平面法線的起點距離原點的位置,如果不在裁切面上就剔除該點
if ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;
}
//全局裁切 WebGLRender中定義裁切面
#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES
bool clipped = true;
#pragma unroll_loop
for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {
plane = clippingPlanes[ i ];
clipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;
}
if ( clipped ) discard;
#endif
#endif