12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850 |
- 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},
- //add:
- ir: {name: "ir", location: 12},
- temp: {name: "temp", location: 13},
- };
- 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, threeRenderer) {
- this.gl = gl;
- this.texture = texture;
-
- if(texture.image && !(texture.image instanceof Image) && !texture.isCanvasTexture && !texture.isDataTexture){
- //renderTarget的texture在创建renderTarget时已经初始化过 见setupRenderTarget
- this.id = threeRenderer.properties.get(texture).__webglTexture || gl.createTexture();
- this.isFromRenderTarget = true
- }else{
- 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;
- }
- //if(this.isFromRenderTarget)return //没找到怎么update。 在three.js里的uploadTexture没找到。 这里会报错,可能是 state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ),类似depthTex的写法
- 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));
-
- if(this.isFromRenderTarget){
- //咋写?
- //gl.texImage2D( 3553, 0, internalFormat, width, height, 0, srcFormat, srcType, null )
- //console.log('isFromRenderTarget')
- }else{
- 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);//貌似不能用,uint只能是Uint32Array
- 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) {
-
- viewer.addTimeMark('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;
-
- //---------从renderOctree搬到这----
- shader.setUniform1f("size", material.usePanoMap ? Potree.config.material.absolutePanoramaSize * Math.min(window.devicePixelRatio,2) : material.size);//usePanoMap时控制在不大不小的范围内感觉较好,考虑到有的点云稀疏,用大一点的点
- shader.setUniform1f("uOpacity", material.usePanoMap ? 1: material.opacity);
- shader.setUniform3f("uColor", material.color.toArray());
-
- shader.setUniform2f("temperRange", material.uniforms.temperRange.value.toArray());
-
- let currentTextureBindingPoint = params.currentTextureBindingPoint
- if (material.pointSizeType >= 0/* && window.needvisibilityTexture */) {
-
- 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;
-
- let webGLTexture = this.textures.get(vnt)
- webGLTexture.update(); //不加这个会闪烁
-
-
- let vnWebGLTexture = this.textures.get(material.visibleNodesTexture); //不知道为什么这段从renderOctree中移过来,会崩溃。暂时不移动了
- if(vnWebGLTexture){
- shader.setUniform1i("visibleNodes", currentTextureBindingPoint);
- gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
- gl.bindTexture(vnWebGLTexture.target, vnWebGLTexture.id);
- currentTextureBindingPoint++;
- }
- }
- }
-
-
-
-
-
-
- /* 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;
- }
- } */
-
-
-
-
-
-
-
-
-
-
-
-
- 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.disable(gl.DEPTH_TEST); gl.depthMask(true); //old
- gl.enable(gl.DEPTH_TEST); gl.depthMask(false);
- //gl.enable(gl.DEPTH_TEST); gl.depthMask(true);
- //gl.disable(gl.DEPTH_TEST);
- /* 几种选择:
- 1 都开启: 当opacity很小时发黑且遮住其他透明物体
- 2 关闭depthTest开启depthWrite 自己深度错乱,前排挡不住后排, 自己将后排的晚渲染可以改善,见disSqToCamZ_。 但前排不透明遮不住它!之前没发现
- 3 开启depthTest关闭depthWrite 除了2的缺点,还挡不住后排的半透明物体(因为后渲染),或被先渲染的前排透明物体完全遮住。(写入深度值就会遮住后方。总之透明的要后渲染而且按距离排序,但mesh和点云排序是不可能了) 采用这项
- 4 关闭depthTest关闭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);
- }
-
- }
- //---------------------------------
-
-
- 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);
- //console.log('vnStart',vnStart)
- 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("levelPercent", octree.nodeMaxLevel ? level / octree.nodeMaxLevel : 0.5);//xzw add
-
- 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);
-
- viewer.addTimeMark('renderNodes','end')
- }
-
-
-
-
- renderOctree(octrees, nodes, camera, target, params = {}){
- viewer.addTimeMark('renderOctree','start')
- let octree
- if(octrees instanceof Array){
- octree = octrees[0];
- }else{
- octree = octrees; octrees = [octree]
- }
- 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) {//最好搬到renderNodes
- 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.shaderNeedsUpdate)
- {
- let [vs, fs] = [material.vertexShader, material.fragmentShader];
- let numSnapshots = material.snapEnabled ? material.numSnapshots : 0;
- let num_in_clipboxes = (material.clipBoxes_in && material.clipBoxes_in.length) ? material.clipBoxes_in.length : 0;
- let num_out_clipboxes = (material.clipBoxes_out && material.clipBoxes_out.length) ? material.clipBoxes_out.length : 0;
- let num_highlightBox = (material.highlightBoxes && material.highlightBoxes.length) ? material.highlightBoxes.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_in_clipboxes ${num_in_clipboxes}`, //改
- `#define num_out_clipboxes ${num_out_clipboxes}`, //改
- `#define num_highlightBox ${num_highlightBox}`, //改
- `#define num_clipspheres ${numClipSpheres}`,
-
- `#define num_prism ${material.prisms.pointsCount ? material.prisms.length : 0}`, //土方量数 如果num_prism>0,prismPointCountSum为0 会报错 :array size must be greater than zero
- `#define prismPointCountSum ${material.prisms.pointsCount}`,//点总个数
- `#define prism_maxPointsCount ${material.prisms.maxPointsCount}`, //单个prism最大点个数 (如果define也能传递个数数组,就不用再uniform里传了,呜 )
-
- ];
-
- //add:-----------
- if(material.bigClipInBox ){//裁剪下载
- defines.push('#define bigClipInBox')
- }
-
- 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(material.uniforms.baseHeightAreaMap.value){//根据模型高亮土方
- defines.push('#define showBaseHeight')
- }
- //---------------
-
-
-
- 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.shaderNeedsUpdate = 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(texture.image && !(texture.image instanceof Image) && !(texture instanceof THREE.CanvasTexture)){
- //renderTarget的texture在创建renderTarget时已经初始化过 见setupRenderTarget
- continue
- } */
-
- if (!this.textures.has(texture) || texture.needsRebuild) {
- let webglTexture = new WebGLTexture(gl, texture, this.threeRenderer);
- this.textures.set(texture, webglTexture);
- delete texture.needsRebuild //renderTarget在resize后会触发dispose, 然后 _gl.deleteTexture( textureProperties.__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) / camera.zoom); //改
- 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_in && material.clipBoxes_in.length > 0) {
- //let flattenedMatrices = [].concat(...material.clipBoxes.map(c => c.inverse.elements));
- const lClipBoxes = shader.uniformLocations["clipBoxes_in[0]"];
- gl.uniformMatrix4fv(lClipBoxes, false, material.uniforms.clipBoxes_in.value);
- }
-
- if (material.clipBoxes_out && material.clipBoxes_out.length > 0) {//add
- const lClipBoxes2 = shader.uniformLocations["clipBoxes_out[0]"];
- gl.uniformMatrix4fv(lClipBoxes2, false, material.uniforms.clipBoxes_out.value);
- }
- if (material.highlightBoxes && material.highlightBoxes.length > 0) {//add
- const boxes_highlight = shader.uniformLocations["boxes_highlight[0]"];
- gl.uniformMatrix4fv(boxes_highlight, false, material.uniforms.boxes_highlight.value);
- }
- if (material.bigClipInBox ) {//add
- shader.setUniformMatrix4("clipBoxBig_in", material.uniforms.clipBoxBig_in.value);
- }
- if(material.uniforms.baseHeightAreaMap.value ){//根据模型高亮土方
- const baseHeightBoundZ = shader.uniformLocations["baseHeightBoundZ"];
- gl.uniform2f(baseHeightBoundZ, ...material.uniforms.baseHeightBoundZ.value.toArray());
- const baseHeightBoundXY = shader.uniformLocations["baseHeightBoundXY"];
- gl.uniform4f(baseHeightBoundXY, ...material.uniforms.baseHeightBoundXY.value.toArray());
- }
-
- if(material.prisms.length){
- const prismList = shader.uniformLocations["prismList[0]"];
- gl.uniformMatrix3fv(prismList, false, material.uniforms.prismList.value);
-
- const prismPoints = shader.uniformLocations["prismPoints[0]"];
- gl.uniform2fv(prismPoints, material.uniforms.prismPoints.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("orthoMaxSize", material.uniforms.orthoMaxSize.value);
- 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);
-
- 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);//最好搬到renderNodes
- if(vnWebGLTexture){
- shader.setUniform1i("visibleNodes", currentTextureBindingPoint); //为何之前写的是"visibleNodesTexture",但和"visibleNodes"效果相同?可shader里只有"visibleNodes"
- 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);
- currentTextureBindingPoint++;
-
-
- 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++; */
-
-
-
- let baseHeightAreaMap = material.uniforms.baseHeightAreaMap.value
- if(baseHeightAreaMap){//根据模型高亮土方
- let map = this.textures.get(baseHeightAreaMap);
- shader.setUniform1i("baseHeightAreaMap", currentTextureBindingPoint);
- gl.activeTexture(gl.TEXTURE0 + currentTextureBindingPoint);
- gl.bindTexture(map.target, map.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
-
- }
- }
- viewer.addTimeMark('renderOctree','end')
-
- params.currentTextureBindingPoint = ++currentTextureBindingPoint
- octrees.forEach(octree=>{
- this.renderNodes(octree, nodes || octree.visibleNodes, 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(params.notAdditiveBlending){//add
-
- traversalResult.octrees.forEach(tree=>{
- if(tree.material.opacity==1){
- tree._z = Infinity //不透明的先渲染 //2024.10发现没用,会透过不透明的看到后面透明的orz
- }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
-
- let mat = params.material || traversalResult.octrees[0].material
- let cloudSameMat = Potree.settings.cloudSameMat && !traversalResult.octrees.some(e=>e.material.activeAttributeName != mat.activeAttributeName) //activeAttributeName都一样才行
-
- if(cloudSameMat && viewer.scene.volumes.length == 0 && mat.pointSizeType != PointSizeType.ADAPTIVE && mat.activeAttributeName != "level of detail"){
- this.renderOctree(traversalResult.octrees, null, camera, target, params); //所有点云除了个别属性需要在shader中更新,其他都使用第一个点云的材质
- }else for (const octree of traversalResult.octrees) {
- for (const octree of traversalResult.octrees) {
- this.renderOctree(octree, octree.visibleNodes, camera, target, params);
- }
- }
-
- //if (octree material.pointSizeType === PointSizeType.ADAPTIVE || material.activeAttributeName === "level of detail") {
-
-
-
- // 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
- */
|