看懂Threejs材质中深度测试相关参数

您所在的位置:网站首页 深度检测 看懂Threejs材质中深度测试相关参数

看懂Threejs材质中深度测试相关参数

2024-03-07 19:02| 来源: 网络整理| 查看: 265

深度测试介绍

3维场景中要绘制物体的遮挡关系,就离不开深度测试

深度测试的简单解释(抛开透明等情况): 如果开启了深度测试,每个片元就要拿自己的深度值,跟深度缓冲区中对应位置的深度值比较,如果自己离屏幕更近(默认的比较方式),且开启了深度写入,就会把深度缓冲区中这块位置的深度值替换成自己的深度值,让自己成为标杆,并有机会展示到屏幕上,后面只有这块位置比自己离屏幕更近的,才有机会替换掉自己展示到屏幕上,如果没开启深度测试,则会按绘制顺序,后面绘制的覆盖前面的

three材质相关的参数可以影响深度测试,这些参数,作用于使用这个材质的物体,原理就是控制前面提到的深度相关的的开启与写入

示例代码介绍

后面的示例都会基于此,绘制存在遮挡关系的正方体跟圆柱体,绘制顺序很重要,先绘制的正方体,后绘制的圆柱体

image.png

代码片段 // 正方体 const cubeGeometry = new THREE.BoxGeometry(200, 200, 200) // 正方体材质 const cubeMaterial = new THREE.MeshLambertMaterial({ color: 0x00ff00 }) const cube = new THREE.Mesh(cubeGeometry, cubeMaterial) scene.add(cube) // 圆柱体 const cyGeometry = new THREE.CylinderGeometry(50, 50, 300, 32) const cyMaterial = new THREE.MeshLambertMaterial({ color: 0xffff00 }) // 圆柱体材质 const cylinder = new THREE.Mesh(cyGeometry, cyMaterial) cylinder.rotateX(Math.PI / 2) scene.add(cylinder) 深度测试相关参数介绍 depthTest

作用:决定在渲染此材质时是否启用深度测试,

源码部分

开启深度测试本质是调用的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 })

image.png

depthWrite

作用:是否可以深度写入

源码部分

本质调用的是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 })

image.png

depthFunc

深度测试函数 作用:默认为LessEqualDepth, 材质使用这些深度函数来比较输入像素和缓冲器中深度的值。 如果比较的结果为true,则将绘制像素。 也就是说深度测试是有规则的,只是默认绘制最近的,可以修改规则

可选择的函数 THREE.NeverDepth THREE.AlwaysDepth THREE.LessDepth THREE.LessEqualDepth THREE.GreaterEqualDepth THREE.GreaterDepth THREE.NotEqualDepth

image.png

源码部分

本质的调用的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 })

image.png



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3