123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746 |
- 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) {
- 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());
-
- /* 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 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++;
- }
- }
- } */
- 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);
- }
-
- }
- //---------------------------------
-
-
- 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("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}`,
- ];
-
- //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(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 (!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) / 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);
- }
- // 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("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++;
-
-
-
-
- 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(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
-
- let mat = traversalResult.octrees[0].material
-
- if(Potree.settings.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
- */
|