自定义裁切面在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