Parcourir la source

fix: 将点云绘制分成普通绘制(无depth但效果好)和绘制到rt上(有depth但效果差)两种

xzw il y a 2 ans
Parent
commit
f691fee881

+ 80 - 76
libs/three.js/lines/LineMaterial.js

@@ -565,7 +565,7 @@ class LineMaterial extends ShaderMaterial {
 		} );
 
 		this.isLineMaterial = true;
-        this.lineWidth_ = 0
+        this.lineWidth_ = 0 
         this.supportExtDepth = parameters.supportExtDepth 
         this.depthTestWhenPick = false //pick时是否识别点云等
         
@@ -822,33 +822,8 @@ class LineMaterial extends ShaderMaterial {
 
 				}
 
-			}
-            ,
+			},
             
-            useDepth:{//add
-                enumerable: true,
-
-                get: function () {
-
-                    return 'useDepth' in this.defines 
-
-                },
-
-                set: function ( value ) {
-                    
-                    value = value && !!this.supportExtDepth
-                    
-                    if(value != this.useDepth){ 
-                        if(value){
-                            this.defines.useDepth = ''
-                            this.updateDepthParams()
-                        }else{
-                            delete this.defines.useDepth
-                        }
-                        this.needsUpdate = true
-                    }
-                }  
-            },
             
             dashWithDepth:{//add 
                 enumerable: true,
@@ -862,8 +837,7 @@ class LineMaterial extends ShaderMaterial {
                 set: function ( value ) {
                     
                     value = value && !!this.supportExtDepth
-                    
-                    
+                     
                     if(value != this.dashWithDepth){ 
                         if(value){
                             this.defines.DASH_with_depth = '' 
@@ -873,67 +847,97 @@ class LineMaterial extends ShaderMaterial {
                         this.needsUpdate = true
                     }
                 }  
-            },
-           
-                
-            
+            }, 
 
 		} ); 
-
-
-		this.setValues( parameters );
-        
+         
         
-            
-        let setSize = (e)=>{ 
-            let viewport = e.viewport
-            let viewportOffset = viewport.offset || new Vector2() 
-            this.uniforms.resolution.value.copy(viewport.resolution) 
-            this.uniforms.viewportOffset.value.copy(viewportOffset) 
-            this.uniforms.devicePixelRatio.value = window.devicePixelRatio
-            this.lineWidth = this.lineWidth_
+        this.events = {
+            setSize:(e)=>{//如果出现横条状的异常,往往是viewportOffset出错  //地图不需要
+                let viewport = e.viewport 
+                this.uniforms.resolution.value.copy(viewport.resolution)  
+                this.uniforms.devicePixelRatio.value = window.devicePixelRatio 
+                this.lineWidth = this.lineWidth_ //update
+                if(!this.useDepth || !e.viewport.camera.isPerspectiveCamera || !e.viewport)return
+                let viewportOffset = viewport.offset || new THREE.Vector2() 
+                this.uniforms.viewportOffset.value.copy(viewportOffset)
+                
+            },
+            render:(e)=>{//before render  如果有大于两个viewport的话,不同viewport用不同的depthTex
+                this.updateDepthParams(e)
+            } 
         }
+            
+        this.setValues( parameters );
         
-        let viewport = viewer.mainViewport;
-         
-        setSize({viewport})
-
-
-        viewer.addEventListener('resize',(e)=>{
-            setSize(e)     
-        })  
-
+        let viewport = viewer.mainViewport; 
+        this.events.setSize({viewport})  
         
+        viewer.addEventListener('resize', this.events.setSize)  
+       
         
-        if(this.supportExtDepth){
-         
-            //add
-            this.updateDepthParams()
+	}
+    
+    
+    get useDepth(){ 
+        return this.useDepth_
+    } 
+    
+      
+    
+    set useDepth(value){
+        value = value && this.supportExtDepth  //如果不支持 EXT_DEPTH 的话会失效  
+        
+        if(this.useDepth_ != value){
             
-            /* viewer.addEventListener('camera_changed', (e)=>{
-                if(e.viewport.name != 'mapViewport') this.updateDepthParams(e) 
-            })  */  
-     
+            this.setRealDepth(value) 
+            this.useDepth_ = value 
+             
+            if(value){
+                viewer.addEventListener("render.begin",  this.events.render)  
+                this.events.setSize( {viewport:viewer.mainViewport} )  
+                this.updateDepthParams() 
+            }else{
+                viewer.removeEventListener("render.begin",  this.events.render)  
+                
+            }
+        }
         
-            viewer.addEventListener("render.begin", (e)=>{//before render  如果有大于两个viewport的话,不同viewport用不同的depthTex
-                if(e.viewport.camera.isPerspectiveCamera) this.updateDepthParams(e)
-            }) 
-
+    } 
+    
+    
+    setRealDepth(useDepth){//确实使用到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
         }
- 
-
-	}
+    }
+    
+    
+    
     
     updateDepthParams(e={}){
+         
+        var viewport = e.viewport || viewer.mainViewport;
+        var camera = viewport.camera;
         
-        if(this.useDepth){ 
-            var viewport = e.viewport || viewer.mainViewport;
-            var camera = viewport.camera;
-            this.uniforms.depthTexture.value = viewer.getPRenderer().getRtEDL(viewport).depthTexture  //viewer.getPRenderer().rtEDL.depthTexture  
-            this.uniforms.nearPlane.value = camera.near; //似乎因为这个所以对OrthographicCamera 无效
-            this.uniforms.farPlane.value = camera.far; 
+        let hasDepth = this.useDepth && camera.isPerspectiveCamera && 
+                (Potree.settings.pointEnableRT || Potree.settings.displayMode == 'showPanos' || viewer.useEDL)
+        
+        this.setRealDepth(hasDepth)
+        
+        if(hasDepth){
+            this.uniforms.depthTexture.value = viewer.getPRenderer().getRtEDL(viewport).depthTexture   //其实只赋值一次就行
+            this.uniforms.nearPlane.value = camera.near;
+            this.uniforms.farPlane.value = camera.far;
         }
-            
+           
     }
 
 }

+ 3 - 2
src/ExtendPointCloudOctree.js

@@ -493,11 +493,12 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
                 let nearest = sorted1[0]  //return nearest.point;  //直接用最近点 在点云稀疏时不太跟手,如地面上,最近点往往在鼠标下方
                 
                 
+                let ratio = 0.1 //系数越大越不跟手,但更容易pick近处的。 (当pick的点较远时,获取框内的点距离可能差别很大,就要所以除以disSquare)
+                let r = rSquare/Math.max(nearest.disSquare,0.001) * ratio
                 hits.forEach( hit=>{
                     let disDiff = hit.disSquare - nearest.disSquare //和最近点的偏差 
                     hit.disDiff = disDiff 
-                    let ratio = 0.1 //系数越大越不跟手,但更容易pick近处的。 (当pick的点较远时,获取框内的点距离可能差别很大,就要所以除以disSquare)
-                    hit.score = -hit.distanceToCenter - disDiff * rSquare/Math.max(nearest.disSquare,0.001) * ratio
+                    hit.score = -hit.distanceToCenter - disDiff * r
                 })
                 
                 let sorted2 = hits.sort( (a, b) => b.score - a.score  );

+ 48 - 29
src/custom/materials/DepthBasicMaterial.js

@@ -29,8 +29,8 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
             uniforms,
             vertexShader: Shaders['depthBasic.vs'],   
             fragmentShader: Shaders['depthBasic.fs'],
-            depthWrite: !1,
-            depthTest: !1,
+            depthWrite: false,
+            depthTest: false,
             transparent: o.transparent == void 0 ?  true : o.transparent,
             side: o.side || 0 /* THREE.DoubleSide */, 
         })
@@ -49,9 +49,9 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
                 this.updateDepthParams(e)
             },
             cameraChange:(e)=>{
-                if(e.changeInfo.projectionChanged){//resize时也会触发。虽然保守起见的话加上resize比较好
+                if(e.changeInfo.projectionChanged){//resize时也会触发。虽然保守起见的话加上resize比较好//所以当时为何不用resize
                     //console.log('projectionChanged')
-                    this.events.setSize(e)
+                    this.events.setSize(e)  
                 }
             }
             
@@ -62,7 +62,7 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
         
         //-----其他----
          
-        
+        this.autoDepthTest = o.autoDepthTest
         if(o.opacity != void 0){
             this.opacity = o.opacity
         }
@@ -72,34 +72,50 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
    
     }
     
-    
-    get useDepth(){
+     
+    get useDepth(){ 
         return this.useDepth_
     } 
     
       
     
-    set useDepth(value){//如果不支持 EXT_DEPTH 的话会失效
+    set useDepth(value){
+        value = value && Features.EXT_DEPTH.isSupported()   //如果不支持 EXT_DEPTH 的话会失效  
+        
         if(this.useDepth_ != value){
-            if(value && Features.EXT_DEPTH.isSupported()){
-                this.defines.useDepth = '' 
-                //viewer.addEventListener('resize', this.events.setSize)
+            
+            this.setRealDepth(value) 
+            this.useDepth_ = value 
+             
+            if(value){
                 viewer.addEventListener("render.begin",  this.events.render) 
-                viewer.addEventListener('camera_changed', this.events.cameraChange)      
-                this.events.setSize( {viewport:viewer.mainViewport} )
+                viewer.addEventListener('camera_changed', this.events.cameraChange)  
+                this.events.setSize( {viewport:viewer.mainViewport} )  
                 this.updateDepthParams() 
-                
             }else{
-                delete this.defines.useDepth
-                //viewer.removeEventListener('resize', this.events.setSize)
                 viewer.removeEventListener("render.begin",  this.events.render)  
-                viewer.removeEventListener('camera_changed', this.events.cameraChange) 
+                viewer.removeEventListener('camera_changed', this.events.cameraChange)
             }
-            this.useDepth_ = value
-            this.needsUpdate = true
         }
+        
     } 
     
+    
+    setRealDepth(useDepth){//确实使用到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
+        }
+    }
+    
+    
+    
      
     get map(){
         return this.uniforms.map.value
@@ -141,21 +157,24 @@ export default class DepthBasicMaterial extends THREE.ShaderMaterial{
         return this
     }
     
+    
+    
+    
     updateDepthParams(e={}){//主要用于点云遮住mesh
         var viewport = e.viewport || viewer.mainViewport;
         var camera = viewport.camera;
-        if(this.useDepth && camera.isPerspectiveCamera ){   
-            /* if(Potree.settings.displayMode == 'showPanos' && viewer.images360.currentPano.depthTex){
-                this.uniforms.depthTexture.value = viewer.images360.currentPano.depthTex
-            }else{ */
-                this.uniforms.depthTexture.value = viewer.getPRenderer().getRtEDL(viewport).depthTexture   //其实只赋值一次就行
-            //}
+        
+        let hasDepth = this.useDepth && camera.isPerspectiveCamera && 
+                (Potree.settings.pointEnableRT || Potree.settings.displayMode == 'showPanos' || viewer.useEDL)
+        
+        this.setRealDepth(hasDepth)
+        
+        if(hasDepth){
+            this.uniforms.depthTexture.value = viewer.getPRenderer().getRtEDL(viewport).depthTexture   //其实只赋值一次就行
             this.uniforms.nearPlane.value = camera.near;
             this.uniforms.farPlane.value = camera.far;
-            
-        }else{
-            this.uniforms.depthTexture.value
-        }           
+        }
+              
     }
 
     

+ 4 - 1
src/custom/modules/mergeModel/MergeEditor.js

@@ -55,6 +55,9 @@ let MergeEditor = {
     
     init(){  
         { 
+        
+            Potree.settings.notAdditiveBlending = true
+        
             let ground = this.ground = new InfiniteGridHelper(1, 10000, new THREE.Color('#eee'), 10000, 0.2, 0.3)
             viewer.scene.scene.add(ground) 
             //再加两条线否则在正侧边看不到
@@ -63,7 +66,7 @@ let MergeEditor = {
             ground.renderOrder = Potree.config.renderOrders.model + 1//line1.renderOrder + 1  //要比模型低,否则模型透明时效果不对
             ground.add(line1) 
             ground.add(line2)
-             
+            ground.material.opacity = 0.9 //为了滞后渲染,否则被rt遮住
             ground.material.polygonOffset = true //多边形偏移(视觉上没有移动模型位置),防止闪烁
             ground.material.polygonOffsetFactor = 100 //多边形偏移因子
 			ground.material.polygonOffsetUnits = 10 //多边形偏移单位  

+ 1 - 1
src/custom/modules/panoEdit/panoEditor.js

@@ -704,7 +704,7 @@ class PanoEditor extends THREE.EventDispatcher{
             if(floor.panos.length == 0){
                 floor.panosBound = viewer.images360.bound.bounding.clone()
             }else{  
-                let minSize = new THREE.Vector3(5,5,5)
+                let minSize = new THREE.Vector3(10,10,10)
                 let bound = math.getBoundByPoints(floor.panos.map(e=>e.position), minSize)
                 floor.panosBound = bound.bounding
             }

+ 21 - 21
src/custom/modules/panos/Panorama.js

@@ -36,26 +36,9 @@ const labelProp2 = {
     fontsize:30,
 }
 
-let standardMarkerMat 
+ 
 let markerTex
-let getMarkerMat = function(){
-    if(!markerTex) {
-        markerTex = {
-            default:texLoader.load( Potree.resourcePath+'/textures/marker.png' ),
-            ring:texLoader.load( Potree.resourcePath+'/textures/marker2.png' )
-        }
-        markerTex.default.anisotropy = 4 // 各向异性过滤 .防止倾斜模糊
-        markerTex.ring.anisotropy = 4  
-        //有可能被点云遮住吗。 
-     
-    }
-    return  new DepthBasicMaterial({opacity: markerOpacitys.default, side: THREE.DoubleSide , map:markerTex.default ,transparent:true, 
-        clipDistance: 2,  occlusionDistance:1,  //不能设置太短,因为过渡时深度不准确
-        //depthTest: !!Potree.settings.useDepthTex,
-        useDepth:  !!Potree.settings.useDepthTex
-        //改为DepthBasicMaterial是因为原Basic的材质过渡时会先隐藏后出现
-    })    
-}
+
 //显示全景图时marker没有被遮挡,如果需要,要换成depthBasicMaterial  或者直接把skybox的深度修改(拿到深度贴图后更如此)
 let planeGeo = new THREE.PlaneBufferGeometry(0.2,0.2);
 
@@ -290,7 +273,7 @@ class Panorama extends THREE.EventDispatcher{
             //this.quaternion = quaternion
         } 
          
-        let marker = new THREE.Mesh(planeGeo, getMarkerMat() ) 
+        let marker = new THREE.Mesh(planeGeo, this.getMarkerMat() ) 
             marker.name = 'marker_'+this.id
             marker.up.set(0,0,1)
             marker.lookAt(marker.up) 
@@ -357,7 +340,24 @@ class Panorama extends THREE.EventDispatcher{
     
     
     
-    
+    getMarkerMat(){
+        if(!markerTex) {
+            markerTex = {
+                default:texLoader.load( Potree.resourcePath+'/textures/marker.png' ),
+                ring:texLoader.load( Potree.resourcePath+'/textures/marker2.png' )
+            }
+            markerTex.default.anisotropy = 4 // 各向异性过滤 .防止倾斜模糊
+            markerTex.ring.anisotropy = 4  
+            //有可能被点云遮住吗。 
+         
+        } 
+        return  new DepthBasicMaterial({opacity: markerOpacitys.default, side: THREE.DoubleSide , map:markerTex.default ,transparent:true, 
+            clipDistance: 2,  occlusionDistance:1,  //不能设置太短,因为过渡时深度不准确 
+            useDepth:  !!(Potree.settings.useDepthTex && this.pointcloud.hasDepthTex),
+            autoDepthTest:true
+            //改为DepthBasicMaterial是因为原Basic的材质在有深度图时过渡会先隐藏后出现。 注:没有深度图时全景模式的marker无法遮挡
+        })    
+    }
     
     
     

+ 9 - 1
src/custom/modules/siteModel/BuildingBox.js

@@ -96,7 +96,7 @@ let getFaceMat = (name)=>{
 				polygonOffsetUnits : -4.0,//多边形偏移单位  
                 map: gridTex,
             }), */
-            roomSelect: new DepthBasicMaterial({
+            roomSelect: new DepthBasicMaterial({  
                 map: gridTex,
                 color:"#ff44ee", 
                 side:THREE.DoubleSide,//BackSide, 
@@ -338,10 +338,18 @@ export class BuildingBox extends ctrlPolygon{//建筑实体,包括building, fl
         
         var mesh = new THREE.Mesh(geometry, this.mats.boxDefault)
         mesh.name = 'buildingBox';
+        
+        
+        
         if(this.buildType == 'floor'){
             Potree.Utils.setObjectLayers(mesh, 'siteModelMapUnvisi' ) //楼层默认在地图不显示,为了不会叠加透明度
+            //mesh.renderOrder = 1
         }else{
+            /* if(this.buildType == 'room'){
+                mesh.renderOrder = 2
+            } */
             Potree.Utils.setObjectLayers(mesh, 'bothMapAndScene' )
+            
         }
          
         

+ 5 - 0
src/custom/modules/siteModel/SiteModel.js

@@ -737,6 +737,9 @@ var SiteModel = {
     
     
     selectEntity : function(entity, state=true){
+        
+        viewer.dispatchEvent('content_changed')
+        
         if(state === false){
             entity.unselect()
             if(this.selected == entity)this.selected = null
@@ -767,6 +770,8 @@ var SiteModel = {
         if(entity && !entity.isNew && (entity.buildType == 'building' || entity.buildType == 'room' ) && entity.points.length<2){
             this.startInsertion('resume',entity)   //继续画     
         }
+        
+         
     },
     
     

+ 1 - 1
src/custom/objects/tool/Measure.js

@@ -731,7 +731,7 @@ export class Measure extends ctrlPolygon{
                     color: config.measure.default.color, 
                     lineWidth: config.measure.lineWidth,
                     useDepth :true,
-                    dashWithDepth :true,  // 只在被遮住的部分显示虚线,因为实线容易挡住label
+                    dashWithDepth :true,  // 只在被遮住的部分显示虚线,因为实线容易挡住label 
                     dashed :true,   
                     dashSize : 0.04,
                     gapSize: 0.04,    

+ 11 - 19
src/custom/objects/tool/ctrlPolygon.js

@@ -143,7 +143,7 @@ export class ctrlPolygon extends THREE.Object3D {
             this.edges = [...this.edges.slice(0,index), o.edge, ...this.edges.slice(index,this.edges.length)]
         } 
         
-        
+         
     }
     
     
@@ -600,21 +600,14 @@ export class ctrlPolygon extends THREE.Object3D {
         if(this.points.length === 0){
 			return;
 		} 
-        
-        
-        
-        
-        
+          
         let lastIndex = this.points.length - 1
-            
-       
+             
         for (let index = 0; index <= lastIndex; index++) {
             
             let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
             let previousIndex = (index === 0) ? lastIndex : index - 1;
-
-            if(!this.closed && nextIndex == 0  )break; //add
-        
+ 
             let point = this.points[index];
             let nextPoint = this.points[nextIndex];
             let previousPoint = this.points[previousIndex];
@@ -622,21 +615,20 @@ export class ctrlPolygon extends THREE.Object3D {
             if(options.ifUpdateMarkers){
                 this.updateMarker(this.markers[index], point)
             }   
-
+            
+            
+            if(!this.closed && nextIndex == 0  )break; //add
             { // edges
                 let edge = this.edges[index]; 
                 if(edge){
                     LineDraw.updateLine(edge, [point, nextPoint]) 
                     //edge.visible = index < lastIndex || this.isRect || (this.closed && !this.isNew);
-                }
-                
-                
-            }
-
-            
-             
+                } 
+            }  
         }
         
+        
+        
         if(this.areaPlane){
             this.updateAreaPlane() 
         }

+ 5 - 4
src/custom/potree.shim.js

@@ -46,7 +46,7 @@ var texLoader = new THREE.TextureLoader()
         button,设置按下了哪一个鼠标按键,默认为0。-1表示没有按键,0表示按下主键(通常是左键),1表示按下辅助键(通常是中间的键),2表示按下次要键(通常是右键)
      */
          
-    
+    Potree.browser = browser
 
     /////////// add ////////////////////////////////// 
     Potree.defines.GLCubeFaces = {
@@ -995,7 +995,7 @@ Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
 	let priorityQueue = new BinaryHeap(function (x) { return 1 / x.weight; });//二叉堆。
 
                 
-  
+    viewer.addTimeMark('visiStructure','start')
 
     //camera.updateMatrixWorld();
     let viewI = camera.matrixWorldInverse;
@@ -1078,7 +1078,7 @@ Potree.updateVisibilityStructures = function(pointclouds, camera, areaSize) {
 		}
 	}
 
- 
+    viewer.addTimeMark('visiStructure','end')
       
 	return {
 		'frustums': frustums,
@@ -1307,7 +1307,8 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
 				node = pointcloud.toTreeNode(node, parent);
 				loadedToGPUThisFrame++;
 			} else {
-				unloadedGeometry.push({pointcloud,node});   //加载点云
+                //console.log('unloadedGeometry',node)
+				unloadedGeometry.push({pointcloud,node});   //加载点云。虽然还没加载,但也计入了visibleNodes,只是无children,numPoints=0
 				visibleGeometry.push(node);
 			}
 		}

+ 8 - 4
src/custom/settings.js

@@ -211,7 +211,7 @@ const config = {//配置参数   不可修改
         pointcloud: 11,
         sceneObjects:0,//default
         model : 2,   
-        
+        light: 15, 
         measure:4,  
         magnifier:5, 
         magnifierContent:16,
@@ -229,8 +229,8 @@ const config = {//配置参数   不可修改
         siteModeSideVisi:14,//只有侧面可见
         
         
-        layer1: 10,// 备用1
-        layer2: 15,// 备用2
+        layer1: 18,// 备用1
+        layer2: 17,// 备用2
     },
     
     renderOrders:{ //会影响到绘制、pick时的顺序。
@@ -427,7 +427,11 @@ let settings = {//设置   可修改
     precision:2,  // 两位小数 
     useV4url:true, //v4的全景图等路径不一样 scene_view_data
     
-    useRTskybox:true,  //直接使用rtEDL绘制到屏幕,当是全景模式时. 在降4倍时能给render节省1毫秒
+    useRTskybox:true,  //直接使用rtEDL绘制到屏幕,当是全景模式时. 在降4倍时能给render节省1毫秒,gpu时间未测
+    useRTPoint:true,    //直接使用rtEDL绘制到屏幕,当是点云模式时。可以大大节省gpu时间
+    pointEnableRT:false,//点云是否允许绘制到rtEDL。只在有需要时使用
+    
+    
     showCompass : isTest,
     showAxis : isTest,
     //testCube : true,

+ 49 - 0
src/custom/three.shim.js

@@ -238,6 +238,55 @@ THREE.Object3D.prototype.traverse = function ( callback ) {
 
 
 
+THREE.Material.prototype.setValues = function ( values ) {
+
+    if ( values === undefined ) return;
+
+    for ( const key in values ) {
+
+        const newValue = values[ key ];
+
+        if ( newValue === undefined ) {
+
+            console.warn( 'THREE.Material: \'' + key + '\' parameter is undefined.' );
+            continue;
+
+        }
+
+        // for backward compatability if shading is set in the constructor
+        if ( key === 'shading' ) {
+
+            console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
+            this.flatShading = ( newValue === FlatShading ) ? true : false;
+            continue;
+
+        }
+
+        const currentValue = this[ key ]; 
+
+        /* if ( currentValue === undefined ) { //-----主要删了这段,否则很难和 set 一起使用
+
+            //console.warn( 'THREE.' + this.type + ': \'' + key + '\' is not a property of this material.' );
+            continue; 
+        } */
+
+        if ( currentValue && currentValue.isColor ) {
+
+            currentValue.set( newValue );
+
+        } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
+
+            currentValue.copy( newValue );
+
+        } else {
+
+            this[ key ] = newValue;
+
+        }
+
+    }
+
+} 
 
 
 

+ 1 - 1
src/custom/utils/DrawUtil.js

@@ -82,7 +82,7 @@ var LineDraw = {
             //默认
             lineWidth : 5,  
             color:0xffffff,
-            transparent : true, depthWrite:false,  depthTest:false,
+            transparent : true,  depthWrite:false,  depthTest:false,
             dashSize : 0.1, gapSize:0.1, 
         }, o, {
             //修正覆盖:

+ 58 - 11
src/custom/viewer/ViewerNew.js

@@ -166,7 +166,7 @@ export class Viewer extends ViewerBase{
 		$(domElement).append(this.elMessages);
 		
          
-        this.paused  
+        this.fakeMeasure = {};
          
         document.addEventListener('visibilitychange',(e)=>{ 
             //console.log('visibilitychange', !document.hidden )
@@ -2853,7 +2853,10 @@ export class Viewer extends ViewerBase{
         
         this.renderer.setRenderTarget(null)
         this.needRender = false
-		 
+        
+        viewer.scene.pointclouds[0] && this.addFakeMeasure('visibleNodes', viewer.scene.pointclouds[0].visibleNodes.length )// 
+        this.addFakeMeasure('numVisiblePoints', Potree.numVisiblePoints/100000)//十万  numVisiblePoints和帧率成反比(若每一帧都render的话),和render用时成正比 (y=kn+b)。但visibleNodes个数也影响,多的话也更卡。visibleNodes和numVisiblePoints不成正比,少的visibleNodes可能numVisiblePoints多
+      
         viewer.addTimeMark('renderDefault','end')
 	}
     
@@ -2957,8 +2960,14 @@ export class Viewer extends ViewerBase{
 
         if(params.cameraLayers) cameraLayers = params.cameraLayers
         else{
-            if(params.viewport.name == "mapViewport" )cameraLayers = ['bothMapAndScene']
-            else cameraLayers = ['sceneObjects',   'model',  'bothMapAndScene' ];
+            if(params.viewport.name == "mapViewport" )cameraLayers = ['bothMapAndScene', 'light']
+            else {
+                cameraLayers = ['sceneObjects', 'light', 'bothMapAndScene' ];
+                if(!params.drawedModelOnRT){
+                     cameraLayers.push('model')
+                } 
+            }
+            
         }
         
          
@@ -3052,7 +3061,16 @@ export class Viewer extends ViewerBase{
 	render(params={}){//add params 
         viewer.addTimeMark('render','start')
         const vrActive = this.renderer.xr.isPresenting;
-
+        let SiteModel = viewer.modules.SiteModel 
+        
+        
+        Potree.settings.useRTPoint = !(SiteModel.editing && SiteModel.selected && SiteModel.selected.buildType == 'room' )//空间模型的房间选中材质是需要depth的,这时候需要绘制两次点云
+        
+        Potree.settings.pointEnableRT = this.scene.measurements.length > 0 || !Potree.settings.useRTPoint 
+        
+        
+        
+        
         if(vrActive){
             this.renderVR();
         }else{
@@ -3747,7 +3765,18 @@ export class Viewer extends ViewerBase{
             }
         } 
     }    
-
+    
+    
+    addFakeMeasure(name,duration){//把一些count当做duration来统计
+        if(!Potree.measureTimings)return
+        if(!this.fakeMeasure[name]){ 
+            this.fakeMeasure[name] = []
+        }
+        let object = {
+            name, duration
+        }
+        this.fakeMeasure[name].push(object)
+    }
 
 	resolveTimings(timestamp,log){//打印用时。   注:performance手机的精度只到整数位 。 sidebar中监听update时有高cpu的函数所以不要用demo测
 		 
@@ -3758,6 +3787,10 @@ export class Viewer extends ViewerBase{
         if(duration > 1000.0){
             if(log){
                 let measures = performance.getEntriesByType("measure");
+                for(let i in this.fakeMeasure){
+                    measures.push(...this.fakeMeasure[i])
+                }
+                
                 
                 let names = new Set();
                 for(let measure of measures){
@@ -3784,6 +3817,9 @@ export class Viewer extends ViewerBase{
                     group.max = Math.max(group.max, measure.duration);
                 }
 
+
+                 
+
                 /* let glQueries = Potree.resolveQueries(this.renderer.getContext());  // resolveQueries 无
                 for(let [key, value] of glQueries){
 
@@ -3802,14 +3838,25 @@ export class Viewer extends ViewerBase{
                 
                 for(let [name, group] of groups){
                     group.mean = group.sum / group.n;
-                    group.measures.sort( (a, b) => a.duration - b.duration );
+                    /* group.measures.sort( (a, b) => a.duration - b.duration );
                     
                     if(group.n === 1){
                         group.median = group.measures[0].duration;
                     }else if(group.n > 1){
                         group.median = group.measures[parseInt(group.n / 2)].duration;
                     }
+                     */
+                    let measures = group.measures.slice()
+                    measures.sort( (a, b) => a.duration - b.duration );
+                    
+                    if(group.n === 1){
+                        group.median = measures[0].duration;
+                    }else if(group.n > 1){
+                        group.median = measures[parseInt(group.n / 2)].duration;
+                    }
                     
+                     
+                     
                 }
                 
                 let cn = Array.from(names).reduce( (a, i) => Math.max(a, i.length), 0) + 5;
@@ -3846,9 +3893,7 @@ export class Viewer extends ViewerBase{
                 console.log(message);
             }
             
-            
-            
-            
+            this.fakeMeasure = {}  //clear
             performance.clearMarks();
             performance.clearMeasures();
             this.toggle = timestamp;
@@ -3861,8 +3906,9 @@ export class Viewer extends ViewerBase{
         //let startTime = performance.now()
         //console.log('间隔:' ,parseInt((startTime - this.lastEndTime)*100 )/100)
         
+        if(performance.getEntriesByName("loopWaitNext-start").length)viewer.addTimeMark('loopWaitNext','end') 
         
-        
+         
 		if(this.stats){
 			this.stats.begin();
 		}
@@ -3909,6 +3955,7 @@ export class Viewer extends ViewerBase{
         
        
         viewer.addTimeMark('loop','end')
+        viewer.addTimeMark('loopWaitNext','start')
 		this.resolveTimings(timestamp, Potree.measureTimings);
 
 	}

+ 1 - 1
src/navigation/InputHandlerNew.js

@@ -1347,7 +1347,7 @@ export class InputHandler extends THREE.EventDispatcher {
             intersections = intersections.filter(e=>{
                 let material = e.object.material
                 
-                return e.object.pickDontCheckDis || ( material.depthTest == false || material.depthWrite == false) && !material.useDepth  //!material.depthTestWhenPick
+                return e.object.pickDontCheckDis || ( material.depthTest == false || material.depthWrite == false) && !material.realUseDepth  //!material.depthTestWhenPick
                  || ( material.useDepth ? e.distance < this.intersect.distance + material.uniforms.occlusionDistance.value : e.distance < this.intersect.distance )
             }) 
         }

+ 41 - 27
src/viewer/EDLRendererNew.js

@@ -46,7 +46,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
             fragmentShader: copyShader.fragmentShader, 
             transparent: true,         
             defines:{
-                useDepth: true
+                useDepth: true  //开启后,其他物体才能被遮挡
             }            
         })
         /*  let copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
@@ -61,7 +61,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                 depthTest: false,
                 depthWrite: false
             }); */
-        if(Potree.settings.useRTskybox){
+        if(Potree.settings.useRTskybox != Potree.settings.useRTPoint){//如果两个只开了一个
             viewer.images360.addEventListener('endChangeMode',()=>{
                 this.resize({viewport:viewer.mainViewport})
             }) 
@@ -72,7 +72,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 	resize(e){
         if(Features.EXT_DEPTH.isSupported()){  
             let viewport = e.viewport
-            let size = Potree.settings.useRTskybox && Potree.settings.displayMode == 'showPanos' ? viewport.resolution2 : viewport.resolution; //若要渲染skybox,需要和设备一样精度的rt
+            let size = ( Potree.settings.displayMode == 'showPanos' ? Potree.settings.useRTskybox : Potree.settings.useRTPoint) ? viewport.resolution2 : viewport.resolution; //若要渲染skybox,需要和设备一样精度的rt
             this.getRtEDL(viewport).setSize( size.x, size.y  );   //理论上可以是任意尺寸,但会影响精度,且aspect最好和渲染的一致
         }
 	}
@@ -192,7 +192,8 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
         const viewer = this.viewer; 
 		let camera = params.camera ? params.camera : viewer.scene.getActiveCamera();
 		const resolution = params.viewport ? params.viewport.resolution : this.viewer.renderer.getSize(new THREE.Vector2());//突然发现mobile用resolution2点云会放大
-        let rtEDL = Features.EXT_DEPTH.isSupported() && camera.type != "OrthographicCamera" && !params.dontRenderRtEDL && (params.rtEDL || this.getRtEDL(params.viewport))  // 平面相机不用depthTex直接打开depthTest?且不使用edl
+        let rtEDL = (Potree.settings.pointEnableRT || Potree.settings.displayMode == 'showPanos' || viewer.useEDL) && 
+                    Features.EXT_DEPTH.isSupported() && camera.type != "OrthographicCamera" && !params.dontRenderRtEDL && (params.rtEDL || this.getRtEDL(params.viewport))  // 平面相机不用depthTex直接打开depthTest?且不使用edl
         let useEDL = viewer.useEDL && rtEDL && Potree.settings.displayMode != 'showPanos'
         let target = params.target || null
         viewer.renderer.setRenderTarget(target);
@@ -207,28 +208,31 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 		}); */
     
         //skybox  全景图
-        if(!params.magnifier){
-            Potree.Utils.setCameraLayers(camera, ['skybox'])
-            let useDepthTex
-            if(Potree.settings.displayMode == 'showPanos' && viewer.images360.currentPano.pointcloud.hasDepthTex && rtEDL){//渲染深度图
-                useDepthTex = true
-             
-                viewer.renderer.setRenderTarget(rtEDL) //将带有深度图的skybox画在rtEDL一下,这样就不需要绘制后边的点云了
-                viewer.renderer.render(viewer.scene.scene, camera);
-                viewer.renderer.setRenderTarget(target);
-                
-                if(Potree.settings.useRTskybox){//直接使用rtEDL,但是会失去抗锯齿,不知在skybox上需要抗锯齿吗
-                    this.recoverToScreenMat.uniforms.depthTex.value = rtEDL.depthTexture
-                    this.recoverToScreenMat.uniforms.tDiffuse.value = rtEDL.texture  
-                    Utils.screenPass.render(viewer.renderer, this.recoverToScreenMat, target);  
+        if(!params.magnifier){ 
+            if(Potree.settings.displayMode == 'showPanos' || Potree.settings.testCube){
+                 
+                Potree.Utils.setCameraLayers(camera, ['skybox'])
+            
+                if(Potree.settings.displayMode == 'showPanos' && viewer.images360.currentPano.pointcloud.hasDepthTex && rtEDL){//渲染深度图
+                     
+                    viewer.renderer.setRenderTarget(rtEDL) //将带有深度图的skybox画在rtEDL一下,这样就不需要绘制后边的点云了
+                    viewer.renderer.render(viewer.scene.scene, camera);
+                    viewer.renderer.setRenderTarget(target);
+                    
+                    if(Potree.settings.useRTskybox){//直接使用rtEDL,但是会失去抗锯齿,不知在skybox上需要抗锯齿吗
+                        this.recoverToScreenMat.uniforms.depthTex.value = rtEDL.depthTexture
+                        this.recoverToScreenMat.uniforms.tDiffuse.value = rtEDL.texture  
+                        Utils.screenPass.render(viewer.renderer, this.recoverToScreenMat, target);  
+                    }else{
+                        viewer.renderer.render(viewer.scene.scene, camera);
+                    }
+                    return
                 }else{
                     viewer.renderer.render(viewer.scene.scene, camera);
-                }
-            }else{
-                viewer.renderer.render(viewer.scene.scene, camera);
-            }                
+                }     
+                 
+            }
             
-            if(useDepthTex)return 
         }  
          
         
@@ -268,7 +272,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 			}
 
              
-            if(rtEDL/* Features.EXT_DEPTH.isSupported() && !params.dontRenderRtEDL */){ //借用rtEDL存储深度信息  
+            if(rtEDL ){ //借用rtEDL存储深度信息  
                 viewer.renderer.setRenderTarget( rtEDL );
                 
                 if(visiblePointClouds2.length>0){  //渲染scenePointCloud到rtEDL
@@ -279,7 +283,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                     });
                 } 
                 if(Potree.settings.intersectOnObjs){// model也要渲染到rtEDL
-                    camera.layers.set(Potree.config.renderLayers.model);
+                    Potree.Utils.setCameraLayers(camera, ['model','light'])  
                     viewer.objs.traverse(e=>{if(e.material)e._OlddepthWrite = e.material.depthWrite, e.material.depthWrite = true}) //否则半透明的mesh无法遮住测量线
                     viewer.renderer.render(viewer.scene.scene, camera);
                     viewer.objs.traverse(e=>{if(e.material)e.material.depthWrite = e._OlddepthWrite})
@@ -299,7 +303,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
          
         
         if(showPointClouds){ //绘制点云到画布
-            if(useEDL) {  //设置edlMaterial  //Features.EXT_DEPTH不支持的话不会到这一块
+            if(useEDL){  //设置edlMaterial  //Features.EXT_DEPTH不支持的话不会到这一块
                  
                 const uniforms = this.edlMaterial.uniforms; 
                 uniforms.resolution.value.copy(resolution) 
@@ -314,8 +318,18 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
              
                 uniforms.uEDLColor.value = rtEDL.texture; 
                 uniforms.opacity.value = viewer.edlOpacity; // HACK 
+                 
                 Utils.screenPass.render(viewer.renderer, this.edlMaterial, target);  //相当于一个描边后期特效。 缺点: 因为target上的没有抗锯齿,所以点云在晃动镜头时会不稳定地闪烁1px位置。优点:比不打开edl少绘制一次点云,更流畅了?!
-            }else{ 
+            }else if(Potree.settings.useRTPoint && rtEDL){ 
+            
+                this.recoverToScreenMat.uniforms.tDiffuse.value = rtEDL.texture; 
+                if(this.recoverToScreenMat.defines.useDepth){
+                    this.recoverToScreenMat.uniforms.depthTex.value = rtEDL.depthTexture; 
+                }
+                 
+                Utils.screenPass.render(viewer.renderer, this.recoverToScreenMat, target);
+                params.drawedModelOnRT = true
+            }else{
                 //渲染点云 (直接用rtEDL上的会失去抗锯齿, 导致频闪、密集时出现条纹,  自己写抗锯齿也要渲染好几次。另外透明度也要处理下) 
                    
                 let prop = {

+ 2 - 2
src/viewer/ExtendScene.js

@@ -154,12 +154,12 @@ class ExtendScene extends Scene{
         
         //add:------给空间模型的box 或其他obj------
         let light2 = new THREE.AmbientLight( 16777215, 1 );
-        Potree.Utils.setObjectLayers(light2, 'bothMapAndScene')
+        Potree.Utils.setObjectLayers(light2, 'light'/* 'bothMapAndScene' */)
         this.scene.add(light2)
         let light3 = new THREE.DirectionalLight( 16777215, 1);  
         light3.position.set( 10, 10, 10 );
 		light3.lookAt( new THREE.Vector3(0, 0, 0));
-        Potree.Utils.setObjectLayers(light3, 'bothMapAndScene')
+        Potree.Utils.setObjectLayers(light3, 'light')
         this.scene.add(light3)  
         //--------------------------------------------
 

+ 57 - 0
改bug的历史.txt

@@ -1,3 +1,60 @@
+2023.2.17
+
+现象:转动过程中,面对相同的一块点云,有时候很流畅,有时候反向再转回去超级卡,但numVisiblePoints并无增加。
+
+如数据:
+ NAME                  |    MIN | MEDIAN |    MAX |    AVE | SAMPLES 
+ ----------------------------------------------------------------------
+ loop                  |  0.700 |  7.300 | 11.500 |  7.322 |   50
+ loopWaitNext          |  6.200 | 10.300 | 41.500 | 13.804 |   49
+ mapRender             |  0.200 |  0.300 |  0.600 |  0.321 |   47
+ numVisiblePoints      | 59.614 | 59.939 | 59.996 | 59.934 |   47
+ render                |  0.000 |  6.300 |  9.500 |  6.134 |   50
+ renderDefault         |  4.500 |  6.300 |  9.400 |  6.519 |   47
+ renderNodes           |  1.300 |  2.200 |  3.500 |  2.233 |   94
+ renderOctree          |  0.000 |  0.000 |  0.100 |  0.027 |   94
+ renderOverlay         |  0.100 |  0.300 |  0.500 |  0.306 |   47
+ update                |  0.500 |  0.900 |  1.700 |  0.958 |   50
+ updateClouds          |  1.100 |  1.200 |  1.800 |  1.340 |   47
+ visiStructure         |  0.000 |  0.100 |  0.300 |  0.140 |   47
+ visibleNodes          | 536.000 | 544.000 | 554.000 | 544.426 |   47
+
+
+NAME                  |    MIN | MEDIAN |    MAX |    AVE | SAMPLES 
+ ----------------------------------------------------------------------
+ loop                  |  5.700 |  6.500 |  9.300 |  6.952 |   21
+ loopWaitNext          | 40.700 | 43.500 | 44.200 | 43.100 |   20
+ mapRender             |  0.200 |  0.300 |  0.400 |  0.295 |   21
+ numVisiblePoints      | 59.880 | 59.959 | 59.999 | 59.955 |   21
+ render                |  4.700 |  5.300 |  8.100 |  5.781 |   21
+ renderDefault         |  4.700 |  5.300 |  8.100 |  5.776 |   21
+ renderNodes           |  1.300 |  1.700 |  2.900 |  1.867 |   42
+ renderOctree          |  0.000 |  0.000 |  0.100 |  0.033 |   42
+ renderOverlay         |  0.200 |  0.300 |  0.300 |  0.257 |   21
+ update                |  0.600 |  0.900 |  1.200 |  0.948 |   21
+ updateClouds          |  1.100 |  1.400 |  1.800 |  1.405 |   21
+ visiStructure         |  0.100 |  0.200 |  0.200 |  0.152 |   21
+ visibleNodes          | 528.000 | 533.000 | 540.000 | 533.286 |   21
+
+
+这两个数据numVisiblePoints、visibleNodes相差很小,但是渲染时间却迥异,为何?
+再怎么卡,loopWaitNext也只需要等待一轮回,也就是小于16.6*2即可,这里却达到40!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 2023.2.7