Attributes render out of order in shared Webgl environment
See original GitHub issueDescribe the bug
I’m using shared Webgl for map, but found that since version r118, the rendered attributes data will be rendered garbled, I found that the needUpdate function does not return true; if I force needUpdate to return true, then it seems to work
Code
// code goes here
function needsUpdate(geometry, index) {
// good
return true;
const cachedAttributes = currentState.attributes;
const geometryAttributes = geometry.attributes;
let attributesNum = 0;
for (const key in geometryAttributes) {
const cachedAttribute = cachedAttributes[key];
const geometryAttribute = geometryAttributes[key];
if (cachedAttribute === undefined) return true;
if (cachedAttribute.attribute !== geometryAttribute) return true;
if (cachedAttribute.data !== geometryAttribute.data) return true;
attributesNum++;
}
if (currentState.attributesNum !== attributesNum) return true;
if (currentState.index !== index) return true;
return false;
}
Live example I can not get jsfidle , so…
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>自定义三维图层</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
<style>
html,
body,
#container {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://webapi.amap.com/maps?v=2.0&key=dc695ce0c94242cb2f1eaddfe6ba580e"></script>
<!-- error -->
<!-- <script src="https://cdn.bootcdn.net/ajax/libs/three.js/r134/three.js"></script> -->
<!-- good -->
<script src="https://cdn.bootcdn.net/ajax/libs/three.js/r117/three.js"></script>
<script type="text/javascript">
var map = new AMap.Map('container', {
center: [116.54, 39.79],
zooms: [2, 20],
zoom: 14,
viewMode: '3D',
pitch: 50,
});
// map.getLayers().forEach(function (layer) {
// // layer.hide()
// })
var camera;
var renderer;
var scene;
// 数据转换工具
var customCoords = map.customCoords;
// 数据使用转换工具进行转换,这个操作必须要提前执行(在获取镜头参数 函数之前执行),否则将会获得一个错误信息。
var data = customCoords.lngLatsToCoords([
[116.52, 39.79],
[116.54, 39.79],
[116.56, 39.79],
]);
// 创建 GL 图层
var gllayer = new AMap.GLCustomLayer({
// 图层的层级
zIndex: 10,
// 初始化的操作,创建图层过程中执行一次。
init: (gl) => {
// 这里我们的地图模式是 3D,所以创建一个透视相机,相机的参数初始化可以随意设置,因为在 render 函数中,每一帧都需要同步相机参数,因此这里变得不那么重要。
// 如果你需要 2D 地图(viewMode: '2D'),那么你需要创建一个正交相机
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 1 << 10);
renderer = new THREE.WebGLRenderer({
// context: gl, // 地图的 gl 上下文
alpha: true,
antialias: true,
canvas: gl.canvas,
});
// 自动清空画布这里必须设置为 false,否则地图底图将无法显示
renderer.autoClear = false;
scene = new THREE.Scene();
// 这里可以使用 three 的各种材质,示例使用的是 three 的自定义 shader
// var material = new THREE.PointsMaterial({
// color: 0xff00f0,
// size: 100,
// depthTest: false,
// transparent: true,
// vertexColors: false,
// isMaterial: true,
// precision: 'highp',
// premultipliedAlpha: true,
// dithering: true,
// toneMapped: false,
// });
var material = new THREE.RawShaderMaterial({
depthTest: true,
transparent: true,
side: THREE.DoubleSide,
vertexShader: `
precision highp float;
attribute vec3 position;
attribute vec4 color;
uniform mat4 modelViewMatrix; // optional
uniform mat4 projectionMatrix; // optional
varying vec4 vColor;
void main() {
vColor = color;
gl_PointSize = 100.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position.xy, 0, 1.0 );
}
`,
fragmentShader: `
precision highp float;
varying vec4 vColor;
void main() {
gl_FragColor = vColor;
}
`,
});
var geometry = new THREE.BufferGeometry();
var ver = [];
var color = [];
for (var i = 0; i < data.length; i++) {
var d = data[i];
// 每一个点的坐标,x/y/z,这里我们给 10 米的高度。
ver.push(d[0], d[1], 1000 * Math.random());
// 每个点的颜色随机给
color.push(0.6, 0.5, 0.7, 1);
}
// console.log(ver);
// geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.setAttribute('position', new THREE.Float32BufferAttribute(ver, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(color), 4));
var mesh = new THREE.Points(geometry, material);
scene.add(mesh);
// const stats = new Stats();
// container.appendChild( stats.dom );
},
render: () => {
// 这里必须执行!!重新设置 three 的 gl 上下文状态。
renderer.state.reset();
renderer.resetAttributes && renderer.resetAttributes();
var { near, far, fov, up, lookAt, position } = customCoords.getCameraParams();
// 2D 地图下使用的正交相机
// var { near, far, top, bottom, left, right, position, rotation } = customCoords.getCameraParams();
// console.log(near, far, fov, up, lookAt, position);
// 这里的顺序不能颠倒,否则可能会出现绘制卡顿的效果。
camera.near = near;
camera.far = far;
camera.fov = fov;
camera.position.set(...position);
camera.up.set(...up);
camera.lookAt(...lookAt);
camera.updateProjectionMatrix();
// 2D 地图使用的正交相机参数赋值
// camera.top = top;
// camera.bottom = bottom;
// camera.left = left;
// camera.right = right;
// camera.position.set(...position);
// camera.updateProjectionMatrix();
renderer.render(scene, camera);
},
});
map.add(gllayer);
</script>
</body>
</html>
Issue Analytics
- State:
- Created a year ago
- Comments:8 (1 by maintainers)
Top Results From Across the Web
WebGL Rendering to a Texture
How to render to a texture. ... We just need WebGL to allocate the texture. ... Tell the position attribute how to get...
Read more >In WebGL - when instancing geometry, is it possible to pass ...
It depends on what you mean by. is it possible to pass per-vertex data for each instance of the geometry that gets rendered?...
Read more >WebGLRenderer – three.js docs
Returns an object that describes the attributes set on the WebGL context when it was created. # .getActiveCubeFace () : Integer. Returns the...
Read more >WebGL2 Optimization - Instanced Drawing
WebGL has a feature called instanced drawing. It is basically a way to draw more than one of the same thing faster than...
Read more >Rendering order in the Built-in Render Pipeline - Unity - Manual
By default, Unity places objects in the render queue specified in their Unity shader. You define this value using the [Queue] SubShader tag....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Not true, you can share the same WebGL context over different libraries (e.g. mapbox and three.js).
Can you please replace this code via:
I believe you run into #20549.
OK~ Good Job !