HQSplatRenderer.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. import * as THREE from "../../libs/three.js/build/three.module.js";
  2. import {NormalizationMaterial} from "../materials/NormalizationMaterial.js";
  3. import {NormalizationEDLMaterial} from "../materials/NormalizationEDLMaterial.js";
  4. import {PointCloudMaterial} from "../materials/PointCloudMaterial.js";
  5. import {PointShape} from "../defines.js";
  6. import {SphereVolume} from "../utils/Volume.js";
  7. import {Utils} from "../utils.js";
  8. //在potree.shim中修改。。official中用不到
  9. export class HQSplatRenderer{
  10. constructor(viewer){
  11. this.viewer = viewer;
  12. this.depthMaterials = new Map();
  13. this.attributeMaterials = new Map();
  14. this.normalizationMaterial = null;
  15. this.rtDepth = null;
  16. this.rtAttribute = null;
  17. this.gl = viewer.renderer.getContext();
  18. this.initialized = false;
  19. }
  20. init(){
  21. if (this.initialized) {
  22. return;
  23. }
  24. this.normalizationMaterial = new NormalizationMaterial();
  25. this.normalizationMaterial.depthTest = true;
  26. this.normalizationMaterial.depthWrite = true;
  27. this.normalizationMaterial.transparent = true;
  28. this.normalizationEDLMaterial = new NormalizationEDLMaterial();
  29. this.normalizationEDLMaterial.depthTest = true;
  30. this.normalizationEDLMaterial.depthWrite = true;
  31. this.normalizationEDLMaterial.transparent = true;
  32. this.rtDepth = new THREE.WebGLRenderTarget(1024, 1024, {
  33. minFilter: THREE.NearestFilter,
  34. magFilter: THREE.NearestFilter,
  35. format: THREE.RGBAFormat,
  36. type: THREE.FloatType,
  37. depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
  38. });
  39. this.rtAttribute = new THREE.WebGLRenderTarget(1024, 1024, {
  40. minFilter: THREE.NearestFilter,
  41. magFilter: THREE.NearestFilter,
  42. format: THREE.RGBAFormat,
  43. type: THREE.FloatType,
  44. depthTexture: this.rtDepth.depthTexture,
  45. });
  46. this.initialized = true;
  47. };
  48. resize(width, height){
  49. this.rtDepth.setSize(width, height);
  50. this.rtAttribute.setSize(width, height);
  51. }
  52. clearTargets(){
  53. const viewer = this.viewer;
  54. const {renderer} = viewer;
  55. const oldTarget = renderer.getRenderTarget();
  56. renderer.setClearColor(0x000000, 0);
  57. renderer.setRenderTarget( this.rtDepth );
  58. renderer.clear( true, true, true );
  59. renderer.setRenderTarget( this.rtAttribute );
  60. renderer.clear( true, true, true );
  61. renderer.setRenderTarget(oldTarget);
  62. }
  63. clear(){
  64. this.init();
  65. const {renderer, background} = this.viewer;
  66. if(background === "skybox"){
  67. renderer.setClearColor(0x000000, 0);
  68. } else if (background === 'gradient') {
  69. renderer.setClearColor(0x000000, 0);
  70. } else if (background === 'black') {
  71. renderer.setClearColor(0x000000, 1);
  72. } else if (background === 'white') {
  73. renderer.setClearColor(0xFFFFFF, 1);
  74. } else {
  75. renderer.setClearColor(0x000000, 0);
  76. }
  77. renderer.clear();
  78. this.clearTargets();
  79. }
  80. render (params) {
  81. this.init();
  82. const viewer = this.viewer;
  83. const camera = params.camera ? params.camera : viewer.scene.getActiveCamera();
  84. const {width, height} = this.viewer.renderer.getSize(new THREE.Vector2());
  85. viewer.dispatchEvent({type: "render.pass.begin",viewer: viewer});
  86. this.resize(width, height);
  87. const visiblePointClouds = viewer.scene.pointclouds.filter(pc => pc.visible);
  88. const originalMaterials = new Map();
  89. for(let pointcloud of visiblePointClouds){
  90. originalMaterials.set(pointcloud, pointcloud.material);
  91. if(!this.attributeMaterials.has(pointcloud)){
  92. let attributeMaterial = new PointCloudMaterial();
  93. this.attributeMaterials.set(pointcloud, attributeMaterial);
  94. }
  95. if(!this.depthMaterials.has(pointcloud)){
  96. let depthMaterial = new PointCloudMaterial();
  97. depthMaterial.setDefine("depth_pass", "#define hq_depth_pass");
  98. depthMaterial.setDefine("use_edl", "#define use_edl");
  99. this.depthMaterials.set(pointcloud, depthMaterial);
  100. }
  101. }
  102. { // DEPTH PASS
  103. for (let pointcloud of visiblePointClouds) {
  104. let octreeSize = pointcloud.pcoGeometry.boundingBox.getSize(new THREE.Vector3()).x;
  105. let material = originalMaterials.get(pointcloud);
  106. let depthMaterial = this.depthMaterials.get(pointcloud);
  107. depthMaterial.size = material.size;
  108. depthMaterial.minSize = material.minSize;
  109. depthMaterial.maxSize = material.maxSize;
  110. depthMaterial.pointSizeType = material.pointSizeType;
  111. depthMaterial.visibleNodesTexture = material.visibleNodesTexture;
  112. depthMaterial.weighted = false;
  113. depthMaterial.screenWidth = width;
  114. depthMaterial.shape = PointShape.CIRCLE;
  115. depthMaterial.screenHeight = height;
  116. depthMaterial.uniforms.visibleNodes.value = material.visibleNodesTexture;
  117. depthMaterial.uniforms.octreeSize.value = octreeSize;
  118. depthMaterial.spacing = pointcloud.pcoGeometry.spacing; // * Math.max(...pointcloud.scale.toArray());
  119. depthMaterial.classification = material.classification;
  120. depthMaterial.uniforms.classificationLUT.value.image.data = material.uniforms.classificationLUT.value.image.data;
  121. depthMaterial.classificationTexture.needsUpdate = true;
  122. depthMaterial.uniforms.uFilterReturnNumberRange.value = material.uniforms.uFilterReturnNumberRange.value;
  123. depthMaterial.uniforms.uFilterNumberOfReturnsRange.value = material.uniforms.uFilterNumberOfReturnsRange.value;
  124. depthMaterial.uniforms.uFilterGPSTimeClipRange.value = material.uniforms.uFilterGPSTimeClipRange.value;
  125. depthMaterial.uniforms.uFilterPointSourceIDClipRange.value = material.uniforms.uFilterPointSourceIDClipRange.value;
  126. depthMaterial.clipTask = material.clipTask;
  127. depthMaterial.clipMethod = material.clipMethod;
  128. depthMaterial.setClipBoxes(material.clipBoxes);
  129. depthMaterial.setClipPolygons(material.clipPolygons);
  130. pointcloud.material = depthMaterial;
  131. }
  132. viewer.pRenderer.render(viewer.scene.scenePointCloud, camera, this.rtDepth, {
  133. clipSpheres: viewer.scene.volumes.filter(v => (v instanceof SphereVolume)),
  134. });
  135. }
  136. { // ATTRIBUTE PASS
  137. for (let pointcloud of visiblePointClouds) {
  138. let octreeSize = pointcloud.pcoGeometry.boundingBox.getSize(new THREE.Vector3()).x;
  139. let material = originalMaterials.get(pointcloud);
  140. let attributeMaterial = this.attributeMaterials.get(pointcloud);
  141. attributeMaterial.size = material.size;
  142. attributeMaterial.minSize = material.minSize;
  143. attributeMaterial.maxSize = material.maxSize;
  144. attributeMaterial.pointSizeType = material.pointSizeType;
  145. attributeMaterial.activeAttributeName = material.activeAttributeName;
  146. attributeMaterial.visibleNodesTexture = material.visibleNodesTexture;
  147. attributeMaterial.weighted = true;
  148. attributeMaterial.screenWidth = width;
  149. attributeMaterial.screenHeight = height;
  150. attributeMaterial.shape = PointShape.CIRCLE;
  151. attributeMaterial.uniforms.visibleNodes.value = material.visibleNodesTexture;
  152. attributeMaterial.uniforms.octreeSize.value = octreeSize;
  153. attributeMaterial.spacing = pointcloud.pcoGeometry.spacing; // * Math.max(...pointcloud.scale.toArray());
  154. attributeMaterial.classification = material.classification;
  155. attributeMaterial.uniforms.classificationLUT.value.image.data = material.uniforms.classificationLUT.value.image.data;
  156. attributeMaterial.classificationTexture.needsUpdate = true;
  157. attributeMaterial.uniforms.uFilterReturnNumberRange.value = material.uniforms.uFilterReturnNumberRange.value;
  158. attributeMaterial.uniforms.uFilterNumberOfReturnsRange.value = material.uniforms.uFilterNumberOfReturnsRange.value;
  159. attributeMaterial.uniforms.uFilterGPSTimeClipRange.value = material.uniforms.uFilterGPSTimeClipRange.value;
  160. attributeMaterial.uniforms.uFilterPointSourceIDClipRange.value = material.uniforms.uFilterPointSourceIDClipRange.value;
  161. attributeMaterial.elevationGradientRepeat = material.elevationGradientRepeat;
  162. attributeMaterial.elevationRange = material.elevationRange;
  163. attributeMaterial.gradient = material.gradient;
  164. attributeMaterial.matcap = material.matcap;
  165. attributeMaterial.intensityRange = material.intensityRange;
  166. attributeMaterial.intensityGamma = material.intensityGamma;
  167. attributeMaterial.intensityContrast = material.intensityContrast;
  168. attributeMaterial.intensityBrightness = material.intensityBrightness;
  169. attributeMaterial.rgbGamma = material.rgbGamma;
  170. attributeMaterial.rgbContrast = material.rgbContrast;
  171. attributeMaterial.rgbBrightness = material.rgbBrightness;
  172. attributeMaterial.weightRGB = material.weightRGB;
  173. attributeMaterial.weightIntensity = material.weightIntensity;
  174. attributeMaterial.weightElevation = material.weightElevation;
  175. attributeMaterial.weightRGB = material.weightRGB;
  176. attributeMaterial.weightClassification = material.weightClassification;
  177. attributeMaterial.weightReturnNumber = material.weightReturnNumber;
  178. attributeMaterial.weightSourceID = material.weightSourceID;
  179. attributeMaterial.color = material.color;
  180. attributeMaterial.clipTask = material.clipTask;
  181. attributeMaterial.clipMethod = material.clipMethod;
  182. attributeMaterial.setClipBoxes(material.clipBoxes);
  183. attributeMaterial.setClipPolygons(material.clipPolygons);
  184. pointcloud.material = attributeMaterial;
  185. }
  186. let gl = this.gl;
  187. viewer.renderer.setRenderTarget(null);
  188. viewer.pRenderer.render(viewer.scene.scenePointCloud, camera, this.rtAttribute, {
  189. clipSpheres: viewer.scene.volumes.filter(v => (v instanceof SphereVolume)),
  190. //material: this.attributeMaterial,
  191. blendFunc: [gl.SRC_ALPHA, gl.ONE],
  192. //depthTest: false,
  193. depthWrite: false
  194. });
  195. }
  196. for(let [pointcloud, material] of originalMaterials){
  197. pointcloud.material = material;
  198. }
  199. viewer.renderer.setRenderTarget(null);
  200. if(viewer.background === "skybox"){
  201. viewer.renderer.setClearColor(0x000000, 0);
  202. viewer.renderer.clear();
  203. viewer.skybox.camera.rotation.copy(viewer.scene.cameraP.rotation);
  204. viewer.skybox.camera.fov = viewer.scene.cameraP.fov;
  205. viewer.skybox.camera.aspect = viewer.scene.cameraP.aspect;
  206. viewer.skybox.parent.rotation.x = 0;
  207. viewer.skybox.parent.updateMatrixWorld();
  208. viewer.skybox.camera.updateProjectionMatrix();
  209. viewer.renderer.render(viewer.skybox.scene, viewer.skybox.camera);
  210. } else if (viewer.background === 'gradient') {
  211. viewer.renderer.setClearColor(0x000000, 0);
  212. viewer.renderer.clear();
  213. viewer.renderer.render(viewer.scene.sceneBG, viewer.scene.cameraBG);
  214. } else if (viewer.background === 'black') {
  215. viewer.renderer.setClearColor(0x000000, 1);
  216. viewer.renderer.clear();
  217. } else if (viewer.background === 'white') {
  218. viewer.renderer.setClearColor(0xFFFFFF, 1);
  219. viewer.renderer.clear();
  220. } else {
  221. viewer.renderer.setClearColor(0x000000, 0);
  222. viewer.renderer.clear();
  223. }
  224. { // NORMALIZATION PASS
  225. let normalizationMaterial = this.useEDL ? this.normalizationEDLMaterial : this.normalizationMaterial;
  226. if(this.useEDL){
  227. normalizationMaterial.uniforms.edlStrength.value = viewer.edlStrength;
  228. normalizationMaterial.uniforms.radius.value = viewer.edlRadius;
  229. normalizationMaterial.uniforms.screenWidth.value = width;
  230. normalizationMaterial.uniforms.screenHeight.value = height;
  231. normalizationMaterial.uniforms.uEDLMap.value = this.rtDepth.texture;
  232. }
  233. normalizationMaterial.uniforms.uWeightMap.value = this.rtAttribute.texture;
  234. normalizationMaterial.uniforms.uDepthMap.value = this.rtAttribute.depthTexture;
  235. Utils.screenPass.render(viewer.renderer, normalizationMaterial);
  236. }
  237. viewer.renderer.render(viewer.scene.scene, camera);
  238. viewer.dispatchEvent({type: "render.pass.scene", viewer: viewer});
  239. viewer.renderer.clearDepth();
  240. viewer.transformationTool.update();
  241. viewer.dispatchEvent({type: "render.pass.perspective_overlay",viewer: viewer});
  242. viewer.renderer.render(viewer.controls.sceneControls, camera);
  243. viewer.renderer.render(viewer.clippingTool.sceneVolume, camera);
  244. viewer.renderer.render(viewer.transformationTool.scene, camera);
  245. viewer.renderer.setViewport(width - viewer.navigationCube.width,
  246. height - viewer.navigationCube.width,
  247. viewer.navigationCube.width, viewer.navigationCube.width);
  248. viewer.renderer.render(viewer.navigationCube, viewer.navigationCube.camera);
  249. viewer.renderer.setViewport(0, 0, width, height);
  250. viewer.dispatchEvent({type: "render.pass.end",viewer: viewer});
  251. }
  252. }