1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648 |
- import * as THREE from "../libs/three.js/build/three.module.js";
- import {PointCloudTree} from "./PointCloudTree.js";
- import {PointSizeType, ClipTask, ElevationGradientRepeat} from "./defines.js";
- // Copied from three.js: WebGLRenderer.js
- function paramThreeToGL(_gl, p) {
- let extension;
- if (p === THREE.RepeatWrapping) return _gl.REPEAT;
- if (p === THREE.ClampToEdgeWrapping) return _gl.CLAMP_TO_EDGE;
- if (p === THREE.MirroredRepeatWrapping) return _gl.MIRRORED_REPEAT;
- if (p === THREE.NearestFilter) return _gl.NEAREST;
- if (p === THREE.NearestMipMapNearestFilter) return _gl.NEAREST_MIPMAP_NEAREST;
- if (p === THREE.NearestMipMapLinearFilter) return _gl.NEAREST_MIPMAP_LINEAR;
- if (p === THREE.LinearFilter) return _gl.LINEAR;
- if (p === THREE.LinearMipMapNearestFilter) return _gl.LINEAR_MIPMAP_NEAREST;
- if (p === THREE.LinearMipMapLinearFilter) return _gl.LINEAR_MIPMAP_LINEAR;
- if (p === THREE.UnsignedByteType) return _gl.UNSIGNED_BYTE;
- if (p === THREE.UnsignedShort4444Type) return _gl.UNSIGNED_SHORT_4_4_4_4;
- if (p === THREE.UnsignedShort5551Type) return _gl.UNSIGNED_SHORT_5_5_5_1;
- if (p === THREE.UnsignedShort565Type) return _gl.UNSIGNED_SHORT_5_6_5;
- if (p === THREE.ByteType) return _gl.BYTE;
- if (p === THREE.ShortType) return _gl.SHORT;
- if (p === THREE.UnsignedShortType) return _gl.UNSIGNED_SHORT;
- if (p === THREE.IntType) return _gl.INT;
- if (p === THREE.UnsignedIntType) return _gl.UNSIGNED_INT;
- if (p === THREE.FloatType) return _gl.FLOAT;
- if (p === THREE.HalfFloatType) {
- extension = extensions.get('OES_texture_half_float');
- if (extension !== null) return extension.HALF_FLOAT_OES;
- }
- if (p === THREE.AlphaFormat) return _gl.ALPHA;
- if (p === THREE.RGBFormat) return _gl.RGB;
- if (p === THREE.RGBAFormat) return _gl.RGBA;
- if (p === THREE.LuminanceFormat) return _gl.LUMINANCE;
- if (p === THREE.LuminanceAlphaFormat) return _gl.LUMINANCE_ALPHA;
- if (p === THREE.DepthFormat) return _gl.DEPTH_COMPONENT;
- if (p === THREE.DepthStencilFormat) return _gl.DEPTH_STENCIL;
- if (p === THREE.AddEquation) return _gl.FUNC_ADD;
- if (p === THREE.SubtractEquation) return _gl.FUNC_SUBTRACT;
- if (p === THREE.ReverseSubtractEquation) return _gl.FUNC_REVERSE_SUBTRACT;
- if (p === THREE.ZeroFactor) return _gl.ZERO;
- if (p === THREE.OneFactor) return _gl.ONE;
- if (p === THREE.SrcColorFactor) return _gl.SRC_COLOR;
- if (p === THREE.OneMinusSrcColorFactor) return _gl.ONE_MINUS_SRC_COLOR;
- if (p === THREE.SrcAlphaFactor) return _gl.SRC_ALPHA;
- if (p === THREE.OneMinusSrcAlphaFactor) return _gl.ONE_MINUS_SRC_ALPHA;
- if (p === THREE.DstAlphaFactor) return _gl.DST_ALPHA;
- if (p === THREE.OneMinusDstAlphaFactor) return _gl.ONE_MINUS_DST_ALPHA;
- if (p === THREE.DstColorFactor) return _gl.DST_COLOR;
- if (p === THREE.OneMinusDstColorFactor) return _gl.ONE_MINUS_DST_COLOR;
- if (p === THREE.SrcAlphaSaturateFactor) return _gl.SRC_ALPHA_SATURATE;
- if (p === THREE.RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
- p === THREE.RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) {
- extension = extensions.get('WEBGL_compressed_texture_s3tc');
- if (extension !== null) {
- if (p === THREE.RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
- if (p === THREE.RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
- if (p === THREE.RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
- if (p === THREE.RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
- }
- }
- if (p === THREE.RGB_PVRTC_4BPPV1_Format || p === THREE.RGB_PVRTC_2BPPV1_Format ||
- p === THREE.RGBA_PVRTC_4BPPV1_Format || p === THREE.RGBA_PVRTC_2BPPV1_Format) {
- extension = extensions.get('WEBGL_compressed_texture_pvrtc');
- if (extension !== null) {
- if (p === THREE.RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
- if (p === THREE.RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
- if (p === THREE.RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
- if (p === THREE.RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
- }
- }
- if (p === THREE.RGB_ETC1_Format) {
- extension = extensions.get('WEBGL_compressed_texture_etc1');
- if (extension !== null) return extension.COMPRESSED_RGB_ETC1_WEBGL;
- }
- if (p === THREE.MinEquation || p === THREE.MaxEquation) {
- extension = extensions.get('EXT_blend_minmax');
- if (extension !== null) {
- if (p === THREE.MinEquation) return extension.MIN_EXT;
- if (p === THREE.MaxEquation) return extension.MAX_EXT;
- }
- }
- if (p === UnsignedInt248Type) {
- extension = extensions.get('WEBGL_depth_texture');
- if (extension !== null) return extension.UNSIGNED_INT_24_8_WEBGL;
- }
- return 0;
- };
- let attributeLocations = {
- "position": {name: "position", location: 0},
- "color": {name: "color", location: 1},
- "rgba": {name: "color", location: 1},
- "intensity": {name: "intensity", location: 2},
- "classification": {name: "classification", location: 3},
- "returnNumber": {name: "returnNumber", location: 4},
- "return number": {name: "returnNumber", location: 4},
- "returns": {name: "returnNumber", location: 4},
- "numberOfReturns": {name: "numberOfReturns", location: 5},
- "number of returns": {name: "numberOfReturns", location: 5},
- "pointSourceID": {name: "pointSourceID", location: 6},
- "source id": {name: "pointSourceID", location: 6},
- "point source id": {name: "pointSourceID", location: 6},
- "indices": {name: "indices", location: 7},
- "normal": {name: "normal", location: 8},
- "spacing": {name: "spacing", location: 9},
- "gps-time": {name: "gpsTime", location: 10},
- "aExtra": {name: "aExtra", location: 11},
- };
- class Shader {
- constructor(gl, name, vsSource, fsSource) {
- this.gl = gl;
- this.name = name;
- this.vsSource = vsSource;
- this.fsSource = fsSource;
- this.cache = new Map();
- this.vs = null;
- this.fs = null;
- this.program = null;
- this.uniformLocations = {};
- this.attributeLocations = {};
- this.uniformBlockIndices = {};
- this.uniformBlocks = {};
- this.uniforms = {};
- this.update(vsSource, fsSource);
- }
- update(vsSource, fsSource) {
- this.vsSource = vsSource;
- this.fsSource = fsSource;
- this.linkProgram();
- }
- compileShader(shader, source){
- let gl = this.gl;
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
- let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
- if (!success) {
- let info = gl.getShaderInfoLog(shader);
- let numberedSource = source.split("\n").map((a, i) => `${i + 1}`.padEnd(5) + a).join("\n");
- throw `could not compile shader ${this.name}: ${info}, \n${numberedSource}`;
- }
- }
- linkProgram() {
- const tStart = performance.now();
- let gl = this.gl;
- this.uniformLocations = {};
- this.attributeLocations = {};
- this.uniforms = {};
- gl.useProgram(null);
- let cached = this.cache.get(`${this.vsSource}, ${this.fsSource}`);
- if (cached) {
- this.program = cached.program;
- this.vs = cached.vs;
- this.fs = cached.fs;
- this.attributeLocations = cached.attributeLocations;
- this.uniformLocations = cached.uniformLocations;
- this.uniformBlocks = cached.uniformBlocks;
- this.uniforms = cached.uniforms;
- return;
- } else {
- this.vs = gl.createShader(gl.VERTEX_SHADER);
- this.fs = gl.createShader(gl.FRAGMENT_SHADER);
-
-
-
-
- this.program = gl.createProgram();
-
- if( !gl.isProgram(this.program )){//创建失败 开启多个页面可能会,原因是webglcontextlost
- //console.error('创建program失败');
- viewer.dispatchEvent('webglError', {msg: 'potreeRenderer创建program失败'})
- console.log(this.vs)
- console.log(this.fs)
-
- return;
- }
- for(let name of Object.keys(attributeLocations)){
- let location = attributeLocations[name].location;
- let glslName = attributeLocations[name].name;
- gl.bindAttribLocation(this.program, location, glslName);
- }
- this.compileShader(this.vs, this.vsSource);
- this.compileShader(this.fs, this.fsSource);
- let program = this.program;
- gl.attachShader(program, this.vs);
- gl.attachShader(program, this.fs);
- gl.linkProgram(program);
- gl.detachShader(program, this.vs);
- gl.detachShader(program, this.fs);
-
- // 检测当前程序链接状态
- let success = gl.getProgramParameter(program, gl.LINK_STATUS);
- if (!success) {
- let info = gl.getProgramInfoLog(program);
- throw `could not link program ${this.name}: ${info}`;
- }
- { // attribute locations
- let numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
- for (let i = 0; i < numAttributes; i++) {
- let attribute = gl.getActiveAttrib(program, i);
- let location = gl.getAttribLocation(program, attribute.name);
- this.attributeLocations[attribute.name] = location;
- }
- }
- { // uniform locations
- let numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
- for (let i = 0; i < numUniforms; i++) {
- let uniform = gl.getActiveUniform(program, i);
- let location = gl.getUniformLocation(program, uniform.name);
- this.uniformLocations[uniform.name] = location;
- this.uniforms[uniform.name] = {
- location: location,
- value: null,
- };
- }
- }
- // uniform blocks
- if( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext){ //WebGL2RenderingContext在mac的safari14以下是没有定义的
- let numBlocks = gl.getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS);
- for (let i = 0; i < numBlocks; i++) {
- let blockName = gl.getActiveUniformBlockName(program, i);
- let blockIndex = gl.getUniformBlockIndex(program, blockName);
- this.uniformBlockIndices[blockName] = blockIndex;
- gl.uniformBlockBinding(program, blockIndex, blockIndex);
- let dataSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
- let uBuffer = gl.createBuffer();
- gl.bindBuffer(gl.UNIFORM_BUFFER, uBuffer);
- gl.bufferData(gl.UNIFORM_BUFFER, dataSize, gl.DYNAMIC_READ);
- gl.bindBufferBase(gl.UNIFORM_BUFFER, blockIndex, uBuffer);
- gl.bindBuffer(gl.UNIFORM_BUFFER, null);
- this.uniformBlocks[blockName] = {
- name: blockName,
- index: blockIndex,
- dataSize: dataSize,
- buffer: uBuffer
- };
- }
- }
- let cached = {
- program: this.program,
- vs: this.vs,
- fs: this.fs,
- attributeLocations: this.attributeLocations,
- uniformLocations: this.uniformLocations,
- uniforms: this.uniforms,
- uniformBlocks: this.uniformBlocks,
- };
- this.cache.set(`${this.vsSource}, ${this.fsSource}`, cached);
- }
- const tEnd = performance.now();
- const duration = tEnd - tStart;
- //console.log(`shader compile duration: ${duration.toFixed(3)}`);
- }
- setUniformMatrix4(name, value) {
- const gl = this.gl;
- const location = this.uniformLocations[name];
- if (location == null) {
- return;
- }
- let tmp = new Float32Array(value.elements);
- gl.uniformMatrix4fv(location, false, tmp);
- }
- setUniform1f(name, value) {
- const gl = this.gl;
- const uniform = this.uniforms[name];
- if (uniform === undefined) {
- return;
- }
- if(uniform.value === value){
- return;
- }
- uniform.value = value;
- gl.uniform1f(uniform.location, value);
- }
- setUniformBoolean(name, value) {
- const gl = this.gl;
- const uniform = this.uniforms[name];
- if (uniform === undefined) {
- return;
- }
- if(uniform.value === value){
- return;
- }
- uniform.value = value;
- gl.uniform1i(uniform.location, value);
- }
- setUniformTexture(name, value) {
- const gl = this.gl;
- const location = this.uniformLocations[name];
- if (location == null) {
- return;
- }
- gl.uniform1i(location, value);
- }
- setUniform2f(name, value) {
- const gl = this.gl;
- const location = this.uniformLocations[name];
- if (location == null) {
- return;
- }
- gl.uniform2f(location, value[0], value[1]);
- }
- setUniform3f(name, value) {
- const gl = this.gl;
- const location = this.uniformLocations[name];
- if (location == null) {
- return;
- }
- gl.uniform3f(location, value[0], value[1], value[2]);
- }
- setUniform(name, value) {
- if (value.constructor === THREE.Matrix4) {
- this.setUniformMatrix4(name, value);
- } else if (typeof value === "number") {
- this.setUniform1f(name, value);
- } else if (typeof value === "boolean") {
- this.setUniformBoolean(name, value);
- } else if (value instanceof WebGLTexture) {
- this.setUniformTexture(name, value);
- } else if (value instanceof Array) {
- if (value.length === 2) {
- this.setUniform2f(name, value);
- } else if (value.length === 3) {
- this.setUniform3f(name, value);
- }
- } else {
- console.error("unhandled uniform type: ", name, value);
- }
- }
- setUniform1i(name, value) {
- let gl = this.gl;
- let location = this.uniformLocations[name];
- if (location == null) {
- return;
- }
- gl.uniform1i(location, value);
- }
- };
- class WebGLTexture {
- constructor(gl, texture) {
- this.gl = gl;
- this.texture = texture;
- this.id = gl.createTexture();
- this.target = gl.TEXTURE_2D;
- this.version = -1;
- this.update(texture);
- }
- update() {
- if (!this.texture.image) {
- this.version = this.texture.version;
- return;
- }
- let gl = this.gl;
- let texture = this.texture;
- if (this.version === texture.version) {
- return;
- }
- this.target = gl.TEXTURE_2D;
- gl.bindTexture(this.target, this.id);
- let level = 0;
- let internalFormat = paramThreeToGL(gl, texture.format);
- let width = texture.image.width;
- let height = texture.image.height;
- let border = 0;
- let srcFormat = internalFormat;
- let srcType = paramThreeToGL(gl, texture.type);
- let data;
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
- gl.pixelStorei(gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
- if (texture instanceof THREE.DataTexture) {
- data = texture.image.data;
- gl.texParameteri(this.target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(this.target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, paramThreeToGL(gl, texture.magFilter));
- gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, paramThreeToGL(gl, texture.minFilter));
- gl.texImage2D(this.target, level, internalFormat,
- width, height, border, srcFormat, srcType,
- data);
- } else if ((texture instanceof THREE.CanvasTexture) || (texture instanceof THREE.Texture)) {
- data = texture.image;
- gl.texParameteri(this.target, gl.TEXTURE_WRAP_S, paramThreeToGL(gl, texture.wrapS));
- gl.texParameteri(this.target, gl.TEXTURE_WRAP_T, paramThreeToGL(gl, texture.wrapT));
- gl.texParameteri(this.target, gl.TEXTURE_MAG_FILTER, paramThreeToGL(gl, texture.magFilter));
- gl.texParameteri(this.target, gl.TEXTURE_MIN_FILTER, paramThreeToGL(gl, texture.minFilter));
- gl.texImage2D(this.target, level, internalFormat,
- internalFormat, srcType, data);
- if (texture instanceof THREE.Texture) {gl.generateMipmap(gl.TEXTURE_2D);}
- }
- gl.bindTexture(this.target, null);
- this.version = texture.version;
- }
- };
- class WebGLBuffer {
- constructor() {
- this.numElements = 0;
- this.vao = null;
- this.vbos = new Map();
- }
- };
- export class Renderer {
- constructor(threeRenderer) {
- this.threeRenderer = threeRenderer;
- this.gl = this.threeRenderer.getContext();
-
- this.buffers = new Map();
- this.shaders = new Map();
- this.textures = new Map();
- this.glTypeMapping = new Map();
- this.glTypeMapping.set(Float32Array, this.gl.FLOAT);
- this.glTypeMapping.set(Uint8Array, this.gl.UNSIGNED_BYTE);
- this.glTypeMapping.set(Uint16Array, this.gl.UNSIGNED_SHORT);
- this.toggle = 0;
- }
- deleteBuffer(geometry) {
- let gl = this.gl;
- let webglBuffer = this.buffers.get(geometry);
- if (webglBuffer != null) {
- for (let attributeName in geometry.attributes) {
- gl.deleteBuffer(webglBuffer.vbos.get(attributeName).handle);
- }
- this.buffers.delete(geometry);
- }
- }
- createBuffer(geometry){
- let gl = this.gl;
- let webglBuffer = new WebGLBuffer();
- webglBuffer.vao = gl.createVertexArray();
- webglBuffer.numElements = geometry.attributes.position.count;
- gl.bindVertexArray(webglBuffer.vao);
- for(let attributeName in geometry.attributes){
- let bufferAttribute = geometry.attributes[attributeName];
- let vbo = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
- gl.bufferData(gl.ARRAY_BUFFER, bufferAttribute.array, gl.STATIC_DRAW);
- let normalized = bufferAttribute.normalized;
- let type = this.glTypeMapping.get(bufferAttribute.array.constructor);
- if(attributeLocations[attributeName] === undefined){
- //attributeLocation = attributeLocations["aExtra"];
- }else{
- let attributeLocation = attributeLocations[attributeName].location;
- gl.vertexAttribPointer(attributeLocation, bufferAttribute.itemSize, type, normalized, 0, 0);
- gl.enableVertexAttribArray(attributeLocation);
- }
- webglBuffer.vbos.set(attributeName, {
- handle: vbo,
- name: attributeName,
- count: bufferAttribute.count,
- itemSize: bufferAttribute.itemSize,
- type: geometry.attributes.position.array.constructor,
- version: 0
- });
- }
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
- gl.bindVertexArray(null);
- let disposeHandler = (event) => {
- this.deleteBuffer(geometry);
- geometry.removeEventListener("dispose", disposeHandler);
- };
- geometry.addEventListener("dispose", disposeHandler);
- return webglBuffer;
- }
- updateBuffer(geometry){
- let gl = this.gl;
- let webglBuffer = this.buffers.get(geometry);
- gl.bindVertexArray(webglBuffer.vao);
- for(let attributeName in geometry.attributes){
- let bufferAttribute = geometry.attributes[attributeName];
- let normalized = bufferAttribute.normalized;
- let type = this.glTypeMapping.get(bufferAttribute.array.constructor);
- let vbo = null;
- if(!webglBuffer.vbos.has(attributeName)){
- vbo = gl.createBuffer();
- webglBuffer.vbos.set(attributeName, {
- handle: vbo,
- name: attributeName,
- count: bufferAttribute.count,
- itemSize: bufferAttribute.itemSize,
- type: geometry.attributes.position.array.constructor,
- version: bufferAttribute.version
- });
- }else{
- vbo = webglBuffer.vbos.get(attributeName).handle;
- webglBuffer.vbos.get(attributeName).version = bufferAttribute.version;
- }
- gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
- gl.bufferData(gl.ARRAY_BUFFER, bufferAttribute.array, gl.STATIC_DRAW);
- if(attributeLocations[attributeName] === undefined){
- //attributeLocation = attributeLocations["aExtra"];
- }else{
- let attributeLocation = attributeLocations[attributeName].location;
-
- gl.vertexAttribPointer(attributeLocation, bufferAttribute.itemSize, type, normalized, 0, 0);
- gl.enableVertexAttribArray(attributeLocation);
- }
- }
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
- gl.bindVertexArray(null);
- }
- traverse(scene) {
- let octrees = [];
- let stack = [scene];
- while (stack.length > 0) {
- let node = stack.pop();
- if (node instanceof PointCloudTree) {
- octrees.push(node);
- continue;
- }
- let visibleChildren = node.children.filter(c => c.visible);
- stack.push(...visibleChildren);
- }
- let result = {
- octrees: octrees
- };
- return result;
- }
- renderNodes(octree, nodes, visibilityTextureData, camera, target, shader, params) {
- if (exports.measureTimings) performance.mark("renderNodes-start");
- let gl = this.gl;
- let material = params.material ? params.material : octree.material;
- let shadowMaps = params.shadowMaps == null ? [] : params.shadowMaps;
- let view = camera.matrixWorldInverse;
- if(params.viewOverride){
- view = params.viewOverride;
- }
- let worldView = new THREE.Matrix4();
- let mat4holder = new Float32Array(16);
- let i = 0;
- for (let node of nodes) {
- if(exports.debug.allowedNodes !== undefined){
- if(!exports.debug.allowedNodes.includes(node.name)){
- continue;
- }
- }
- let world = node.sceneNode.matrixWorld;
- worldView.multiplyMatrices(view, world);
- if (visibilityTextureData) {
- let vnStart = visibilityTextureData.offsets.get(node);
- shader.setUniform1f("uVNStart", vnStart);
- }
- let level = node.getLevel();
- if(node.debug){
- shader.setUniform("uDebug", true);
- }else{
- shader.setUniform("uDebug", false);
- }
- // let isLeaf = false;
- // if(node instanceof PointCloudOctreeNode){
- // isLeaf = Object.keys(node.children).length === 0;
- // }else if(node instanceof PointCloudArena4DNode){
- // isLeaf = node.geometryNode.isLeaf;
- // }
- // shader.setUniform("uIsLeafNode", isLeaf);
- // let isLeaf = node.children.filter(n => n != null).length === 0;
- // if(!isLeaf){
- // continue;
- // }
- // TODO consider passing matrices in an array to avoid uniformMatrix4fv overhead
- const lModel = shader.uniformLocations["modelMatrix"];
- if (lModel) {
- mat4holder.set(world.elements);
- gl.uniformMatrix4fv(lModel, false, mat4holder);
- }
- const lModelView = shader.uniformLocations["modelViewMatrix"];
- //mat4holder.set(worldView.elements);
- // faster then set in chrome 63
- for(let j = 0; j < 16; j++){
- mat4holder[j] = worldView.elements[j];
- }
- gl.uniformMatrix4fv(lModelView, false, mat4holder);
- { // Clip Polygons
- if(material.clipPolygons && material.clipPolygons.length > 0){
- let clipPolygonVCount = [];
- let worldViewProjMatrices = [];
- for(let clipPolygon of material.clipPolygons){
- let view = clipPolygon.viewMatrix;
- let proj = clipPolygon.projMatrix;
- let worldViewProj = proj.clone().multiply(view).multiply(world);
- clipPolygonVCount.push(clipPolygon.markers.length);
- worldViewProjMatrices.push(worldViewProj);
- }
- let flattenedMatrices = [].concat(...worldViewProjMatrices.map(m => m.elements));
- let flattenedVertices = new Array(8 * 3 * material.clipPolygons.length);
- for(let i = 0; i < material.clipPolygons.length; i++){
- let clipPolygon = material.clipPolygons[i];
- for(let j = 0; j < clipPolygon.markers.length; j++){
- flattenedVertices[i * 24 + (j * 3 + 0)] = clipPolygon.markers[j].position.x;
- flattenedVertices[i * 24 + (j * 3 + 1)] = clipPolygon.markers[j].position.y;
- flattenedVertices[i * 24 + (j * 3 + 2)] = clipPolygon.markers[j].position.z;
- }
- }
- const lClipPolygonVCount = shader.uniformLocations["uClipPolygonVCount[0]"];
- gl.uniform1iv(lClipPolygonVCount, clipPolygonVCount);
- const lClipPolygonVP = shader.uniformLocations["uClipPolygonWVP[0]"];
- gl.uniformMatrix4fv(lClipPolygonVP, false, flattenedMatrices);
- const lClipPolygons = shader.uniformLocations["uClipPolygonVertices[0]"];
- gl.uniform3fv(lClipPolygons, flattenedVertices);
- }
- }
- //shader.setUniformMatrix4("modelMatrix", world);
- //shader.setUniformMatrix4("modelViewMatrix", worldView);
- shader.setUniform1f("uLevel", level);
- shader.setUniform1f("uNodeSpacing", node.geometryNode.estimatedSpacing);
- shader.setUniform1f("uPCIndex", i);
- // uBBSize
- if (shadowMaps.length > 0) {
- const lShadowMap = shader.uniformLocations["uShadowMap[0]"];
- shader.setUniform3f("uShadowColor", material.uniforms.uShadowColor.value);
- let bindingStart = 5;
- let bindingPoints = new Array(shadowMaps.length).fill(bindingStart).map((a, i) => (a + i));
- gl.uniform1iv(lShadowMap, bindingPoints);
- for (let i = 0; i < shadowMaps.length; i++) {
- let shadowMap = shadowMaps[i];
- let bindingPoint = bindingPoints[i];
- let glTexture = this.threeRenderer.properties.get(shadowMap.target.texture).__webglTexture;
- gl.activeTexture(gl[`TEXTURE${bindingPoint}`]);
- gl.bindTexture(gl.TEXTURE_2D, glTexture);
- }
- {
- let worldViewMatrices = shadowMaps
- .map(sm => sm.camera.matrixWorldInverse)
- .map(view => new THREE.Matrix4().multiplyMatrices(view, world))
- let flattenedMatrices = [].concat(...worldViewMatrices.map(c => c.elements));
- const lWorldView = shader.uniformLocations["uShadowWorldView[0]"];
- gl.uniformMatrix4fv(lWorldView, false, flattenedMatrices);
- }
- {
- let flattenedMatrices = [].concat(...shadowMaps.map(sm => sm.camera.projectionMatrix.elements));
- const lProj = shader.uniformLocations["uShadowProj[0]"];
- gl.uniformMatrix4fv(lProj, false, flattenedMatrices);
- }
- }
- const geometry = node.geometryNode.geometry;
- if(geometry.attributes["gps-time"]){
- const bufferAttribute = geometry.attributes["gps-time"];
- const attGPS = octree.getAttribute("gps-time");
- let initialRange = attGPS.initialRange;
- let initialRangeSize = initialRange[1] - initialRange[0];
- let globalRange = attGPS.range;
- let globalRangeSize = globalRange[1] - globalRange[0];
- let scale = initialRangeSize / globalRangeSize;
- let offset = -(globalRange[0] - initialRange[0]) / initialRangeSize;
- scale = Number.isNaN(scale) ? 1 : scale;
- offset = Number.isNaN(offset) ? 0 : offset;
- shader.setUniform1f("uGpsScale", scale);
- shader.setUniform1f("uGpsOffset", offset);
- //shader.setUniform2f("uFilterGPSTimeClipRange", [-Infinity, Infinity]);
- let uFilterGPSTimeClipRange = material.uniforms.uFilterGPSTimeClipRange.value;
- // let gpsCliPRangeMin = uFilterGPSTimeClipRange[0]
- // let gpsCliPRangeMax = uFilterGPSTimeClipRange[1]
- // shader.setUniform2f("uFilterGPSTimeClipRange", [gpsCliPRangeMin, gpsCliPRangeMax]);
- let normalizedClipRange = [
- (uFilterGPSTimeClipRange[0] - globalRange[0]) / globalRangeSize,
- (uFilterGPSTimeClipRange[1] - globalRange[0]) / globalRangeSize,
- ];
- shader.setUniform2f("uFilterGPSTimeClipRange", normalizedClipRange);
- // // ranges in full gps coordinate system
- // const globalRange = attGPS.range;
- // const bufferRange = bufferAttribute.potree.range;
- // // ranges in [0, 1]
- // // normalizedGlobalRange = [0, 1]
- // // normalizedBufferRange: norm buffer within norm global range e.g. [0.2, 0.8]
- // const globalWidth = globalRange[1] - globalRange[0];
- // const normalizedBufferRange = [
- // (bufferRange[0] - globalRange[0]) / globalWidth,
- // (bufferRange[1] - globalRange[0]) / globalWidth,
- // ];
- // shader.setUniform2f("uNormalizedGpsBufferRange", normalizedBufferRange);
- // let uFilterGPSTimeClipRange = material.uniforms.uFilterGPSTimeClipRange.value;
- // let gpsCliPRangeMin = uFilterGPSTimeClipRange[0]
- // let gpsCliPRangeMax = uFilterGPSTimeClipRange[1]
- // shader.setUniform2f("uFilterGPSTimeClipRange", [gpsCliPRangeMin, gpsCliPRangeMax]);
- // shader.setUniform1f("uGpsScale", bufferAttribute.potree.scale);
- // shader.setUniform1f("uGpsOffset", bufferAttribute.potree.offset);
- }
- {
- let uFilterReturnNumberRange = material.uniforms.uFilterReturnNumberRange.value;
- let uFilterNumberOfReturnsRange = material.uniforms.uFilterNumberOfReturnsRange.value;
- let uFilterPointSourceIDClipRange = material.uniforms.uFilterPointSourceIDClipRange.value;
-
-
-
- shader.setUniform2f("uFilterReturnNumberRange", uFilterReturnNumberRange);
- shader.setUniform2f("uFilterNumberOfReturnsRange", uFilterNumberOfReturnsRange);
- shader.setUniform2f("uFilterPointSourceIDClipRange", uFilterPointSourceIDClipRange);
- }
- let webglBuffer = null;
- if(!this.buffers.has(geometry)){
- webglBuffer = this.createBuffer(geometry);
- this.buffers.set(geometry, webglBuffer);
- }else{
- webglBuffer = this.buffers.get(geometry);
- for(let attributeName in geometry.attributes){
- let attribute = geometry.attributes[attributeName];
- if(attribute.version > webglBuffer.vbos.get(attributeName).version){
- this.updateBuffer(geometry);
- }
- }
- }
- gl.bindVertexArray(webglBuffer.vao);
- let isExtraAttribute =
- attributeLocations[material.activeAttributeName] === undefined
- && Object.keys(geometry.attributes).includes(material.activeAttributeName);
- if(isExtraAttribute){
- const attributeLocation = attributeLocations["aExtra"].location;
- for(const attributeName in geometry.attributes){
- const bufferAttribute = geometry.attributes[attributeName];
- const vbo = webglBuffer.vbos.get(attributeName);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, vbo.handle);
- gl.disableVertexAttribArray(attributeLocation);
- }
- const attName = material.activeAttributeName;
- const bufferAttribute = geometry.attributes[attName];
- const vbo = webglBuffer.vbos.get(attName);
- if(bufferAttribute !== undefined && vbo !== undefined){
- let type = this.glTypeMapping.get(bufferAttribute.array.constructor);
- let normalized = bufferAttribute.normalized;
- gl.bindBuffer(gl.ARRAY_BUFFER, vbo.handle);
- gl.vertexAttribPointer(attributeLocation, bufferAttribute.itemSize, type, normalized, 0, 0);
- gl.enableVertexAttribArray(attributeLocation);
- }
- {
- const attExtra = octree.pcoGeometry.pointAttributes.attributes
- .find(a => a.name === attName);
- let range = material.getRange(attName);
- if(!range){
- range = attExtra.range;
- }
- if(!range){
- range = [0, 1];
- }
- let initialRange = attExtra.initialRange;
- let initialRangeSize = initialRange[1] - initialRange[0];
- let globalRange = range;
- let globalRangeSize = globalRange[1] - globalRange[0];
- let scale = initialRangeSize / globalRangeSize;
- let offset = -(globalRange[0] - initialRange[0]) / initialRangeSize;
- scale = Number.isNaN(scale) ? 1 : scale;
- offset = Number.isNaN(offset) ? 0 : offset;
- shader.setUniform1f("uExtraScale", scale);
- shader.setUniform1f("uExtraOffset", offset);
- }
- }else{
- for(const attributeName in geometry.attributes){
- const bufferAttribute = geometry.attributes[attributeName];
- const vbo = webglBuffer.vbos.get(attributeName);
- if(attributeLocations[attributeName] !== undefined){
- const attributeLocation = attributeLocations[attributeName].location;
- let type = this.glTypeMapping.get(bufferAttribute.array.constructor);
- let normalized = bufferAttribute.normalized;
-
- gl.bindBuffer(gl.ARRAY_BUFFER, vbo.handle);
- gl.vertexAttribPointer(attributeLocation, bufferAttribute.itemSize, type, normalized, 0, 0);
- gl.enableVertexAttribArray(attributeLocation);
-
- }
- }
- }
- let numPoints = webglBuffer.numElements;
-
- gl.drawArrays(gl.POINTS, 0, numPoints);
- //gl.drawArrays(gl.TRIANGLES, 0, numPoints);
-
-
- i++;
- }
- gl.bindVertexArray(null);
- if (exports.measureTimings) {
- performance.mark("renderNodes-end");
- performance.measure("render.renderNodes", "renderNodes-start", "renderNodes-end");
- }
- }
-
-
-
-
- renderOctree(octree, nodes, camera, target, params = {}){
- let gl = this.gl;
- let material = params.material ? params.material : octree.material;
- let shadowMaps = params.shadowMaps == null ? [] : params.shadowMaps;
- let view = camera.matrixWorldInverse;
- let viewInv = camera.matrixWorld;
- if(params.viewOverride){
- view = params.viewOverride;
- viewInv = view.clone().invert();
- }
- let proj = camera.projectionMatrix;
- let projInv = proj.clone().invert();
- //let worldView = new THREE.Matrix4();
- let shader = null;
- let visibilityTextureData = null;
- let currentTextureBindingPoint = 0;
- if (material.pointSizeType >= 0) {
- if (material.pointSizeType === PointSizeType.ADAPTIVE ||
- material.activeAttributeName === "level of detail") {
- let vnNodes = (params.vnTextureNodes != null) ? params.vnTextureNodes : nodes;
- visibilityTextureData = octree.computeVisibilityTextureData(vnNodes, camera);
- const vnt = material.visibleNodesTexture;
- const data = vnt.image.data;
- data.set(visibilityTextureData.data);
- vnt.needsUpdate = true;
- }
- }
- { // UPDATE SHADER AND TEXTURES
- if (!this.shaders.has(material)) {
- let [vs, fs] = [material.vertexShader, material.fragmentShader];
- let shader = new Shader(gl, "pointcloud", vs, fs);
- this.shaders.set(material, shader);
- }
-
- shader = this.shaders.get(material);
- //if(material.needsUpdate){
- {
- let [vs, fs] = [material.vertexShader, material.fragmentShader];
- let numSnapshots = material.snapEnabled ? material.numSnapshots : 0;
- let numClipBoxes = (material.clipBoxes && material.clipBoxes.length) ? material.clipBoxes.length : 0;
- let numClipSpheres = (params.clipSpheres && params.clipSpheres.length) ? params.clipSpheres.length : 0;
- let numClipPolygons = (material.clipPolygons && material.clipPolygons.length) ? material.clipPolygons.length : 0;
- let defines = [
- `#define num_shadowmaps ${shadowMaps.length}`,
- `#define num_snapshots ${numSnapshots}`,
- `#define num_clipboxes ${numClipBoxes}`,
- `#define num_clipspheres ${numClipSpheres}`,
- `#define num_clippolygons ${numClipPolygons}`,
- ];
-
- //add:-----------
- if(material.usePanoMap){
- defines.push("#define usePanoMap");
- }
-
- if(material.useFilterByNormal){
- defines.push("#define use_filter_by_normal");
- //Potree.settings.editType == 'pano' ? defines.push("#define attenuated_opacity2") : defines.push("#define attenuated_opacity");
-
- }
-
- //---------------
-
-
-
- if(octree.pcoGeometry.root.isLoaded()){
- let attributes = octree.pcoGeometry.root.geometry.attributes;
- if(attributes["gps-time"]){
- defines.push("#define clip_gps_enabled");
- }
- if(attributes["return number"]){
- defines.push("#define clip_return_number_enabled");
- }
- if(attributes["number of returns"]){
- defines.push("#define clip_number_of_returns_enabled");
- }
- if(attributes["source id"] || attributes["point source id"]){
- defines.push("#define clip_point_source_id_enabled");
- }
- }
- let definesString = defines.join("\n");
- let vsVersionIndex = vs.indexOf("#version ");
- let fsVersionIndex = fs.indexOf("#version ");
- if(vsVersionIndex >= 0){
- vs = vs.replace(/(#version .*)/, `$1\n${definesString}`)
- }else{
- vs = `${definesString}\n${vs}`;
- }
- if(fsVersionIndex >= 0){
- fs = fs.replace(/(#version .*)/, `$1\n${definesString}`)
- }else{
- fs = `${definesString}\n${fs}`;
- }
- shader.update(vs, fs);
- material.needsUpdate = false;
- }
-
- for (let uniformName of Object.keys(material.uniforms)) {
- let uniform = material.uniforms[uniformName];
- if (uniform.type == "t") {
- let texture = uniform.value;
- if (!texture) {
- continue;
- }
- //add
- if(uniformName == 'pano0Map' || uniformName == 'pano1Map' ){ //属于cubeTex,另外设置
- continue
- }
-
- if (!this.textures.has(texture)) {
- let webglTexture = new WebGLTexture(gl, texture);
- this.textures.set(texture, webglTexture);
- }
- let webGLTexture = this.textures.get(texture);
- webGLTexture.update();
- }
- }
- }
- gl.useProgram(shader.program);
- let transparent = false;
- if(params.transparent !== undefined){
- transparent = params.transparent && material.opacity < 1;
- }else{
- transparent = material.usePanoMap ? false : (material.useFilterByNormal || material.opacity < 1); //add useFilterByNormal
- }
- if (transparent){
- gl.enable(gl.BLEND);
-
- if(params.notAdditiveBlending){
- gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); //NormalBlending
- gl.enable(gl.DEPTH_TEST);
- gl.depthMask(true); //如果不开启depthWrite,深度会错乱。
- }else{
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE); //AdditiveBlending 原本
- gl.disable(gl.DEPTH_TEST);
- gl.depthMask(false);
- }
-
-
- } else {
- gl.disable(gl.BLEND);
- gl.depthMask(true);
- gl.enable(gl.DEPTH_TEST);
- }
- if(params.blendFunc !== undefined){
- gl.enable(gl.BLEND);
- gl.blendFunc(...params.blendFunc);
- }
- if(params.depthTest !== undefined){
- if(params.depthTest === true){
- gl.enable(gl.DEPTH_TEST);
- }else{
- gl.disable(gl.DEPTH_TEST);
- }
- }
- if(params.depthWrite !== undefined){
- if(params.depthWrite === true){
- gl.depthMask(true);
- }else{
- gl.depthMask(false);
- }
-
- }
- { // UPDATE UNIFORMS
- shader.setUniformMatrix4("projectionMatrix", proj);
- shader.setUniformMatrix4("viewMatrix", view);
- shader.setUniformMatrix4("uViewInv", viewInv);
- shader.setUniformMatrix4("uProjInv", projInv);
- /* let screenWidth = target ? target.width : material.screenWidth;
- let screenHeight = target ? target.height : material.screenHeight;
- shader.setUniform1f("uScreenWidth", screenWidth);
- shader.setUniform1f("uScreenHeight", screenHeight); */
-
- shader.setUniform2f('resolution', material.resolution.toArray())
-
-
- shader.setUniform1f("fov", Math.PI * camera.fov / 180);
- shader.setUniform1f("near", camera.near);
- shader.setUniform1f("far", camera.far);
-
- if(camera instanceof THREE.OrthographicCamera){
- shader.setUniform("uUseOrthographicCamera", true);
- shader.setUniform("uOrthoWidth", camera.right - camera.left);
- shader.setUniform("uOrthoHeight", camera.top - camera.bottom);
- }else{
- shader.setUniform("uUseOrthographicCamera", false);
- }
- if(material.clipBoxes.length + material.clipPolygons.length === 0){
- shader.setUniform1i("clipTask", ClipTask.NONE);
- }else{
- shader.setUniform1i("clipTask", material.clipTask);
- }
- shader.setUniform1i("clipMethod", material.clipMethod);
- if (material.clipBoxes && material.clipBoxes.length > 0) {
- //let flattenedMatrices = [].concat(...material.clipBoxes.map(c => c.inverse.elements));
- //const lClipBoxes = shader.uniformLocations["clipBoxes[0]"];
- //gl.uniformMatrix4fv(lClipBoxes, false, flattenedMatrices);
- const lClipBoxes = shader.uniformLocations["clipBoxes[0]"];
- gl.uniformMatrix4fv(lClipBoxes, false, material.uniforms.clipBoxes.value);
- }
- // TODO CLIPSPHERES
- if(params.clipSpheres && params.clipSpheres.length > 0){
- let clipSpheres = params.clipSpheres;
- let matrices = [];
- for(let clipSphere of clipSpheres){
- //let mScale = new THREE.Matrix4().makeScale(...clipSphere.scale.toArray());
- //let mTranslate = new THREE.Matrix4().makeTranslation(...clipSphere.position.toArray());
- //let clipToWorld = new THREE.Matrix4().multiplyMatrices(mTranslate, mScale);
- let clipToWorld = clipSphere.matrixWorld;
- let viewToWorld = camera.matrixWorld
- let worldToClip = clipToWorld.clone().invert();
- let viewToClip = new THREE.Matrix4().multiplyMatrices(worldToClip, viewToWorld);
- matrices.push(viewToClip);
- }
- let flattenedMatrices = [].concat(...matrices.map(matrix => matrix.elements));
- const lClipSpheres = shader.uniformLocations["uClipSpheres[0]"];
- gl.uniformMatrix4fv(lClipSpheres, false, flattenedMatrices);
-
- //const lClipSpheres = shader.uniformLocations["uClipSpheres[0]"];
- //gl.uniformMatrix4fv(lClipSpheres, false, material.uniforms.clipSpheres.value);
- }
- shader.setUniform1f("size", material.usePanoMap ? Potree.config.material.absolutePanoramaSize * Math.min(window.devicePixelRatio,2) : material.size);//usePanoMap时控制在不大不小的范围内感觉较好,考虑到有的点云稀疏,用大一点的点
- shader.setUniform1f("maxSize", material.uniforms.maxSize.value);
- shader.setUniform1f("minSize", material.uniforms.minSize.value);
- // uniform float uPCIndex
- shader.setUniform1f("uOctreeSpacing", material.spacing);
- shader.setUniform("uOctreeSize", material.uniforms.octreeSize.value);
- //uniform vec3 uColor;
- shader.setUniform3f("uColor", material.color.toArray());
- //uniform float opacity;
- shader.setUniform1f("uOpacity", material.usePanoMap ? 1: material.opacity);
- shader.setUniform2f("elevationRange", material.elevationRange);
- shader.setUniform2f("intensityRange", material.intensityRange);
- shader.setUniform3f("uIntensity_gbc", [
- material.intensityGamma,
- material.intensityBrightness,
- material.intensityContrast
- ]);
- shader.setUniform3f("uRGB_gbc", [
- material.rgbGamma,
- material.rgbBrightness,
- material.rgbContrast
- ]);
- shader.setUniform1f("uTransition", material.transition);
- shader.setUniform1f("wRGB", material.weightRGB);
- shader.setUniform1f("wIntensity", material.weightIntensity);
- shader.setUniform1f("wElevation", material.weightElevation);
- shader.setUniform1f("wClassification", material.weightClassification);
- shader.setUniform1f("wReturnNumber", material.weightReturnNumber);
- shader.setUniform1f("wSourceID", material.weightSourceID);
- shader.setUniform("backfaceCulling", material.uniforms.backfaceCulling.value);
-
-
- //==========================
- //gl.TEXTURE_CUBE_MAP: 34067
- //gl.TEXTURE0=33984 , vnWebGLTexture.target=gl.TEXTURE_2D = 3353
-
- let vnWebGLTexture = this.textures.get(material.visibleNodesTexture);
- if(vnWebGLTexture){
- shader.setUniform1i("visibleNodesTexture", currentTextureBindingPoint);
- gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
- gl.bindTexture(vnWebGLTexture.target, vnWebGLTexture.id);
- currentTextureBindingPoint++;
- }
- let gradientTexture = this.textures.get(material.gradientTexture);
- shader.setUniform1i("gradient", currentTextureBindingPoint);
- gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
- gl.bindTexture(gradientTexture.target, gradientTexture.id);
- const repeat = material.elevationGradientRepeat;
- if(repeat === ElevationGradientRepeat.REPEAT){
- gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_T, gl.REPEAT);
- }else if(repeat === ElevationGradientRepeat.MIRRORED_REPEAT){
- gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);
- gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
- }else{
- gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gradientTexture.target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- }
- currentTextureBindingPoint++;
- let classificationTexture = this.textures.get(material.classificationTexture);
- shader.setUniform1i("classificationLUT", currentTextureBindingPoint);
- gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
- gl.bindTexture(classificationTexture.target, classificationTexture.id);
- currentTextureBindingPoint++;
- let matcapTexture = this.textures.get(material.matcapTexture);
- shader.setUniform1i("matcapTextureUniform", currentTextureBindingPoint);
- gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
- gl.bindTexture(matcapTexture.target, matcapTexture.id);
- currentTextureBindingPoint++;
- if (material.snapEnabled === true) {
- {
- const lSnapshot = shader.uniformLocations["uSnapshot[0]"];
- const lSnapshotDepth = shader.uniformLocations["uSnapshotDepth[0]"];
- let bindingStart = currentTextureBindingPoint;
- let lSnapshotBindingPoints = new Array(5).fill(bindingStart).map((a, i) => (a + i));
- let lSnapshotDepthBindingPoints = new Array(5)
- .fill(1 + Math.max(...lSnapshotBindingPoints))
- .map((a, i) => (a + i));
- currentTextureBindingPoint = 1 + Math.max(...lSnapshotDepthBindingPoints);
- gl.uniform1iv(lSnapshot, lSnapshotBindingPoints);
- gl.uniform1iv(lSnapshotDepth, lSnapshotDepthBindingPoints);
- for (let i = 0; i < 5; i++) {
- let texture = material.uniforms[`uSnapshot`].value[i];
- let textureDepth = material.uniforms[`uSnapshotDepth`].value[i];
- if (!texture) {
- break;
- }
- let snapTexture = this.threeRenderer.properties.get(texture).__webglTexture;
- let snapTextureDepth = this.threeRenderer.properties.get(textureDepth).__webglTexture;
- let bindingPoint = lSnapshotBindingPoints[i];
- let depthBindingPoint = lSnapshotDepthBindingPoints[i];
- gl.activeTexture(gl[`TEXTURE${bindingPoint}`]);
- gl.bindTexture(gl.TEXTURE_2D, snapTexture);
- gl.activeTexture(gl[`TEXTURE${depthBindingPoint}`]);
- gl.bindTexture(gl.TEXTURE_2D, snapTextureDepth);
- }
- }
- {
- let flattenedMatrices = [].concat(...material.uniforms.uSnapView.value.map(c => c.elements));
- const lSnapView = shader.uniformLocations["uSnapView[0]"];
- gl.uniformMatrix4fv(lSnapView, false, flattenedMatrices);
- }
- {
- let flattenedMatrices = [].concat(...material.uniforms.uSnapProj.value.map(c => c.elements));
- const lSnapProj = shader.uniformLocations["uSnapProj[0]"];
- gl.uniformMatrix4fv(lSnapProj, false, flattenedMatrices);
- }
- {
- let flattenedMatrices = [].concat(...material.uniforms.uSnapProjInv.value.map(c => c.elements));
- const lSnapProjInv = shader.uniformLocations["uSnapProjInv[0]"];
- gl.uniformMatrix4fv(lSnapProjInv, false, flattenedMatrices);
- }
- {
- let flattenedMatrices = [].concat(...material.uniforms.uSnapViewInv.value.map(c => c.elements));
- const lSnapViewInv = shader.uniformLocations["uSnapViewInv[0]"];
- gl.uniformMatrix4fv(lSnapViewInv, false, flattenedMatrices);
- }
- }
-
-
-
- //=============add===========
-
-
-
- if(material.usePanoMap){//为什么pointsize失效
- shader.setUniform1f("progress", material.uniforms.progress.value);
- shader.setUniform1f("easeInOutRatio", material.uniforms.easeInOutRatio.value);
- shader.setUniform3f("pano0Position", material.uniforms.pano0Position.value.toArray());
- shader.setUniform3f("pano1Position", material.uniforms.pano1Position.value.toArray());
- shader.setUniform('pano0Matrix', material.uniforms.pano0Matrix.value);
- shader.setUniform('pano1Matrix', material.uniforms.pano1Matrix.value);
-
- let pano0Map = material.uniforms.pano0Map.value
- if(pano0Map){
- this.threeRenderer._textures.safeSetTextureCube( pano0Map, ++currentTextureBindingPoint );
-
- shader.setUniform1i('pano0Map', currentTextureBindingPoint);
- }
- let pano1Map = material.uniforms.pano1Map.value
- if(pano1Map){
- this.threeRenderer._textures.safeSetTextureCube( pano1Map, ++currentTextureBindingPoint );
-
- shader.setUniform1i('pano1Map', currentTextureBindingPoint);
- }
-
- //注: three.js我添加了个 _textures, safeSetTextureCube里主要就是activeTexture和bindTexture
-
- }
-
-
-
-
-
- }
- this.renderNodes(octree, nodes, visibilityTextureData, camera, target, shader, params);
- gl.activeTexture(gl.TEXTURE2);
- gl.bindTexture(gl.TEXTURE_2D, null);
- gl.activeTexture(gl.TEXTURE0);
-
-
-
- //gl.bindTexture(gl.TEXTURE_2D, null); //add
-
-
-
-
- //add 恢复为不透明(否则renderToCubeMap时的贴图会被渲染成高亮的颜色)
- gl.disable(gl.BLEND);
- gl.depthMask(true);
- gl.enable(gl.DEPTH_TEST);
- //DEPTH_TEST等需要恢复吗
-
-
- }
-
-
-
-
-
-
-
-
-
-
-
- render(scene, camera, target = null, params = {}) {
-
- const gl = this.gl;
- // PREPARE
- if (target != null) {
- this.threeRenderer.setRenderTarget(target);
- }
- //camera.updateProjectionMatrix();
- // camera.matrixWorldInverse.invert(camera.matrixWorld);
- const traversalResult = this.traverse(scene);
-
- //排序
- if(Potree.settings.notAdditiveBlending){//add
-
- traversalResult.octrees.forEach(tree=>{
- if(tree.material.opacity==1){
- tree._z = Infinity //不透明的先渲染
- }else{
- let center = tree.boundCenter ? tree.boundCenter.clone() : tree.boundingBox.getCenter(tree.boundCenter).applyMatrix4(tree.matrixWorld)
- center.project(camera)
- tree._z = center.z
- }
- })
-
- traversalResult.octrees.sort((tree1,tree2)=>{
- return tree2._z - tree1._z //降序 (-1 朝外)。 离屏幕近的后渲染
- })
- }
-
-
-
-
- // RENDER
- for (const octree of traversalResult.octrees) {
- let nodes = octree.visibleNodes;
-
-
-
- /* nodes.sort((node1,node2)=>{//姑且
-
- let center = node.getBoundingSphere().center.clone().applyMatrix4(octree.matrixWorld)
- return
-
-
- }) */
-
- this.renderOctree(octree, nodes, camera, target, params);
- }
- // CLEANUP
- gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, null);
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
- gl.bindVertexArray(null);
- this.threeRenderer.resetState();
- }
- };
- /*
- 中东的链接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
- geometry: 有的attributes: 属性是:
- classification:
- color:
- indices:
- normal:
- position:
- 最好有个spacing
- */
|