看懂Threejs材质中深度测试相关参数 |
您所在的位置:网站首页 › 深度检测 › 看懂Threejs材质中深度测试相关参数 |
深度测试介绍
3维场景中要绘制物体的遮挡关系,就离不开深度测试 深度测试的简单解释(抛开透明等情况): 如果开启了深度测试,每个片元就要拿自己的深度值,跟深度缓冲区中对应位置的深度值比较,如果自己离屏幕更近(默认的比较方式),且开启了深度写入,就会把深度缓冲区中这块位置的深度值替换成自己的深度值,让自己成为标杆,并有机会展示到屏幕上,后面只有这块位置比自己离屏幕更近的,才有机会替换掉自己展示到屏幕上,如果没开启深度测试,则会按绘制顺序,后面绘制的覆盖前面的 three材质相关的参数可以影响深度测试,这些参数,作用于使用这个材质的物体,原理就是控制前面提到的深度相关的的开启与写入 示例代码介绍后面的示例都会基于此,绘制存在遮挡关系的正方体跟圆柱体,绘制顺序很重要,先绘制的正方体,后绘制的圆柱体 作用:决定在渲染此材质时是否启用深度测试, 源码部分开启深度测试本质是调用的gl.enable(gl.DEPTH_TEST) setTest: function ( depthTest ) { if ( depthTest ) { enable( gl.DEPTH_TEST ); } else { disable( gl.DEPTH_TEST ); } } function enable( id ) { if ( enabledCapabilities[ id ] !== true ) { gl.enable( id ); enabledCapabilities[ id ] = true; } } function disable( id ) { if ( enabledCapabilities[ id ] !== false ) { gl.disable( id ); enabledCapabilities[ id ] = false; } } 效果展示使用此参数使圆柱不被遮挡,可以关闭圆柱的深度测试,这样圆柱的绘制,就变成了不按照前后位置关系绘制,而是按照渲染的前后顺序绘制,这样后绘制的圆柱就可以覆盖正方体了 const cyMaterial = new THREE.MeshLambertMaterial({ ... depthTest: false })作用:是否可以深度写入 源码部分本质调用的是gl.depthMask( false ),使深度缓冲区变为只读 depthBuffer.setMask( material.depthWrite ); setMask: function ( depthMask ) { if ( currentDepthMask !== depthMask && ! locked ) { gl.depthMask( depthMask ); currentDepthMask = depthMask; } }, 效果展示上一节为了让圆柱不被遮挡,是处理了圆柱,我们也可以处理正方体使其挡不住圆柱,阻止正方体的深度值写入,这样深度缓冲区中对应位置存的是圆柱的深度信息,圆柱变成了离屏幕最近的,就不会被遮挡了 const cubeMaterial = new THREE.MeshLambertMaterial({ ... depthWrite: false })深度测试函数 作用:默认为LessEqualDepth, 材质使用这些深度函数来比较输入像素和缓冲器中深度的值。 如果比较的结果为true,则将绘制像素。 也就是说深度测试是有规则的,只是默认绘制最近的,可以修改规则 可选择的函数 THREE.NeverDepth THREE.AlwaysDepth THREE.LessDepth THREE.LessEqualDepth THREE.GreaterEqualDepth THREE.GreaterDepth THREE.NotEqualDepth本质的调用的gl.depthFunc setFunc: function ( depthFunc ) { if ( currentDepthFunc !== depthFunc ) { if ( depthFunc ) { switch ( depthFunc ) { case NeverDepth: gl.depthFunc( gl.NEVER ); break; case AlwaysDepth: gl.depthFunc( gl.ALWAYS ); break; case LessDepth: gl.depthFunc( gl.LESS ); break; case LessEqualDepth: gl.depthFunc( gl.LEQUAL ); break; case EqualDepth: gl.depthFunc( gl.EQUAL ); break; case GreaterEqualDepth: gl.depthFunc( gl.GEQUAL ); break; case GreaterDepth: gl.depthFunc( gl.GREATER ); break; case NotEqualDepth: gl.depthFunc( gl.NOTEQUAL ); break; default: gl.depthFunc( gl.LEQUAL ); } } else { gl.depthFunc( gl.LEQUAL ); } currentDepthFunc = depthFunc; } } 效果展示修改圆柱的测试函数为NotEqualDepth,因为取的差集,圆柱被遮挡部分也显示出来了,但是重叠部分会显示正方体的部分,也就是那条绿色切割线 const cyMaterial = new THREE.MeshLambertMaterial({ .... depthFunc: THREE.NotEqualDepth }) |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |