PotreeRenderer.js 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648
  1. import * as THREE from "../libs/three.js/build/three.module.js";
  2. import {PointCloudTree} from "./PointCloudTree.js";
  3. import {PointSizeType, ClipTask, ElevationGradientRepeat} from "./defines.js";
  4. // Copied from three.js: WebGLRenderer.js
  5. function paramThreeToGL(_gl, p) {
  6. let extension;
  7. if (p === THREE.RepeatWrapping) return _gl.REPEAT;
  8. if (p === THREE.ClampToEdgeWrapping) return _gl.CLAMP_TO_EDGE;
  9. if (p === THREE.MirroredRepeatWrapping) return _gl.MIRRORED_REPEAT;
  10. if (p === THREE.NearestFilter) return _gl.NEAREST;
  11. if (p === THREE.NearestMipMapNearestFilter) return _gl.NEAREST_MIPMAP_NEAREST;
  12. if (p === THREE.NearestMipMapLinearFilter) return _gl.NEAREST_MIPMAP_LINEAR;
  13. if (p === THREE.LinearFilter) return _gl.LINEAR;
  14. if (p === THREE.LinearMipMapNearestFilter) return _gl.LINEAR_MIPMAP_NEAREST;
  15. if (p === THREE.LinearMipMapLinearFilter) return _gl.LINEAR_MIPMAP_LINEAR;
  16. if (p === THREE.UnsignedByteType) return _gl.UNSIGNED_BYTE;
  17. if (p === THREE.UnsignedShort4444Type) return _gl.UNSIGNED_SHORT_4_4_4_4;
  18. if (p === THREE.UnsignedShort5551Type) return _gl.UNSIGNED_SHORT_5_5_5_1;
  19. if (p === THREE.UnsignedShort565Type) return _gl.UNSIGNED_SHORT_5_6_5;
  20. if (p === THREE.ByteType) return _gl.BYTE;
  21. if (p === THREE.ShortType) return _gl.SHORT;
  22. if (p === THREE.UnsignedShortType) return _gl.UNSIGNED_SHORT;
  23. if (p === THREE.IntType) return _gl.INT;
  24. if (p === THREE.UnsignedIntType) return _gl.UNSIGNED_INT;
  25. if (p === THREE.FloatType) return _gl.FLOAT;
  26. if (p === THREE.HalfFloatType) {
  27. extension = extensions.get('OES_texture_half_float');
  28. if (extension !== null) return extension.HALF_FLOAT_OES;
  29. }
  30. if (p === THREE.AlphaFormat) return _gl.ALPHA;
  31. if (p === THREE.RGBFormat) return _gl.RGB;
  32. if (p === THREE.RGBAFormat) return _gl.RGBA;
  33. if (p === THREE.LuminanceFormat) return _gl.LUMINANCE;
  34. if (p === THREE.LuminanceAlphaFormat) return _gl.LUMINANCE_ALPHA;
  35. if (p === THREE.DepthFormat) return _gl.DEPTH_COMPONENT;
  36. if (p === THREE.DepthStencilFormat) return _gl.DEPTH_STENCIL;
  37. if (p === THREE.AddEquation) return _gl.FUNC_ADD;
  38. if (p === THREE.SubtractEquation) return _gl.FUNC_SUBTRACT;
  39. if (p === THREE.ReverseSubtractEquation) return _gl.FUNC_REVERSE_SUBTRACT;
  40. if (p === THREE.ZeroFactor) return _gl.ZERO;
  41. if (p === THREE.OneFactor) return _gl.ONE;
  42. if (p === THREE.SrcColorFactor) return _gl.SRC_COLOR;
  43. if (p === THREE.OneMinusSrcColorFactor) return _gl.ONE_MINUS_SRC_COLOR;
  44. if (p === THREE.SrcAlphaFactor) return _gl.SRC_ALPHA;
  45. if (p === THREE.OneMinusSrcAlphaFactor) return _gl.ONE_MINUS_SRC_ALPHA;
  46. if (p === THREE.DstAlphaFactor) return _gl.DST_ALPHA;
  47. if (p === THREE.OneMinusDstAlphaFactor) return _gl.ONE_MINUS_DST_ALPHA;
  48. if (p === THREE.DstColorFactor) return _gl.DST_COLOR;
  49. if (p === THREE.OneMinusDstColorFactor) return _gl.ONE_MINUS_DST_COLOR;
  50. if (p === THREE.SrcAlphaSaturateFactor) return _gl.SRC_ALPHA_SATURATE;
  51. if (p === THREE.RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
  52. p === THREE.RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) {
  53. extension = extensions.get('WEBGL_compressed_texture_s3tc');
  54. if (extension !== null) {
  55. if (p === THREE.RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
  56. if (p === THREE.RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
  57. if (p === THREE.RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
  58. if (p === THREE.RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
  59. }
  60. }
  61. if (p === THREE.RGB_PVRTC_4BPPV1_Format || p === THREE.RGB_PVRTC_2BPPV1_Format ||
  62. p === THREE.RGBA_PVRTC_4BPPV1_Format || p === THREE.RGBA_PVRTC_2BPPV1_Format) {
  63. extension = extensions.get('WEBGL_compressed_texture_pvrtc');
  64. if (extension !== null) {
  65. if (p === THREE.RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  66. if (p === THREE.RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  67. if (p === THREE.RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  68. if (p === THREE.RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  69. }
  70. }
  71. if (p === THREE.RGB_ETC1_Format) {
  72. extension = extensions.get('WEBGL_compressed_texture_etc1');
  73. if (extension !== null) return extension.COMPRESSED_RGB_ETC1_WEBGL;
  74. }
  75. if (p === THREE.MinEquation || p === THREE.MaxEquation) {
  76. extension = extensions.get('EXT_blend_minmax');
  77. if (extension !== null) {
  78. if (p === THREE.MinEquation) return extension.MIN_EXT;
  79. if (p === THREE.MaxEquation) return extension.MAX_EXT;
  80. }
  81. }
  82. if (p === UnsignedInt248Type) {
  83. extension = extensions.get('WEBGL_depth_texture');
  84. if (extension !== null) return extension.UNSIGNED_INT_24_8_WEBGL;
  85. }
  86. return 0;
  87. };
  88. let attributeLocations = {
  89. "position": {name: "position", location: 0},
  90. "color": {name: "color", location: 1},
  91. "rgba": {name: "color", location: 1},
  92. "intensity": {name: "intensity", location: 2},
  93. "classification": {name: "classification", location: 3},
  94. "returnNumber": {name: "returnNumber", location: 4},
  95. "return number": {name: "returnNumber", location: 4},
  96. "returns": {name: "returnNumber", location: 4},
  97. "numberOfReturns": {name: "numberOfReturns", location: 5},
  98. "number of returns": {name: "numberOfReturns", location: 5},
  99. "pointSourceID": {name: "pointSourceID", location: 6},
  100. "source id": {name: "pointSourceID", location: 6},
  101. "point source id": {name: "pointSourceID", location: 6},
  102. "indices": {name: "indices", location: 7},
  103. "normal": {name: "normal", location: 8},
  104. "spacing": {name: "spacing", location: 9},
  105. "gps-time": {name: "gpsTime", location: 10},
  106. "aExtra": {name: "aExtra", location: 11},
  107. };
  108. class Shader {
  109. constructor(gl, name, vsSource, fsSource) {
  110. this.gl = gl;
  111. this.name = name;
  112. this.vsSource = vsSource;
  113. this.fsSource = fsSource;
  114. this.cache = new Map();
  115. this.vs = null;
  116. this.fs = null;
  117. this.program = null;
  118. this.uniformLocations = {};
  119. this.attributeLocations = {};
  120. this.uniformBlockIndices = {};
  121. this.uniformBlocks = {};
  122. this.uniforms = {};
  123. this.update(vsSource, fsSource);
  124. }
  125. update(vsSource, fsSource) {
  126. this.vsSource = vsSource;
  127. this.fsSource = fsSource;
  128. this.linkProgram();
  129. }
  130. compileShader(shader, source){
  131. let gl = this.gl;
  132. gl.shaderSource(shader, source);
  133. gl.compileShader(shader);
  134. let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  135. if (!success) {
  136. let info = gl.getShaderInfoLog(shader);
  137. let numberedSource = source.split("\n").map((a, i) => `${i + 1}`.padEnd(5) + a).join("\n");
  138. throw `could not compile shader ${this.name}: ${info}, \n${numberedSource}`;
  139. }
  140. }
  141. linkProgram() {
  142. const tStart = performance.now();
  143. let gl = this.gl;
  144. this.uniformLocations = {};
  145. this.attributeLocations = {};
  146. this.uniforms = {};
  147. gl.useProgram(null);
  148. let cached = this.cache.get(`${this.vsSource}, ${this.fsSource}`);
  149. if (cached) {
  150. this.program = cached.program;
  151. this.vs = cached.vs;
  152. this.fs = cached.fs;
  153. this.attributeLocations = cached.attributeLocations;
  154. this.uniformLocations = cached.uniformLocations;
  155. this.uniformBlocks = cached.uniformBlocks;
  156. this.uniforms = cached.uniforms;
  157. return;
  158. } else {
  159. this.vs = gl.createShader(gl.VERTEX_SHADER);
  160. this.fs = gl.createShader(gl.FRAGMENT_SHADER);
  161. this.program = gl.createProgram();
  162. if( !gl.isProgram(this.program )){//创建失败 开启多个页面可能会,原因是webglcontextlost
  163. //console.error('创建program失败');
  164. viewer.dispatchEvent('webglError', {msg: 'potreeRenderer创建program失败'})
  165. console.log(this.vs)
  166. console.log(this.fs)
  167. return;
  168. }
  169. for(let name of Object.keys(attributeLocations)){
  170. let location = attributeLocations[name].location;
  171. let glslName = attributeLocations[name].name;
  172. gl.bindAttribLocation(this.program, location, glslName);
  173. }
  174. this.compileShader(this.vs, this.vsSource);
  175. this.compileShader(this.fs, this.fsSource);
  176. let program = this.program;
  177. gl.attachShader(program, this.vs);
  178. gl.attachShader(program, this.fs);
  179. gl.linkProgram(program);
  180. gl.detachShader(program, this.vs);
  181. gl.detachShader(program, this.fs);
  182. // 检测当前程序链接状态
  183. let success = gl.getProgramParameter(program, gl.LINK_STATUS);
  184. if (!success) {
  185. let info = gl.getProgramInfoLog(program);
  186. throw `could not link program ${this.name}: ${info}`;
  187. }
  188. { // attribute locations
  189. let numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
  190. for (let i = 0; i < numAttributes; i++) {
  191. let attribute = gl.getActiveAttrib(program, i);
  192. let location = gl.getAttribLocation(program, attribute.name);
  193. this.attributeLocations[attribute.name] = location;
  194. }
  195. }
  196. { // uniform locations
  197. let numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
  198. for (let i = 0; i < numUniforms; i++) {
  199. let uniform = gl.getActiveUniform(program, i);
  200. let location = gl.getUniformLocation(program, uniform.name);
  201. this.uniformLocations[uniform.name] = location;
  202. this.uniforms[uniform.name] = {
  203. location: location,
  204. value: null,
  205. };
  206. }
  207. }
  208. // uniform blocks
  209. if( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext){ //WebGL2RenderingContext在mac的safari14以下是没有定义的
  210. let numBlocks = gl.getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS);
  211. for (let i = 0; i < numBlocks; i++) {
  212. let blockName = gl.getActiveUniformBlockName(program, i);
  213. let blockIndex = gl.getUniformBlockIndex(program, blockName);
  214. this.uniformBlockIndices[blockName] = blockIndex;
  215. gl.uniformBlockBinding(program, blockIndex, blockIndex);
  216. let dataSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
  217. let uBuffer = gl.createBuffer();
  218. gl.bindBuffer(gl.UNIFORM_BUFFER, uBuffer);
  219. gl.bufferData(gl.UNIFORM_BUFFER, dataSize, gl.DYNAMIC_READ);
  220. gl.bindBufferBase(gl.UNIFORM_BUFFER, blockIndex, uBuffer);
  221. gl.bindBuffer(gl.UNIFORM_BUFFER, null);
  222. this.uniformBlocks[blockName] = {
  223. name: blockName,
  224. index: blockIndex,
  225. dataSize: dataSize,
  226. buffer: uBuffer
  227. };
  228. }
  229. }
  230. let cached = {
  231. program: this.program,
  232. vs: this.vs,
  233. fs: this.fs,
  234. attributeLocations: this.attributeLocations,
  235. uniformLocations: this.uniformLocations,
  236. uniforms: this.uniforms,
  237. uniformBlocks: this.uniformBlocks,
  238. };
  239. this.cache.set(`${this.vsSource}, ${this.fsSource}`, cached);
  240. }
  241. const tEnd = performance.now();
  242. const duration = tEnd - tStart;
  243. //console.log(`shader compile duration: ${duration.toFixed(3)}`);
  244. }
  245. setUniformMatrix4(name, value) {
  246. const gl = this.gl;
  247. const location = this.uniformLocations[name];
  248. if (location == null) {
  249. return;
  250. }
  251. let tmp = new Float32Array(value.elements);
  252. gl.uniformMatrix4fv(location, false, tmp);
  253. }
  254. setUniform1f(name, value) {
  255. const gl = this.gl;
  256. const uniform = this.uniforms[name];
  257. if (uniform === undefined) {
  258. return;
  259. }
  260. if(uniform.value === value){
  261. return;
  262. }
  263. uniform.value = value;
  264. gl.uniform1f(uniform.location, value);
  265. }
  266. setUniformBoolean(name, value) {
  267. const gl = this.gl;
  268. const uniform = this.uniforms[name];
  269. if (uniform === undefined) {
  270. return;
  271. }
  272. if(uniform.value === value){
  273. return;
  274. }
  275. uniform.value = value;
  276. gl.uniform1i(uniform.location, value);
  277. }
  278. setUniformTexture(name, value) {
  279. const gl = this.gl;
  280. const location = this.uniformLocations[name];
  281. if (location == null) {
  282. return;
  283. }
  284. gl.uniform1i(location, value);
  285. }
  286. setUniform2f(name, value) {
  287. const gl = this.gl;
  288. const location = this.uniformLocations[name];
  289. if (location == null) {
  290. return;
  291. }
  292. gl.uniform2f(location, value[0], value[1]);
  293. }
  294. setUniform3f(name, value) {
  295. const gl = this.gl;
  296. const location = this.uniformLocations[name];
  297. if (location == null) {
  298. return;
  299. }
  300. gl.uniform3f(location, value[0], value[1], value[2]);
  301. }
  302. setUniform(name, value) {
  303. if (value.constructor === THREE.Matrix4) {
  304. this.setUniformMatrix4(name, value);
  305. } else if (typeof value === "number") {
  306. this.setUniform1f(name, value);
  307. } else if (typeof value === "boolean") {
  308. this.setUniformBoolean(name, value);
  309. } else if (value instanceof WebGLTexture) {
  310. this.setUniformTexture(name, value);
  311. } else if (value instanceof Array) {
  312. if (value.length === 2) {
  313. this.setUniform2f(name, value);
  314. } else if (value.length === 3) {
  315. this.setUniform3f(name, value);
  316. }
  317. } else {
  318. console.error("unhandled uniform type: ", name, value);
  319. }
  320. }
  321. setUniform1i(name, value) {
  322. let gl = this.gl;
  323. let location = this.uniformLocations[name];
  324. if (location == null) {
  325. return;
  326. }
  327. gl.uniform1i(location, value);
  328. }
  329. };
  330. class WebGLTexture {
  331. constructor(gl, texture) {
  332. this.gl = gl;
  333. this.texture = texture;
  334. this.id = gl.createTexture();
  335. this.target = gl.TEXTURE_2D;
  336. this.version = -1;
  337. this.update(texture);
  338. }
  339. update() {
  340. if (!this.texture.image) {
  341. this.version = this.texture.version;
  342. return;
  343. }
  344. let gl = this.gl;
  345. let texture = this.texture;
  346. if (this.version === texture.version) {
  347. return;
  348. }
  349. this.target = gl.TEXTURE_2D;
  350. gl.bindTexture(this.target, this.id);
  351. let level = 0;
  352. let internalFormat = paramThreeToGL(gl, texture.format);
  353. let width = texture.image.width;
  354. let height = texture.image.height;
  355. let border = 0;
  356. let srcFormat = internalFormat;
  357. let srcType = paramThreeToGL(gl, texture.type);
  358. let data;
  359. gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);
  360. gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
  361. gl.pixelStorei(gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
  362. if (texture instanceof THREE.DataTexture) {
  363. data = texture.image.data;
  364. gl.texParameteri(this.target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  365. gl.texParameteri(this.target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  366. gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, paramThreeToGL(gl, texture.magFilter));
  367. gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, paramThreeToGL(gl, texture.minFilter));
  368. gl.texImage2D(this.target, level, internalFormat,
  369. width, height, border, srcFormat, srcType,
  370. data);
  371. } else if ((texture instanceof THREE.CanvasTexture) || (texture instanceof THREE.Texture)) {
  372. data = texture.image;
  373. gl.texParameteri(this.target, gl.TEXTURE_WRAP_S, paramThreeToGL(gl, texture.wrapS));
  374. gl.texParameteri(this.target, gl.TEXTURE_WRAP_T, paramThreeToGL(gl, texture.wrapT));
  375. gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, paramThreeToGL(gl, texture.magFilter));
  376. gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, paramThreeToGL(gl, texture.minFilter));
  377. gl.texImage2D(this.target, level, internalFormat,
  378. internalFormat, srcType, data);
  379. if (texture instanceof THREE.Texture) {gl.generateMipmap(gl.TEXTURE_2D);}
  380. }
  381. gl.bindTexture(this.target, null);
  382. this.version = texture.version;
  383. }
  384. };
  385. class WebGLBuffer {
  386. constructor() {
  387. this.numElements = 0;
  388. this.vao = null;
  389. this.vbos = new Map();
  390. }
  391. };
  392. export class Renderer {
  393. constructor(threeRenderer) {
  394. this.threeRenderer = threeRenderer;
  395. this.gl = this.threeRenderer.getContext();
  396. this.buffers = new Map();
  397. this.shaders = new Map();
  398. this.textures = new Map();
  399. this.glTypeMapping = new Map();
  400. this.glTypeMapping.set(Float32Array, this.gl.FLOAT);
  401. this.glTypeMapping.set(Uint8Array, this.gl.UNSIGNED_BYTE);
  402. this.glTypeMapping.set(Uint16Array, this.gl.UNSIGNED_SHORT);
  403. this.toggle = 0;
  404. }
  405. deleteBuffer(geometry) {
  406. let gl = this.gl;
  407. let webglBuffer = this.buffers.get(geometry);
  408. if (webglBuffer != null) {
  409. for (let attributeName in geometry.attributes) {
  410. gl.deleteBuffer(webglBuffer.vbos.get(attributeName).handle);
  411. }
  412. this.buffers.delete(geometry);
  413. }
  414. }
  415. createBuffer(geometry){
  416. let gl = this.gl;
  417. let webglBuffer = new WebGLBuffer();
  418. webglBuffer.vao = gl.createVertexArray();
  419. webglBuffer.numElements = geometry.attributes.position.count;
  420. gl.bindVertexArray(webglBuffer.vao);
  421. for(let attributeName in geometry.attributes){
  422. let bufferAttribute = geometry.attributes[attributeName];
  423. let vbo = gl.createBuffer();
  424. gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
  425. gl.bufferData(gl.ARRAY_BUFFER, bufferAttribute.array, gl.STATIC_DRAW);
  426. let normalized = bufferAttribute.normalized;
  427. let type = this.glTypeMapping.get(bufferAttribute.array.constructor);
  428. if(attributeLocations[attributeName] === undefined){
  429. //attributeLocation = attributeLocations["aExtra"];
  430. }else{
  431. let attributeLocation = attributeLocations[attributeName].location;
  432. gl.vertexAttribPointer(attributeLocation, bufferAttribute.itemSize, type, normalized, 0, 0);
  433. gl.enableVertexAttribArray(attributeLocation);
  434. }
  435. webglBuffer.vbos.set(attributeName, {
  436. handle: vbo,
  437. name: attributeName,
  438. count: bufferAttribute.count,
  439. itemSize: bufferAttribute.itemSize,
  440. type: geometry.attributes.position.array.constructor,
  441. version: 0
  442. });
  443. }
  444. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  445. gl.bindVertexArray(null);
  446. let disposeHandler = (event) => {
  447. this.deleteBuffer(geometry);
  448. geometry.removeEventListener("dispose", disposeHandler);
  449. };
  450. geometry.addEventListener("dispose", disposeHandler);
  451. return webglBuffer;
  452. }
  453. updateBuffer(geometry){
  454. let gl = this.gl;
  455. let webglBuffer = this.buffers.get(geometry);
  456. gl.bindVertexArray(webglBuffer.vao);
  457. for(let attributeName in geometry.attributes){
  458. let bufferAttribute = geometry.attributes[attributeName];
  459. let normalized = bufferAttribute.normalized;
  460. let type = this.glTypeMapping.get(bufferAttribute.array.constructor);
  461. let vbo = null;
  462. if(!webglBuffer.vbos.has(attributeName)){
  463. vbo = gl.createBuffer();
  464. webglBuffer.vbos.set(attributeName, {
  465. handle: vbo,
  466. name: attributeName,
  467. count: bufferAttribute.count,
  468. itemSize: bufferAttribute.itemSize,
  469. type: geometry.attributes.position.array.constructor,
  470. version: bufferAttribute.version
  471. });
  472. }else{
  473. vbo = webglBuffer.vbos.get(attributeName).handle;
  474. webglBuffer.vbos.get(attributeName).version = bufferAttribute.version;
  475. }
  476. gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
  477. gl.bufferData(gl.ARRAY_BUFFER, bufferAttribute.array, gl.STATIC_DRAW);
  478. if(attributeLocations[attributeName] === undefined){
  479. //attributeLocation = attributeLocations["aExtra"];
  480. }else{
  481. let attributeLocation = attributeLocations[attributeName].location;
  482. gl.vertexAttribPointer(attributeLocation, bufferAttribute.itemSize, type, normalized, 0, 0);
  483. gl.enableVertexAttribArray(attributeLocation);
  484. }
  485. }
  486. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  487. gl.bindVertexArray(null);
  488. }
  489. traverse(scene) {
  490. let octrees = [];
  491. let stack = [scene];
  492. while (stack.length > 0) {
  493. let node = stack.pop();
  494. if (node instanceof PointCloudTree) {
  495. octrees.push(node);
  496. continue;
  497. }
  498. let visibleChildren = node.children.filter(c => c.visible);
  499. stack.push(...visibleChildren);
  500. }
  501. let result = {
  502. octrees: octrees
  503. };
  504. return result;
  505. }
  506. renderNodes(octree, nodes, visibilityTextureData, camera, target, shader, params) {
  507. if (exports.measureTimings) performance.mark("renderNodes-start");
  508. let gl = this.gl;
  509. let material = params.material ? params.material : octree.material;
  510. let shadowMaps = params.shadowMaps == null ? [] : params.shadowMaps;
  511. let view = camera.matrixWorldInverse;
  512. if(params.viewOverride){
  513. view = params.viewOverride;
  514. }
  515. let worldView = new THREE.Matrix4();
  516. let mat4holder = new Float32Array(16);
  517. let i = 0;
  518. for (let node of nodes) {
  519. if(exports.debug.allowedNodes !== undefined){
  520. if(!exports.debug.allowedNodes.includes(node.name)){
  521. continue;
  522. }
  523. }
  524. let world = node.sceneNode.matrixWorld;
  525. worldView.multiplyMatrices(view, world);
  526. if (visibilityTextureData) {
  527. let vnStart = visibilityTextureData.offsets.get(node);
  528. shader.setUniform1f("uVNStart", vnStart);
  529. }
  530. let level = node.getLevel();
  531. if(node.debug){
  532. shader.setUniform("uDebug", true);
  533. }else{
  534. shader.setUniform("uDebug", false);
  535. }
  536. // let isLeaf = false;
  537. // if(node instanceof PointCloudOctreeNode){
  538. // isLeaf = Object.keys(node.children).length === 0;
  539. // }else if(node instanceof PointCloudArena4DNode){
  540. // isLeaf = node.geometryNode.isLeaf;
  541. // }
  542. // shader.setUniform("uIsLeafNode", isLeaf);
  543. // let isLeaf = node.children.filter(n => n != null).length === 0;
  544. // if(!isLeaf){
  545. // continue;
  546. // }
  547. // TODO consider passing matrices in an array to avoid uniformMatrix4fv overhead
  548. const lModel = shader.uniformLocations["modelMatrix"];
  549. if (lModel) {
  550. mat4holder.set(world.elements);
  551. gl.uniformMatrix4fv(lModel, false, mat4holder);
  552. }
  553. const lModelView = shader.uniformLocations["modelViewMatrix"];
  554. //mat4holder.set(worldView.elements);
  555. // faster then set in chrome 63
  556. for(let j = 0; j < 16; j++){
  557. mat4holder[j] = worldView.elements[j];
  558. }
  559. gl.uniformMatrix4fv(lModelView, false, mat4holder);
  560. { // Clip Polygons
  561. if(material.clipPolygons && material.clipPolygons.length > 0){
  562. let clipPolygonVCount = [];
  563. let worldViewProjMatrices = [];
  564. for(let clipPolygon of material.clipPolygons){
  565. let view = clipPolygon.viewMatrix;
  566. let proj = clipPolygon.projMatrix;
  567. let worldViewProj = proj.clone().multiply(view).multiply(world);
  568. clipPolygonVCount.push(clipPolygon.markers.length);
  569. worldViewProjMatrices.push(worldViewProj);
  570. }
  571. let flattenedMatrices = [].concat(...worldViewProjMatrices.map(m => m.elements));
  572. let flattenedVertices = new Array(8 * 3 * material.clipPolygons.length);
  573. for(let i = 0; i < material.clipPolygons.length; i++){
  574. let clipPolygon = material.clipPolygons[i];
  575. for(let j = 0; j < clipPolygon.markers.length; j++){
  576. flattenedVertices[i * 24 + (j * 3 + 0)] = clipPolygon.markers[j].position.x;
  577. flattenedVertices[i * 24 + (j * 3 + 1)] = clipPolygon.markers[j].position.y;
  578. flattenedVertices[i * 24 + (j * 3 + 2)] = clipPolygon.markers[j].position.z;
  579. }
  580. }
  581. const lClipPolygonVCount = shader.uniformLocations["uClipPolygonVCount[0]"];
  582. gl.uniform1iv(lClipPolygonVCount, clipPolygonVCount);
  583. const lClipPolygonVP = shader.uniformLocations["uClipPolygonWVP[0]"];
  584. gl.uniformMatrix4fv(lClipPolygonVP, false, flattenedMatrices);
  585. const lClipPolygons = shader.uniformLocations["uClipPolygonVertices[0]"];
  586. gl.uniform3fv(lClipPolygons, flattenedVertices);
  587. }
  588. }
  589. //shader.setUniformMatrix4("modelMatrix", world);
  590. //shader.setUniformMatrix4("modelViewMatrix", worldView);
  591. shader.setUniform1f("uLevel", level);
  592. shader.setUniform1f("uNodeSpacing", node.geometryNode.estimatedSpacing);
  593. shader.setUniform1f("uPCIndex", i);
  594. // uBBSize
  595. if (shadowMaps.length > 0) {
  596. const lShadowMap = shader.uniformLocations["uShadowMap[0]"];
  597. shader.setUniform3f("uShadowColor", material.uniforms.uShadowColor.value);
  598. let bindingStart = 5;
  599. let bindingPoints = new Array(shadowMaps.length).fill(bindingStart).map((a, i) => (a + i));
  600. gl.uniform1iv(lShadowMap, bindingPoints);
  601. for (let i = 0; i < shadowMaps.length; i++) {
  602. let shadowMap = shadowMaps[i];
  603. let bindingPoint = bindingPoints[i];
  604. let glTexture = this.threeRenderer.properties.get(shadowMap.target.texture).__webglTexture;
  605. gl.activeTexture(gl[`TEXTURE${bindingPoint}`]);
  606. gl.bindTexture(gl.TEXTURE_2D, glTexture);
  607. }
  608. {
  609. let worldViewMatrices = shadowMaps
  610. .map(sm => sm.camera.matrixWorldInverse)
  611. .map(view => new THREE.Matrix4().multiplyMatrices(view, world))
  612. let flattenedMatrices = [].concat(...worldViewMatrices.map(c => c.elements));
  613. const lWorldView = shader.uniformLocations["uShadowWorldView[0]"];
  614. gl.uniformMatrix4fv(lWorldView, false, flattenedMatrices);
  615. }
  616. {
  617. let flattenedMatrices = [].concat(...shadowMaps.map(sm => sm.camera.projectionMatrix.elements));
  618. const lProj = shader.uniformLocations["uShadowProj[0]"];
  619. gl.uniformMatrix4fv(lProj, false, flattenedMatrices);
  620. }
  621. }
  622. const geometry = node.geometryNode.geometry;
  623. if(geometry.attributes["gps-time"]){
  624. const bufferAttribute = geometry.attributes["gps-time"];
  625. const attGPS = octree.getAttribute("gps-time");
  626. let initialRange = attGPS.initialRange;
  627. let initialRangeSize = initialRange[1] - initialRange[0];
  628. let globalRange = attGPS.range;
  629. let globalRangeSize = globalRange[1] - globalRange[0];
  630. let scale = initialRangeSize / globalRangeSize;
  631. let offset = -(globalRange[0] - initialRange[0]) / initialRangeSize;
  632. scale = Number.isNaN(scale) ? 1 : scale;
  633. offset = Number.isNaN(offset) ? 0 : offset;
  634. shader.setUniform1f("uGpsScale", scale);
  635. shader.setUniform1f("uGpsOffset", offset);
  636. //shader.setUniform2f("uFilterGPSTimeClipRange", [-Infinity, Infinity]);
  637. let uFilterGPSTimeClipRange = material.uniforms.uFilterGPSTimeClipRange.value;
  638. // let gpsCliPRangeMin = uFilterGPSTimeClipRange[0]
  639. // let gpsCliPRangeMax = uFilterGPSTimeClipRange[1]
  640. // shader.setUniform2f("uFilterGPSTimeClipRange", [gpsCliPRangeMin, gpsCliPRangeMax]);
  641. let normalizedClipRange = [
  642. (uFilterGPSTimeClipRange[0] - globalRange[0]) / globalRangeSize,
  643. (uFilterGPSTimeClipRange[1] - globalRange[0]) / globalRangeSize,
  644. ];
  645. shader.setUniform2f("uFilterGPSTimeClipRange", normalizedClipRange);
  646. // // ranges in full gps coordinate system
  647. // const globalRange = attGPS.range;
  648. // const bufferRange = bufferAttribute.potree.range;
  649. // // ranges in [0, 1]
  650. // // normalizedGlobalRange = [0, 1]
  651. // // normalizedBufferRange: norm buffer within norm global range e.g. [0.2, 0.8]
  652. // const globalWidth = globalRange[1] - globalRange[0];
  653. // const normalizedBufferRange = [
  654. // (bufferRange[0] - globalRange[0]) / globalWidth,
  655. // (bufferRange[1] - globalRange[0]) / globalWidth,
  656. // ];
  657. // shader.setUniform2f("uNormalizedGpsBufferRange", normalizedBufferRange);
  658. // let uFilterGPSTimeClipRange = material.uniforms.uFilterGPSTimeClipRange.value;
  659. // let gpsCliPRangeMin = uFilterGPSTimeClipRange[0]
  660. // let gpsCliPRangeMax = uFilterGPSTimeClipRange[1]
  661. // shader.setUniform2f("uFilterGPSTimeClipRange", [gpsCliPRangeMin, gpsCliPRangeMax]);
  662. // shader.setUniform1f("uGpsScale", bufferAttribute.potree.scale);
  663. // shader.setUniform1f("uGpsOffset", bufferAttribute.potree.offset);
  664. }
  665. {
  666. let uFilterReturnNumberRange = material.uniforms.uFilterReturnNumberRange.value;
  667. let uFilterNumberOfReturnsRange = material.uniforms.uFilterNumberOfReturnsRange.value;
  668. let uFilterPointSourceIDClipRange = material.uniforms.uFilterPointSourceIDClipRange.value;
  669. shader.setUniform2f("uFilterReturnNumberRange", uFilterReturnNumberRange);
  670. shader.setUniform2f("uFilterNumberOfReturnsRange", uFilterNumberOfReturnsRange);
  671. shader.setUniform2f("uFilterPointSourceIDClipRange", uFilterPointSourceIDClipRange);
  672. }
  673. let webglBuffer = null;
  674. if(!this.buffers.has(geometry)){
  675. webglBuffer = this.createBuffer(geometry);
  676. this.buffers.set(geometry, webglBuffer);
  677. }else{
  678. webglBuffer = this.buffers.get(geometry);
  679. for(let attributeName in geometry.attributes){
  680. let attribute = geometry.attributes[attributeName];
  681. if(attribute.version > webglBuffer.vbos.get(attributeName).version){
  682. this.updateBuffer(geometry);
  683. }
  684. }
  685. }
  686. gl.bindVertexArray(webglBuffer.vao);
  687. let isExtraAttribute =
  688. attributeLocations[material.activeAttributeName] === undefined
  689. && Object.keys(geometry.attributes).includes(material.activeAttributeName);
  690. if(isExtraAttribute){
  691. const attributeLocation = attributeLocations["aExtra"].location;
  692. for(const attributeName in geometry.attributes){
  693. const bufferAttribute = geometry.attributes[attributeName];
  694. const vbo = webglBuffer.vbos.get(attributeName);
  695. gl.bindBuffer(gl.ARRAY_BUFFER, vbo.handle);
  696. gl.disableVertexAttribArray(attributeLocation);
  697. }
  698. const attName = material.activeAttributeName;
  699. const bufferAttribute = geometry.attributes[attName];
  700. const vbo = webglBuffer.vbos.get(attName);
  701. if(bufferAttribute !== undefined && vbo !== undefined){
  702. let type = this.glTypeMapping.get(bufferAttribute.array.constructor);
  703. let normalized = bufferAttribute.normalized;
  704. gl.bindBuffer(gl.ARRAY_BUFFER, vbo.handle);
  705. gl.vertexAttribPointer(attributeLocation, bufferAttribute.itemSize, type, normalized, 0, 0);
  706. gl.enableVertexAttribArray(attributeLocation);
  707. }
  708. {
  709. const attExtra = octree.pcoGeometry.pointAttributes.attributes
  710. .find(a => a.name === attName);
  711. let range = material.getRange(attName);
  712. if(!range){
  713. range = attExtra.range;
  714. }
  715. if(!range){
  716. range = [0, 1];
  717. }
  718. let initialRange = attExtra.initialRange;
  719. let initialRangeSize = initialRange[1] - initialRange[0];
  720. let globalRange = range;
  721. let globalRangeSize = globalRange[1] - globalRange[0];
  722. let scale = initialRangeSize / globalRangeSize;
  723. let offset = -(globalRange[0] - initialRange[0]) / initialRangeSize;
  724. scale = Number.isNaN(scale) ? 1 : scale;
  725. offset = Number.isNaN(offset) ? 0 : offset;
  726. shader.setUniform1f("uExtraScale", scale);
  727. shader.setUniform1f("uExtraOffset", offset);
  728. }
  729. }else{
  730. for(const attributeName in geometry.attributes){
  731. const bufferAttribute = geometry.attributes[attributeName];
  732. const vbo = webglBuffer.vbos.get(attributeName);
  733. if(attributeLocations[attributeName] !== undefined){
  734. const attributeLocation = attributeLocations[attributeName].location;
  735. let type = this.glTypeMapping.get(bufferAttribute.array.constructor);
  736. let normalized = bufferAttribute.normalized;
  737. gl.bindBuffer(gl.ARRAY_BUFFER, vbo.handle);
  738. gl.vertexAttribPointer(attributeLocation, bufferAttribute.itemSize, type, normalized, 0, 0);
  739. gl.enableVertexAttribArray(attributeLocation);
  740. }
  741. }
  742. }
  743. let numPoints = webglBuffer.numElements;
  744. gl.drawArrays(gl.POINTS, 0, numPoints);
  745. //gl.drawArrays(gl.TRIANGLES, 0, numPoints);
  746. i++;
  747. }
  748. gl.bindVertexArray(null);
  749. if (exports.measureTimings) {
  750. performance.mark("renderNodes-end");
  751. performance.measure("render.renderNodes", "renderNodes-start", "renderNodes-end");
  752. }
  753. }
  754. renderOctree(octree, nodes, camera, target, params = {}){
  755. let gl = this.gl;
  756. let material = params.material ? params.material : octree.material;
  757. let shadowMaps = params.shadowMaps == null ? [] : params.shadowMaps;
  758. let view = camera.matrixWorldInverse;
  759. let viewInv = camera.matrixWorld;
  760. if(params.viewOverride){
  761. view = params.viewOverride;
  762. viewInv = view.clone().invert();
  763. }
  764. let proj = camera.projectionMatrix;
  765. let projInv = proj.clone().invert();
  766. //let worldView = new THREE.Matrix4();
  767. let shader = null;
  768. let visibilityTextureData = null;
  769. let currentTextureBindingPoint = 0;
  770. if (material.pointSizeType >= 0) {
  771. if (material.pointSizeType === PointSizeType.ADAPTIVE ||
  772. material.activeAttributeName === "level of detail") {
  773. let vnNodes = (params.vnTextureNodes != null) ? params.vnTextureNodes : nodes;
  774. visibilityTextureData = octree.computeVisibilityTextureData(vnNodes, camera);
  775. const vnt = material.visibleNodesTexture;
  776. const data = vnt.image.data;
  777. data.set(visibilityTextureData.data);
  778. vnt.needsUpdate = true;
  779. }
  780. }
  781. { // UPDATE SHADER AND TEXTURES
  782. if (!this.shaders.has(material)) {
  783. let [vs, fs] = [material.vertexShader, material.fragmentShader];
  784. let shader = new Shader(gl, "pointcloud", vs, fs);
  785. this.shaders.set(material, shader);
  786. }
  787. shader = this.shaders.get(material);
  788. //if(material.needsUpdate){
  789. {
  790. let [vs, fs] = [material.vertexShader, material.fragmentShader];
  791. let numSnapshots = material.snapEnabled ? material.numSnapshots : 0;
  792. let numClipBoxes = (material.clipBoxes && material.clipBoxes.length) ? material.clipBoxes.length : 0;
  793. let numClipSpheres = (params.clipSpheres && params.clipSpheres.length) ? params.clipSpheres.length : 0;
  794. let numClipPolygons = (material.clipPolygons && material.clipPolygons.length) ? material.clipPolygons.length : 0;
  795. let defines = [
  796. `#define num_shadowmaps ${shadowMaps.length}`,
  797. `#define num_snapshots ${numSnapshots}`,
  798. `#define num_clipboxes ${numClipBoxes}`,
  799. `#define num_clipspheres ${numClipSpheres}`,
  800. `#define num_clippolygons ${numClipPolygons}`,
  801. ];
  802. //add:-----------
  803. if(material.usePanoMap){
  804. defines.push("#define usePanoMap");
  805. }
  806. if(material.useFilterByNormal){
  807. defines.push("#define use_filter_by_normal");
  808. //Potree.settings.editType == 'pano' ? defines.push("#define attenuated_opacity2") : defines.push("#define attenuated_opacity");
  809. }
  810. //---------------
  811. if(octree.pcoGeometry.root.isLoaded()){
  812. let attributes = octree.pcoGeometry.root.geometry.attributes;
  813. if(attributes["gps-time"]){
  814. defines.push("#define clip_gps_enabled");
  815. }
  816. if(attributes["return number"]){
  817. defines.push("#define clip_return_number_enabled");
  818. }
  819. if(attributes["number of returns"]){
  820. defines.push("#define clip_number_of_returns_enabled");
  821. }
  822. if(attributes["source id"] || attributes["point source id"]){
  823. defines.push("#define clip_point_source_id_enabled");
  824. }
  825. }
  826. let definesString = defines.join("\n");
  827. let vsVersionIndex = vs.indexOf("#version ");
  828. let fsVersionIndex = fs.indexOf("#version ");
  829. if(vsVersionIndex >= 0){
  830. vs = vs.replace(/(#version .*)/, `$1\n${definesString}`)
  831. }else{
  832. vs = `${definesString}\n${vs}`;
  833. }
  834. if(fsVersionIndex >= 0){
  835. fs = fs.replace(/(#version .*)/, `$1\n${definesString}`)
  836. }else{
  837. fs = `${definesString}\n${fs}`;
  838. }
  839. shader.update(vs, fs);
  840. material.needsUpdate = false;
  841. }
  842. for (let uniformName of Object.keys(material.uniforms)) {
  843. let uniform = material.uniforms[uniformName];
  844. if (uniform.type == "t") {
  845. let texture = uniform.value;
  846. if (!texture) {
  847. continue;
  848. }
  849. //add
  850. if(uniformName == 'pano0Map' || uniformName == 'pano1Map' ){ //属于cubeTex,另外设置
  851. continue
  852. }
  853. if (!this.textures.has(texture)) {
  854. let webglTexture = new WebGLTexture(gl, texture);
  855. this.textures.set(texture, webglTexture);
  856. }
  857. let webGLTexture = this.textures.get(texture);
  858. webGLTexture.update();
  859. }
  860. }
  861. }
  862. gl.useProgram(shader.program);
  863. let transparent = false;
  864. if(params.transparent !== undefined){
  865. transparent = params.transparent && material.opacity < 1;
  866. }else{
  867. transparent = material.usePanoMap ? false : (material.useFilterByNormal || material.opacity < 1); //add useFilterByNormal
  868. }
  869. if (transparent){
  870. gl.enable(gl.BLEND);
  871. if(params.notAdditiveBlending){
  872. gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); //NormalBlending
  873. gl.enable(gl.DEPTH_TEST);
  874. gl.depthMask(true); //如果不开启depthWrite,深度会错乱。
  875. }else{
  876. gl.blendFunc(gl.SRC_ALPHA, gl.ONE); //AdditiveBlending 原本
  877. gl.disable(gl.DEPTH_TEST);
  878. gl.depthMask(false);
  879. }
  880. } else {
  881. gl.disable(gl.BLEND);
  882. gl.depthMask(true);
  883. gl.enable(gl.DEPTH_TEST);
  884. }
  885. if(params.blendFunc !== undefined){
  886. gl.enable(gl.BLEND);
  887. gl.blendFunc(...params.blendFunc);
  888. }
  889. if(params.depthTest !== undefined){
  890. if(params.depthTest === true){
  891. gl.enable(gl.DEPTH_TEST);
  892. }else{
  893. gl.disable(gl.DEPTH_TEST);
  894. }
  895. }
  896. if(params.depthWrite !== undefined){
  897. if(params.depthWrite === true){
  898. gl.depthMask(true);
  899. }else{
  900. gl.depthMask(false);
  901. }
  902. }
  903. { // UPDATE UNIFORMS
  904. shader.setUniformMatrix4("projectionMatrix", proj);
  905. shader.setUniformMatrix4("viewMatrix", view);
  906. shader.setUniformMatrix4("uViewInv", viewInv);
  907. shader.setUniformMatrix4("uProjInv", projInv);
  908. /* let screenWidth = target ? target.width : material.screenWidth;
  909. let screenHeight = target ? target.height : material.screenHeight;
  910. shader.setUniform1f("uScreenWidth", screenWidth);
  911. shader.setUniform1f("uScreenHeight", screenHeight); */
  912. shader.setUniform2f('resolution', material.resolution.toArray())
  913. shader.setUniform1f("fov", Math.PI * camera.fov / 180);
  914. shader.setUniform1f("near", camera.near);
  915. shader.setUniform1f("far", camera.far);
  916. if(camera instanceof THREE.OrthographicCamera){
  917. shader.setUniform("uUseOrthographicCamera", true);
  918. shader.setUniform("uOrthoWidth", camera.right - camera.left);
  919. shader.setUniform("uOrthoHeight", camera.top - camera.bottom);
  920. }else{
  921. shader.setUniform("uUseOrthographicCamera", false);
  922. }
  923. if(material.clipBoxes.length + material.clipPolygons.length === 0){
  924. shader.setUniform1i("clipTask", ClipTask.NONE);
  925. }else{
  926. shader.setUniform1i("clipTask", material.clipTask);
  927. }
  928. shader.setUniform1i("clipMethod", material.clipMethod);
  929. if (material.clipBoxes && material.clipBoxes.length > 0) {
  930. //let flattenedMatrices = [].concat(...material.clipBoxes.map(c => c.inverse.elements));
  931. //const lClipBoxes = shader.uniformLocations["clipBoxes[0]"];
  932. //gl.uniformMatrix4fv(lClipBoxes, false, flattenedMatrices);
  933. const lClipBoxes = shader.uniformLocations["clipBoxes[0]"];
  934. gl.uniformMatrix4fv(lClipBoxes, false, material.uniforms.clipBoxes.value);
  935. }
  936. // TODO CLIPSPHERES
  937. if(params.clipSpheres && params.clipSpheres.length > 0){
  938. let clipSpheres = params.clipSpheres;
  939. let matrices = [];
  940. for(let clipSphere of clipSpheres){
  941. //let mScale = new THREE.Matrix4().makeScale(...clipSphere.scale.toArray());
  942. //let mTranslate = new THREE.Matrix4().makeTranslation(...clipSphere.position.toArray());
  943. //let clipToWorld = new THREE.Matrix4().multiplyMatrices(mTranslate, mScale);
  944. let clipToWorld = clipSphere.matrixWorld;
  945. let viewToWorld = camera.matrixWorld
  946. let worldToClip = clipToWorld.clone().invert();
  947. let viewToClip = new THREE.Matrix4().multiplyMatrices(worldToClip, viewToWorld);
  948. matrices.push(viewToClip);
  949. }
  950. let flattenedMatrices = [].concat(...matrices.map(matrix => matrix.elements));
  951. const lClipSpheres = shader.uniformLocations["uClipSpheres[0]"];
  952. gl.uniformMatrix4fv(lClipSpheres, false, flattenedMatrices);
  953. //const lClipSpheres = shader.uniformLocations["uClipSpheres[0]"];
  954. //gl.uniformMatrix4fv(lClipSpheres, false, material.uniforms.clipSpheres.value);
  955. }
  956. shader.setUniform1f("size", material.usePanoMap ? Potree.config.material.absolutePanoramaSize * Math.min(window.devicePixelRatio,2) : material.size);//usePanoMap时控制在不大不小的范围内感觉较好,考虑到有的点云稀疏,用大一点的点
  957. shader.setUniform1f("maxSize", material.uniforms.maxSize.value);
  958. shader.setUniform1f("minSize", material.uniforms.minSize.value);
  959. // uniform float uPCIndex
  960. shader.setUniform1f("uOctreeSpacing", material.spacing);
  961. shader.setUniform("uOctreeSize", material.uniforms.octreeSize.value);
  962. //uniform vec3 uColor;
  963. shader.setUniform3f("uColor", material.color.toArray());
  964. //uniform float opacity;
  965. shader.setUniform1f("uOpacity", material.usePanoMap ? 1: material.opacity);
  966. shader.setUniform2f("elevationRange", material.elevationRange);
  967. shader.setUniform2f("intensityRange", material.intensityRange);
  968. shader.setUniform3f("uIntensity_gbc", [
  969. material.intensityGamma,
  970. material.intensityBrightness,
  971. material.intensityContrast
  972. ]);
  973. shader.setUniform3f("uRGB_gbc", [
  974. material.rgbGamma,
  975. material.rgbBrightness,
  976. material.rgbContrast
  977. ]);
  978. shader.setUniform1f("uTransition", material.transition);
  979. shader.setUniform1f("wRGB", material.weightRGB);
  980. shader.setUniform1f("wIntensity", material.weightIntensity);
  981. shader.setUniform1f("wElevation", material.weightElevation);
  982. shader.setUniform1f("wClassification", material.weightClassification);
  983. shader.setUniform1f("wReturnNumber", material.weightReturnNumber);
  984. shader.setUniform1f("wSourceID", material.weightSourceID);
  985. shader.setUniform("backfaceCulling", material.uniforms.backfaceCulling.value);
  986. //==========================
  987. //gl.TEXTURE_CUBE_MAP: 34067
  988. //gl.TEXTURE0=33984 , vnWebGLTexture.target=gl.TEXTURE_2D = 3353
  989. let vnWebGLTexture = this.textures.get(material.visibleNodesTexture);
  990. if(vnWebGLTexture){
  991. shader.setUniform1i("visibleNodesTexture", currentTextureBindingPoint);
  992. gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
  993. gl.bindTexture(vnWebGLTexture.target, vnWebGLTexture.id);
  994. currentTextureBindingPoint++;
  995. }
  996. let gradientTexture = this.textures.get(material.gradientTexture);
  997. shader.setUniform1i("gradient", currentTextureBindingPoint);
  998. gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
  999. gl.bindTexture(gradientTexture.target, gradientTexture.id);
  1000. const repeat = material.elevationGradientRepeat;
  1001. if(repeat === ElevationGradientRepeat.REPEAT){
  1002. gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_S, gl.REPEAT);
  1003. gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_T, gl.REPEAT);
  1004. }else if(repeat === ElevationGradientRepeat.MIRRORED_REPEAT){
  1005. gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);
  1006. gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
  1007. }else{
  1008. gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  1009. gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  1010. }
  1011. currentTextureBindingPoint++;
  1012. let classificationTexture = this.textures.get(material.classificationTexture);
  1013. shader.setUniform1i("classificationLUT", currentTextureBindingPoint);
  1014. gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
  1015. gl.bindTexture(classificationTexture.target, classificationTexture.id);
  1016. currentTextureBindingPoint++;
  1017. let matcapTexture = this.textures.get(material.matcapTexture);
  1018. shader.setUniform1i("matcapTextureUniform", currentTextureBindingPoint);
  1019. gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
  1020. gl.bindTexture(matcapTexture.target, matcapTexture.id);
  1021. currentTextureBindingPoint++;
  1022. if (material.snapEnabled === true) {
  1023. {
  1024. const lSnapshot = shader.uniformLocations["uSnapshot[0]"];
  1025. const lSnapshotDepth = shader.uniformLocations["uSnapshotDepth[0]"];
  1026. let bindingStart = currentTextureBindingPoint;
  1027. let lSnapshotBindingPoints = new Array(5).fill(bindingStart).map((a, i) => (a + i));
  1028. let lSnapshotDepthBindingPoints = new Array(5)
  1029. .fill(1 + Math.max(...lSnapshotBindingPoints))
  1030. .map((a, i) => (a + i));
  1031. currentTextureBindingPoint = 1 + Math.max(...lSnapshotDepthBindingPoints);
  1032. gl.uniform1iv(lSnapshot, lSnapshotBindingPoints);
  1033. gl.uniform1iv(lSnapshotDepth, lSnapshotDepthBindingPoints);
  1034. for (let i = 0; i < 5; i++) {
  1035. let texture = material.uniforms[`uSnapshot`].value[i];
  1036. let textureDepth = material.uniforms[`uSnapshotDepth`].value[i];
  1037. if (!texture) {
  1038. break;
  1039. }
  1040. let snapTexture = this.threeRenderer.properties.get(texture).__webglTexture;
  1041. let snapTextureDepth = this.threeRenderer.properties.get(textureDepth).__webglTexture;
  1042. let bindingPoint = lSnapshotBindingPoints[i];
  1043. let depthBindingPoint = lSnapshotDepthBindingPoints[i];
  1044. gl.activeTexture(gl[`TEXTURE${bindingPoint}`]);
  1045. gl.bindTexture(gl.TEXTURE_2D, snapTexture);
  1046. gl.activeTexture(gl[`TEXTURE${depthBindingPoint}`]);
  1047. gl.bindTexture(gl.TEXTURE_2D, snapTextureDepth);
  1048. }
  1049. }
  1050. {
  1051. let flattenedMatrices = [].concat(...material.uniforms.uSnapView.value.map(c => c.elements));
  1052. const lSnapView = shader.uniformLocations["uSnapView[0]"];
  1053. gl.uniformMatrix4fv(lSnapView, false, flattenedMatrices);
  1054. }
  1055. {
  1056. let flattenedMatrices = [].concat(...material.uniforms.uSnapProj.value.map(c => c.elements));
  1057. const lSnapProj = shader.uniformLocations["uSnapProj[0]"];
  1058. gl.uniformMatrix4fv(lSnapProj, false, flattenedMatrices);
  1059. }
  1060. {
  1061. let flattenedMatrices = [].concat(...material.uniforms.uSnapProjInv.value.map(c => c.elements));
  1062. const lSnapProjInv = shader.uniformLocations["uSnapProjInv[0]"];
  1063. gl.uniformMatrix4fv(lSnapProjInv, false, flattenedMatrices);
  1064. }
  1065. {
  1066. let flattenedMatrices = [].concat(...material.uniforms.uSnapViewInv.value.map(c => c.elements));
  1067. const lSnapViewInv = shader.uniformLocations["uSnapViewInv[0]"];
  1068. gl.uniformMatrix4fv(lSnapViewInv, false, flattenedMatrices);
  1069. }
  1070. }
  1071. //=============add===========
  1072. if(material.usePanoMap){//为什么pointsize失效
  1073. shader.setUniform1f("progress", material.uniforms.progress.value);
  1074. shader.setUniform1f("easeInOutRatio", material.uniforms.easeInOutRatio.value);
  1075. shader.setUniform3f("pano0Position", material.uniforms.pano0Position.value.toArray());
  1076. shader.setUniform3f("pano1Position", material.uniforms.pano1Position.value.toArray());
  1077. shader.setUniform('pano0Matrix', material.uniforms.pano0Matrix.value);
  1078. shader.setUniform('pano1Matrix', material.uniforms.pano1Matrix.value);
  1079. let pano0Map = material.uniforms.pano0Map.value
  1080. if(pano0Map){
  1081. this.threeRenderer._textures.safeSetTextureCube( pano0Map, ++currentTextureBindingPoint );
  1082. shader.setUniform1i('pano0Map', currentTextureBindingPoint);
  1083. }
  1084. let pano1Map = material.uniforms.pano1Map.value
  1085. if(pano1Map){
  1086. this.threeRenderer._textures.safeSetTextureCube( pano1Map, ++currentTextureBindingPoint );
  1087. shader.setUniform1i('pano1Map', currentTextureBindingPoint);
  1088. }
  1089. //注: three.js我添加了个 _textures, safeSetTextureCube里主要就是activeTexture和bindTexture
  1090. }
  1091. }
  1092. this.renderNodes(octree, nodes, visibilityTextureData, camera, target, shader, params);
  1093. gl.activeTexture(gl.TEXTURE2);
  1094. gl.bindTexture(gl.TEXTURE_2D, null);
  1095. gl.activeTexture(gl.TEXTURE0);
  1096. //gl.bindTexture(gl.TEXTURE_2D, null); //add
  1097. //add 恢复为不透明(否则renderToCubeMap时的贴图会被渲染成高亮的颜色)
  1098. gl.disable(gl.BLEND);
  1099. gl.depthMask(true);
  1100. gl.enable(gl.DEPTH_TEST);
  1101. //DEPTH_TEST等需要恢复吗
  1102. }
  1103. render(scene, camera, target = null, params = {}) {
  1104. const gl = this.gl;
  1105. // PREPARE
  1106. if (target != null) {
  1107. this.threeRenderer.setRenderTarget(target);
  1108. }
  1109. //camera.updateProjectionMatrix();
  1110. // camera.matrixWorldInverse.invert(camera.matrixWorld);
  1111. const traversalResult = this.traverse(scene);
  1112. //排序
  1113. if(Potree.settings.notAdditiveBlending){//add
  1114. traversalResult.octrees.forEach(tree=>{
  1115. if(tree.material.opacity==1){
  1116. tree._z = Infinity //不透明的先渲染
  1117. }else{
  1118. let center = tree.boundCenter ? tree.boundCenter.clone() : tree.boundingBox.getCenter(tree.boundCenter).applyMatrix4(tree.matrixWorld)
  1119. center.project(camera)
  1120. tree._z = center.z
  1121. }
  1122. })
  1123. traversalResult.octrees.sort((tree1,tree2)=>{
  1124. return tree2._z - tree1._z //降序 (-1 朝外)。 离屏幕近的后渲染
  1125. })
  1126. }
  1127. // RENDER
  1128. for (const octree of traversalResult.octrees) {
  1129. let nodes = octree.visibleNodes;
  1130. /* nodes.sort((node1,node2)=>{//姑且
  1131. let center = node.getBoundingSphere().center.clone().applyMatrix4(octree.matrixWorld)
  1132. return
  1133. }) */
  1134. this.renderOctree(octree, nodes, camera, target, params);
  1135. }
  1136. // CLEANUP
  1137. gl.activeTexture(gl.TEXTURE1);
  1138. gl.bindTexture(gl.TEXTURE_2D, null);
  1139. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  1140. gl.bindVertexArray(null);
  1141. this.threeRenderer.resetState();
  1142. }
  1143. };
  1144. /*
  1145. 中东的链接http://indoor.popsmart.cn:8094/zdoblh-yz/?vlon=5.14&vlat=-0.13&fov=100.0&pc=true&lon=121.61136592&lat=29.87855579&z=16.577
  1146. geometry: 有的attributes: 属性是:
  1147. classification:
  1148. color:
  1149. indices:
  1150. normal:
  1151. position:
  1152. 最好有个spacing
  1153. */