Three.js 为什么在mapbox中绘制3JS对象,有很多网格锯齿?
我使用customlayer接口绘制threejs对象。但它有很多锯齿 但我发现了一个插件(threebox),可以在mapbox中绘制对象,而且绘制起来很平滑。喜欢这个图像吗 在这张图片中,较高的黄色球是由我的代码创建的,它有许多锯齿。下面的红色球是由threebox创建的threebox,它是平滑的。 那里发生了什么事?我查看了三盒源代码,没有发现与我的代码不同 我把我的代码放在JSBin上。这是链接 请看一看,帮帮我,谢谢Three.js 为什么在mapbox中绘制3JS对象,有很多网格锯齿?,three.js,mapbox,Three.js,Mapbox,我使用customlayer接口绘制threejs对象。但它有很多锯齿 但我发现了一个插件(threebox),可以在mapbox中绘制对象,而且绘制起来很平滑。喜欢这个图像吗 在这张图片中,较高的黄色球是由我的代码创建的,它有许多锯齿。下面的红色球是由threebox创建的threebox,它是平滑的。 那里发生了什么事?我查看了三盒源代码,没有发现与我的代码不同 我把我的代码放在JSBin上。这是链接 请看一看,帮帮我,谢谢 <!DOCTYPE html> <html l
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- mapboxgl -->
<script src="https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.css" rel="stylesheet" />
<!-- echarts -->
<!-- <script src="https://cdn.jsdelivr.net/npm/echarts@4.6.0/dist/echarts.min.js"></script> -->
<!-- <script src="https://cdn.jsdelivr.net/npm/echarts-gl@1.1.1/dist/echarts-gl.min.js"></script> -->
<!-- <script src="echarts.min.385.js"></script> -->
<!-- <script src="echarts-gl-master.m.js"></script> -->
<!-- 其他 -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<!-- <script src="assets/world.js"></script> -->
<!-- 百度地图 -->
<!-- <script src="https://gallerybox.echartsjs.com/dep/echarts/latest/extension/bmap.min.js"></script>
<script src="https://api.map.baidu.com/api?v=3.0&ak=9Y5hSOZKKo9QcWrwag0qMYYvQ6PIKEzw"></script> -->
<style>
body,
html,
#map {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map" class='map'></div>
<!-- <script src="echartsopt.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<!-- <script src="three3.js"></script> -->
<script src="https://unpkg.com/three@0.106.2/examples/js/loaders/GLTFLoader.js"></script>
<script src="https://d3js.org/d3-geo.v1.min.js"></script>
<script src="https://gitcdn.link/repo/peterqliu/threebox/master/dist/threebox.js"></script>
<!-- <script src="mapboxopt.js" type="module"></script> -->
<!-- <script src="mapboxopt.js"></script> -->
<script src="mapboxextrude.js"></script>
<!-- <script src="3dmodel.js"></script> -->
<script>
var __mapcenter__ = [116.582, 35.415];
mapboxgl.accessToken = 'pk.eyJ1IjoiaG91eGlleXUiLCJhIjoiY2pldjE5amU3NndzeDM5bzd5bm9ncDgycyJ9.j1F-Lgid3L5k2Abm8_xTeQ';
var mapboxgl_style = 'mapbox://styles/mapbox/dark-v10';
var tb;
function addTB(mapd, gl) {
tb = new Threebox(
mapd,
gl,
{ defaultLights: true }
);
var sphere = tb.sphere({radius:1, color: 'red', material: 'MeshStandardMaterial' })
.setCoords(__mapcenter__.concat([500]));
// add sphere to the scene
tb.add(sphere);
}
const linetype = 0;//0=normal 1=fat
// var map = myChart.getModel().getComponent('mapbox3D').getMapbox();
var map = new mapboxgl.Map({
container: 'map',
style: mapboxgl_style,
zoom: 16,
center: __mapcenter__,
pitch: 20,
antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
});
$.ajaxSettings.async = false;
var linesdata;
$.getJSON('jp4data.json',
function (res) {
linesdata = res;
});
// configuration of the custom layer for a 3D model per the CustomLayerInterface
function initThree(_this, mapd) {
_this.camera = new THREE.Camera();
_this.scene = new THREE.Scene();
// create two three.js lights to illuminate the model
// var directionalLight = new THREE.DirectionalLight(0xffffff);
// directionalLight.position.set(0, -70, 100).normalize();
// this.scene.add(directionalLight);
// var directionalLight2 = new THREE.DirectionalLight(0xffffff);
// directionalLight2.position.set(0, 70, 100).normalize();
// this.scene.add(directionalLight2);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
_this.scene.add(directionalLight);
_this.map = mapd;
}
var lineGroup;
var mbpt = mapboxgl.MercatorCoordinate.fromLngLat(
__mapcenter__,
0
);
var threescale= mbpt.meterInMercatorCoordinateUnits();
var customLayer = {
id: '3d-model',
type: 'custom',
renderingMode: '3d',
onAdd: function (mapd, gl) {
initThree(this, mapd);
addTB(mapd, gl);
//绘制光源
addLight(this.scene);
//绘制飞线
// drawLines(this.scene);
//绘制建筑物
// drawBuildings(this.scene);
this.renderer = new THREE.WebGLRenderer({
canvas: mapd.getCanvas(),
antialias: true,
alpha:true,
context: gl,
antialias: true
});
this.renderer.autoClear = false;
},
render: function (gl, matrix) {
// updateLight();
tb.update();
// updateLines();
this.camera.projectionMatrix =new THREE.Matrix4().fromArray(matrix);// m.multiply(l);
this.renderer.state.reset();
this.renderer.render(this.scene, this.camera);
this.map.triggerRepaint();
}
};
map.on('style.load', function () {
addMapboxExtrudeLayer();
map.addLayer(customLayer);
});
// used to determine the switch point for the light animation
var invert = 1;
var phase = 0;
var pointColor, pointLight, sphereLight, sphereLightMaterial, sphereLightMesh
function addLight(scene) {
scene.add( new THREE.AmbientLight( 0xffffff ) );
var sunlight = new THREE.DirectionalLight(0xffffff, 0.25);
sunlight.position.set(0,80000000,100000000);
sunlight.matrixWorldNeedsUpdate = true;
scene.add(sunlight);
pointColor = "#ccffcc";
pointLight = new THREE.PointLight(pointColor);
pointLight.distance = 0.1;
scene.add(pointLight);
var pt = mapboxgl.MercatorCoordinate.fromLngLat(
__mapcenter__,
600
);
var met = pt.meterInMercatorCoordinateUnits();
// add a small sphere simulating the pointlight
sphereLight = new THREE.SphereBufferGeometry(30,120,120);
sphereLightMaterial = new THREE.MeshStandardMaterial({ color: 0xac6c25 });
sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
// sphereLightMesh.castShadow = true;
sphereLightMesh.position.set(pt.x, pt.y, pt.z);
sphereLightMesh.scale.set(threescale,threescale,threescale);
console.log(sphereLightMesh)
scene.add(sphereLightMesh);
}
/**
* @desc 经纬度转换成墨卡托投影
* @param {array} 传入经纬度
* @return array [x,y,z]
*/
function lnglatToMector(lnglat) {
var pt = mapboxgl.MercatorCoordinate.fromLngLat(
lnglat,
0
);
const { x, y, z } = pt;
return [x, y, z];
}
function mercatorConvert(fts) {
fts.forEach(d => {
d.vector3 = [];
d.geometry.coordinates.forEach((coordinates, i) => {
d.vector3[i] = [];
coordinates.forEach((c, j) => {
if (c[0] instanceof Array) {
d.vector3[i][j] = [];
c.forEach(cinner => {
let cp = lnglatToMector0(cinner);
d.vector3[i][j].push(cp);
});
} else {
let cp = lnglatToMector0(c);
d.vector3[i].push(cp);
}
});
});
});
}
/**
* @desc 绘制地图模型 points 是一个二维数组 [[x,y], [x,y], [x,y]]
*/
function drawModel(points) {
// console.log(points)
const shape = new THREE.Shape();
points.forEach((d, i) => {
const [x, y] = d;
if (i === 0) {
shape.moveTo(x, y);
} else if (i === points.length - 1) {
shape.quadraticCurveTo(x, y, x, y);
} else {
shape.lineTo(x, y, x, y);
}
});
var extrudeSettings = {
depth: -0.01,
bevelEnabled: false,
};
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
// var material = new THREE.MeshPhongMaterial( { color: 0x156289, emissive: 0x072534, } );
const material = new THREE.MeshBasicMaterial({
color: '#006de0',
// transparent: true,
opacity: 0.8,
side: THREE.DoubleSide
});
var mesh = new THREE.Mesh(geometry, material);
return mesh;
}
var projection;
function lnglatToMector0(lnglat) {
if (!projection) {
projection = d3
.geoMercator()
.center([116.582, 35.415])
.scale(800)
// .rotate(Math.PI / 4)
.translate([0.75, 0.7]);
}
const [y, x] = projection([...lnglat]);
let z = 0;
return [x, y, z];
}
var shines = [];
// var colors = ['#FFCCCC', '#FFFF99', '#CCCCFF'];
var colors = ['#FF6666', '#FFFF00', '#0066CC'];
function addMapboxExtrudeLayer() {
map.addSource("buildings", {
// type: "geojson",
// data: buildingjson,
type: "vector",
"url": "mapbox://houxieyu.as833g2t",
});
map.addLayer({
'id': '3dbuildings',
// 'source': 'buildings',
'source': 'buildings',
'source-layer': 'jiningbuildings-7kbdau',
'type': 'fill-extrusion',
'minzoom': 0,
'paint': {
'fill-extrusion-height': ["get", "height"],// ["*", 3, ["to-number",["get", "hegiht"]]],
'fill-extrusion-color':
// ["get", "ftcolor"]
// ["case", ["to-boolean", ["feature-state", "cc"]], ["feature-state", "cc"], colors[2]]
["case", ["to-boolean", ["feature-state", "cc"]], ["case", ["feature-state", "shine"], ["feature-state", "cc"], colors[2]], colors[2]]
}
});
initShine();
var ystimer = setInterval(function () {
//闪烁版
shines.forEach(function (id) {
var state = map.getFeatureState({
id: id,
source: 'buildings',
'sourceLayer': 'jiningbuildings-7kbdau'
});
state.delay += 1;
if (state.shine) {
if (state.delay > 4) {
state.delay = 0;
state.shine = false;
// state.cc = colors[2];
}
}
else {
if (state.delay > 2) {
state.delay = 0;
state.shine = true;
// state.cc = colors[Math.floor(Math.random() * 2)];
}
}
map.setFeatureState({
id: id,
source: 'buildings',
'sourceLayer': 'jiningbuildings-7kbdau'
}, state);
})
}, 200);
}
var curfts = [];
map.on('data', '3dbuildings', function () {
// curfts = map.queryRenderedFeatures('buildings');
});
function initShine() {
shines = [];
var maxid = 10000;
for (let i = 0, l = maxid / 20; i < l; i++) {
let inx = Math.floor(Math.random() * maxid);
shines.push(inx);
map.setFeatureState({
id: inx,
source: 'buildings',
'sourceLayer': 'jiningbuildings-7kbdau'
}, {
cc: colors[Math.floor(Math.random() * 2)],
delay: Math.floor(Math.random() * 4),
shine: true
});
}
}
</script>
</body>
</html>
文件
身体,
html,
#地图{
填充:0;
保证金:0;
宽度:100%;
身高:100%;
}
var uuu地图中心uuuuu=[116.582,35.415];
mapboxgl.accessToken='pk.eyj1ijoiag91egllexuillcjhijoi2pldj5amu3ndzedm5bzd5bm9ncdgycyj9.j1F-Lgid3L5k2Abm8_xTeQ';
var mapboxgl_style='1〕mapbox://styles/mapbox/dark-v10';
变种结核;
函数addTB(mapd,gl){
tb=新三盒(
mapd,
德国劳埃德船级社,
{defaultLights:true}
);
var sphere=tb.sphere({radius:1,颜色:'red',材质:'mesh标准材质'})
.setCoords(uu地图中心uuu.concat([500]));
//将球体添加到场景中
tb.add(球体);
}
常量线型=0//0=正常1=脂肪
//var map=myChart.getModel().getComponent('mapbox3D').getMapbox();
var map=new mapboxgl.map({
容器:“映射”,
样式:mapboxgl_样式,
缩放:16,
中心:地图中心,
投球:20分,
antialias:true//使用MSAA抗锯齿创建gl上下文,以便自定义图层抗锯齿
});
$.ajaxSettings.async=false;
var linesdata;
$.getJSON('jp4data.json',
功能(res){
linesdata=res;
});
//根据CustomLayerInterface为三维模型配置自定义图层
函数initthis(_this,mapd){
_this.camera=新的三个.camera();
_this.scene=新的三个.scene();
//创建两个three.js灯光以照亮模型
//var方向灯=新的三个方向灯(0xffffff);
//directionalLight.position.set(0,-70100).normalize();
//this.scene.add(方向光);
//var directionalLight2=新的三个方向灯(0xffffff);
//directionalLight2.position.set(0,70,100).normalize();
//this.scene.add(directionalLight2);
恒方向光=新的三个方向光(0xffffff,0.5);
_this.scene.add(方向光);
_this.map=mapd;
}
var线组;
var mbpt=mapboxgl.MercatorCoordinate.fromLngLat(
__地图中心,
0
);
var threescale=mbpt.meterInMercatorCoordinateUnits();
var customLayer={
id:“三维模型”,
键入:“自定义”,
渲染模式:“3d”,
onAdd:函数(mapd、gl){
初始三(本,mapd);
addTB(mapd、gl);
//绘制光源
addLight(这个场景);
//绘制飞线
//抽绳(这个场景);
//绘制建筑物
//绘画建筑(本场景);
this.renderer=new THREE.WebGLRenderer({
画布:mapd.getCanvas(),
反别名:是的,
阿尔法:是的,
背景:德国劳埃德船级社,
反别名:对
});
this.renderer.autoClear=false;
},
渲染:函数(总账、矩阵){
//updateLight();
tb.update();
//updateLines();
this.camera.projectionMatrix=new THREE.Matrix4().fromArray(matrix);//m.multiply(l);
this.renderer.state.reset();
this.renderer.render(this.scene,this.camera);
this.map.triggerRepaint();
}
};
map.on('style.load',函数(){
addMapboxExtrudeLayer();
map.addLayer(customLayer);
});
//用于确定灯光动画的切换点
var倒置=1;
var相位=0;
变量pointColor、pointLight、sphereLight、sphereLightMaterial、sphereLightMesh
功能添加灯光(场景){
添加(新的3.AmbientLight(0xffffff));
var阳光=新的三方向光(0xffffff,0.25);
阳光.位置.集(08000000100000000);
sunlight.matrixWorldNeedsUpdate=true;
场景。添加(阳光);
pointColor=“#ccffcc”;
点光源=新的三个点光源(点光源颜色);
点光源距离=0.1;
场景。添加(点光源);
var pt=mapboxgl.MercatorCoordinate.fromLngLat(
__地图中心,
600
);
var met=pt.meterInMercatorCoordinateUnits();
//添加一个模拟点光源的小球体
sphereLight=新的三个。SphereBufferGeometry(30120120);
sphereLightMaterial=new THREE.MeshStandardMaterial({color:0xac6c25});
sphereLightMesh=新的三个网格(sphereLight、sphereLightMaterial);
//sphereLightMesh.castShadow=true;
sphereLightMesh.position.set(点x、点y、点z);
sphereLightMesh.scale.set(三标度,三标度,三标度);
console.log(sphereLightMesh)
场景.添加(sphereLightMesh);
}
/**
*@desc经纬度转换成墨卡托投影
*@param{array}传入经纬度
*@return数组[x,y,z]
*/
功能LNGLATTOMETOR(lnglat){
var pt=mapboxgl.MercatorCoordinate.fromLngLat(
英格拉特,
0
);
常数{x,y,z}=pt;
返回[x,y,z];
}
墨卡托转换函数(fts){
fts.forEach(d=>{
d、 向量3=[];
d、 geometry.coordinates.forEach((坐标,i)=>{
d、 向量3[i]=[];
坐标.forEach((c,j)=>{
if(数组的c[0]实例){
d、 向量3[i][j]=[];
c、 forEach(cinner=>{
设cp=lnglatToMector0(cinner);
d、 向量3[i][j].推(cp);
});
}否则{
设cp=lnglatToMector0(c);
d、 向量3[i].推(cp);
}
});
});
});
}
/**
*@desc绘制地图模型 要点是一个二维数组 [x,y],[x,y],