import * as THREE from "../../../libs/three.js/build/three.module.js"; import {Shaders} from "../../../build/shaders/shaders.js"; import {Features} from "../../Features.js"; export default class DepthBasicMaterial extends THREE.ShaderMaterial{ constructor(o={}){ let {width, height} = viewer.renderer.getSize(new THREE.Vector2()); let uniforms = { resolution: { type: 'v2', value: new THREE.Vector2(width, height ) }, viewportOffset: { type: 'v2', value: new THREE.Vector2(0, 0 ) }, //left, top uUseOrthographicCamera:{ type: "b", value: false }, nearPlane: { type: 'f', value: 0.1 }, farPlane: { type: 'f', value: 10000 }, depthTexture: { type: 't', value: null }, opacity: { type: 'f', value: 1 }, map: { type: 't', value: o.map }, baseColor: {type:'v3', value: o.color ? new THREE.Color(o.color) : new THREE.Color("#ffffff")}, backColor: {type:'v3', value: o.backColor ? new THREE.Color(o.backColor) : new THREE.Color("#ddd")}, clipDistance : { type: 'f', value: o.clipDistance || 4 }, //消失距离 occlusionDistance : { type: 'f', value: o.occlusionDistance || 1 }, //变为backColor距离 maxClipFactor : { type: 'f', value: o.maxClipFactor || 1 }, //0-1 maxOcclusionFactor : { type: 'f', value: o.maxOcclusionFactor || 1 }, //0-1 //-------add:----- replaceColor : {type:'v3', value: o.replaceColor ? new THREE.Color(o.replaceColor) : null}, beReplacedRed : {type:'f', value: o.beReplacedRed}, mapScale: { type: 'f', value: o.mapScale || 1 }, //0-1 } super({ uniforms, vertexShader: Shaders['depthBasic.vs'], fragmentShader: Shaders['depthBasic.fs'], depthWrite: false, depthTest: false, transparent: o.transparent == void 0 ? true : o.transparent, side: o.side || 0 /* THREE.DoubleSide */, }) this.events = { setSize:(e)=>{//如果出现横条状的异常,往往是viewportOffset出错 //地图不需要 if(!this.realUseDepth || !e.viewport)return let viewport = e.viewport let viewportOffset = viewport.offset || new THREE.Vector2() this.uniforms.resolution.value.copy(viewport.resolution2) //2023.6.12突然发现ratio>1的用resolution不对,得用2才对。但是之前明明记得不是这样 this.uniforms.viewportOffset.value.copy(viewportOffset) }, render:(e)=>{//before render 如果有大于两个viewport的话,不同viewport用不同的depthTex this.updateDepthParams(e) }, /* cameraChange:(e)=>{ if(e.changeInfo.projectionChanged){//resize时也会触发。虽然保守起见的话加上resize比较好//所以当时为何不用resize //console.log('projectionChanged') this.events.setSize(e) } } */ } if(o.mapColorReplace){ this.defines.mapColorReplace = '' } //-----其他---- this.autoDepthTest = o.autoDepthTest if(o.opacity != void 0){ this.opacity = o.opacity } this.useDepth = o.useDepth this.map = o.map } get useDepth(){ return this.useDepth_ } set useDepth(value){ value = value && Features.EXT_DEPTH.isSupported() //如果不支持 EXT_DEPTH 的话会失效 if(this.useDepth_ != value){ this.setRealDepth(value) this.useDepth_ = value if(value){ viewer.addEventListener("render.begin", this.events.render) //viewer.addEventListener('camera_changed', this.events.cameraChange) viewer.addEventListener('resize', this.events.setSize) this.updateDepthParams() }else{ viewer.removeEventListener("render.begin", this.events.render) viewer.removeEventListener('resize', this.events.setSize) } } } setRealDepth(useDepth, viewport){//确实使用到depthTex if(this.realUseDepth != useDepth){ if(useDepth ){ this.defines.useDepth = '' }else{ delete this.defines.useDepth } this.realUseDepth = useDepth if(this.autoDepthTest)this.depthWrite = this.depthTest = !useDepth //如果useDepth = false,使用原始的depthTest this.needsUpdate = true if(!viewport)viewport = viewer.mainViewport //暂时这么设置 useDepth && this.events.setSize({viewport}) } } get map(){ return this.uniforms.map.value } set map(map){ this.uniforms.map.value = map; if(map){ this.defines.use_map = '' }else{ delete this.defines.use_map } } get opacity(){ return this.uniforms.opacity.value } set opacity(o){ this.uniforms && (this.uniforms.opacity.value = o) } get color(){ return this.uniforms.baseColor.value } set color(c){ this.uniforms && (this.uniforms.baseColor.value.set(c)) } /* dispose(){ super.dispose() viewer.depthBasic } */ copy(source){ super.copy(source) this.useDepth = source.useDepth this.map = source.map return this } updateDepthParams(e={}){//主要用于点云遮住mesh var viewport = e.viewport || viewer.mainViewport; var camera = viewport.camera; /* let hasDepth = this.useDepth && (Potree.settings.pointEnableRT || Potree.settings.displayMode == 'showPanos' || viewer.useEDL) */ //深度图不准确 let hasDepth = this.useDepth && Potree.settings.displayMode == 'showPointCloud' && (Potree.settings.pointEnableRT || viewer.useEDL) this.setRealDepth(hasDepth, viewport) if(hasDepth){ this.uniforms.depthTexture.value = viewer.getPRenderer().getRtEDL(viewport).depthTexture //其实只赋值一次就行 this.uniforms.nearPlane.value = camera.near; this.uniforms.farPlane.value = camera.far; } this.uniforms.uUseOrthographicCamera.value = !camera.isPerspectiveCamera } }