diff --git a/packages/gl/src/reshader/common/REGLHelper.js b/packages/gl/src/reshader/common/REGLHelper.js index 7c7c62f5e0..86df3d555e 100644 --- a/packages/gl/src/reshader/common/REGLHelper.js +++ b/packages/gl/src/reshader/common/REGLHelper.js @@ -18,6 +18,20 @@ export function getMaterialType(type) { } +export function getArrayType(array) { + if (array instanceof Uint8Array) { + return 'uint8'; + } else if (array instanceof Int8Array) { + return 'int8'; + } else if (array instanceof Uint16Array) { + return 'uint16'; + } else if (array instanceof Int16Array) { + return 'int16'; + } else { + return 'float'; + } +} + const materialFormats = { 0x1906: 'alpha', 0x1907: 'rgb', @@ -100,6 +114,9 @@ export function getUniqueREGLBuffer(regl, data, options) { extend(info, options); } info.data = array; + if (!info.type) { + info.type = getArrayType(array); + } buffer = regl.buffer(info); // console.log(count++, (array.byteLength / 1024 / 1024).toFixed(1)); arrayBuffer[BUFFER_KEY][byteOffset] = buffer; diff --git a/packages/gl/src/reshader/common/Util.ts b/packages/gl/src/reshader/common/Util.ts index 0fb53eea61..936bc99f36 100644 --- a/packages/gl/src/reshader/common/Util.ts +++ b/packages/gl/src/reshader/common/Util.ts @@ -241,6 +241,9 @@ export function clamp(n: number, min: number, max: number) { * @returns */ export function isSupportVAO(regl: any) { + if (globalThis['MAPTALKS_DISABLE_VAO']) { + return false; + } if (regl.wgpu) { return false; } diff --git a/packages/gl/src/reshader/pbr/glsl/depth.vert b/packages/gl/src/reshader/pbr/glsl/depth.vert index 1b9bcc719f..4a371e091d 100644 --- a/packages/gl/src/reshader/pbr/glsl/depth.vert +++ b/packages/gl/src/reshader/pbr/glsl/depth.vert @@ -1,5 +1,4 @@ #define SHADER_NAME depth_vert -precision highp float; attribute vec3 aPosition; #include diff --git a/packages/gl/src/reshader/pbr/glsl/standard.vert b/packages/gl/src/reshader/pbr/glsl/standard.vert index 674251014d..9e23697dea 100644 --- a/packages/gl/src/reshader/pbr/glsl/standard.vert +++ b/packages/gl/src/reshader/pbr/glsl/standard.vert @@ -1,6 +1,5 @@ #include #define SHADER_NAME PBR -precision highp float; attribute vec3 aPosition; diff --git a/packages/gl/src/reshader/water/water.vert b/packages/gl/src/reshader/water/water.vert index 07537f495c..e43472522f 100644 --- a/packages/gl/src/reshader/water/water.vert +++ b/packages/gl/src/reshader/water/water.vert @@ -1,5 +1,3 @@ -precision highp float; -precision highp sampler2D; const float PI = 3.141592653589793; uniform mat4 projMatrix; uniform mat4 viewMatrix; diff --git a/packages/layer-3dtiles/src/layer/renderer/TileMeshPainter.js b/packages/layer-3dtiles/src/layer/renderer/TileMeshPainter.js index 5195dfd580..4562211674 100644 --- a/packages/layer-3dtiles/src/layer/renderer/TileMeshPainter.js +++ b/packages/layer-3dtiles/src/layer/renderer/TileMeshPainter.js @@ -1,6 +1,7 @@ import * as maptalks from 'maptalks'; import { reshader, vec3, vec4, mat3, mat4, quat, HighlightUtil, ContextUtil } from '@maptalks/gl'; import { iterateMesh, iterateBufferData, getItemAtBufferData, setInstanceData, } from '../../common/GLTFHelpers'; +import pickingVert from './glsl/picking.vert'; import pntsVert from './glsl/pnts.vert'; import pntsFrag from './glsl/pnts.frag'; import { isFunction, isNil, extend, setColumn3, flatArr, isNumber, normalizeColor, pushIn } from '../../common/Util'; @@ -10,7 +11,9 @@ import { isFunctionDefinition, interpolated } from '@maptalks/function-type'; // import { getKHR_techniques } from './s3m/S3MTechnique'; -const { getTextureMagFilter, getTextureMinFilter, getTextureWrap, getMaterialType, getMaterialFormat, getPrimitive, getUniqueREGLBuffer } = reshader.REGLHelper; +const { getTextureMagFilter, getTextureMinFilter, + getTextureWrap, getMaterialType, getMaterialFormat, + getPrimitive, getUniqueREGLBuffer, getArrayType } = reshader.REGLHelper; const Y_TO_Z = [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1]; const X_TO_Z = [0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1]; @@ -1452,6 +1455,7 @@ export default class TileMeshPainter { const isWebGPU = this.getMap().getRenderer().isWebGPU(); const attrs = {}; let positionSize = 0; + let vertexCount = 0; for (const p in attributes) { // 优先采用 attributeSemantics中定义的属性 const name = attributeSemantics[p] || p; @@ -1478,11 +1482,19 @@ export default class TileMeshPainter { attrs[name] = extend({}, attributes[p]); attrs[name].buffer = buffer; + attrs[name].type = getArrayType(attrs[name].array); delete attrs[name].array; if (name === attributeSemantics['POSITION']) { attrs[name].array = attributes[p].array; + vertexCount = attributes[p].array.length / 3; } } + // 补上缺失的_BATHCID属性,解决macos下 vertex buffer not big enough 报错 + const pickingIdAttribute = attributeSemantics['_BATCHID']; + if (!attrs[pickingIdAttribute] && !isI3DM) { + const pickingData = new Uint8Array(vertexCount); + attrs[pickingIdAttribute] = pickingData; + } // createColorArray(attrs); const indices = gltfMesh.indices ? (gltfMesh.indices.array ? gltfMesh.indices.array.slice() : gltfMesh.indices) : null; const geometry = new reshader.Geometry( @@ -1679,7 +1691,7 @@ export default class TileMeshPainter { this.picking = new reshader.FBORayPicking( this._renderer, { - vert: this._standardShader.vert, + vert: pickingVert, extraCommandProps, uniforms: this._standardShader.uniforms, defines: { diff --git a/packages/layer-3dtiles/src/layer/renderer/glsl/picking.vert b/packages/layer-3dtiles/src/layer/renderer/glsl/picking.vert new file mode 100644 index 0000000000..0c25f5fe7b --- /dev/null +++ b/packages/layer-3dtiles/src/layer/renderer/glsl/picking.vert @@ -0,0 +1,53 @@ +#include +#define SHADER_NAME GEO_3DTILES_PICKING + +attribute vec3 aPosition; + +#if defined(HAS_COLOR) + attribute vec4 aColor; +#endif +#if defined(HAS_COLOR0) + #if COLOR0_SIZE == 3 + attribute vec3 aColor0; + varying vec3 vColor0; + #else + attribute vec4 aColor0; + varying vec4 vColor0; + #endif +#endif + + +uniform mat4 modelMatrix; +uniform mat4 modelViewMatrix; +uniform mat4 positionMatrix; +uniform mat4 projMatrix; + +#include +#include + +#include +void main() { + mat4 localPositionMatrix = getPositionMatrix(); + vec4 localVertex = getPosition(aPosition); + + vec4 position = localPositionMatrix * localVertex; + vec4 viewVertex = modelViewMatrix * position; + + #ifdef HAS_MASK_EXTENT + gl_Position = projMatrix * getMaskPosition(position, modelMatrix); + #else + gl_Position = projMatrix * viewVertex; + #endif + + float alpha = 1.0; + #if defined(HAS_COLOR) + alpha *= aColor.a; + #endif + #if defined(HAS_COLOR0) && COLOR0_SIZE == 4 + alpha *= aColor0.a; + #endif + + fbo_picking_setData(gl_Position.w, alpha != 0.0); + + +} diff --git a/packages/layer-3dtiles/test/layer.identify.spec.js b/packages/layer-3dtiles/test/layer.identify.spec.js index 92633c83d4..d823e568c8 100644 --- a/packages/layer-3dtiles/test/layer.identify.spec.js +++ b/packages/layer-3dtiles/test/layer.identify.spec.js @@ -1,5 +1,6 @@ const maptalks = require('maptalks'); require('@maptalks/gl'); +const { GroupGLLayer } = require('@maptalks/gl'); require('@maptalks/transcoders.draco'); require('@maptalks/transcoders.ktx2'); require('@maptalks/transcoders.crn'); @@ -42,6 +43,33 @@ describe('3dtiles identify specs', () => { document.body.innerHTML = ''; }); + it('can identify b3dm data in MacOS, maptalks/issues#470', done => { + globalThis['MAPTALKS_DISABLE_VAO'] = true; + const resPath = 'BatchedDraco/dayanta/'; + const layer = new Geo3DTilesLayer('3d-tiles', { + services : [ + { + url : `http://localhost:${PORT}/integration/fixtures/${resPath}/tileset.json`, + shader: 'phong', + heightOffset: -420 + } + ] + }); + const group = new GroupGLLayer('group', [layer]); + group.addTo(map); + layer.once('loadtileset', () => { + const extent = layer.getExtent(0); + map.fitExtent(extent, 0, { animation: false }); + setTimeout(function() { + const point = new maptalks.Point(255, 497); + const hits = layer.identifyAtPoint(point); + assert(hits[0].data.batchId === 0); + globalThis['MAPTALKS_DISABLE_VAO'] = false; + done(); + }, 1500); + }); + }).timeout(5000); + it('can identify b3dm data', done => { const resPath = 'Cesium3DTiles/Batched/BatchedWithBatchTable'; const layer = new Geo3DTilesLayer('3d-tiles', {