提交 d28ccc7e authored 作者: 詹银鑫's avatar 詹银鑫

添加水面纹理,及准格尔旗水系

上级 e675859a
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -52,6 +52,17 @@ export class Assets { ...@@ -52,6 +52,17 @@ export class Assets {
// path: base_url + "assets/json/zger.json", // path: base_url + "assets/json/zger.json",
path: base_url + "assets/json/jiedao.json", path: base_url + "assets/json/jiedao.json",
}, },
{
type: "File",
name: "surfaceWater",
path: base_url + "assets/json/surfacewater.json",
// path: base_url + "assets/json/linewater.json",
},
{
type: "File",
name: "linewater",
path: base_url + "assets/json/linewater.json",
},
{ {
type: "File", type: "File",
name: "mapStroke", name: "mapStroke",
......
...@@ -422,6 +422,8 @@ export class World extends Mini3d { ...@@ -422,6 +422,8 @@ export class World extends Mini3d {
this.focusMapGroup = focusMapGroup this.focusMapGroup = focusMapGroup
let { china, chinaTopLine } = this.createChina() let { china, chinaTopLine } = this.createChina()
let { map, mapTop, mapLine } = this.createProvince() let { map, mapTop, mapLine } = this.createProvince()
let { waterGroup } = this.createWater()
let { lineWaterGroup } = this.createLineWater()
china.setParent(mapGroup) china.setParent(mapGroup)
chinaTopLine.setParent(mapGroup) chinaTopLine.setParent(mapGroup)
// 创建扩散 // 创建扩散
...@@ -429,6 +431,8 @@ export class World extends Mini3d { ...@@ -429,6 +431,8 @@ export class World extends Mini3d {
map.setParent(focusMapGroup) map.setParent(focusMapGroup)
mapTop.setParent(focusMapGroup) mapTop.setParent(focusMapGroup)
mapLine.setParent(focusMapGroup) mapLine.setParent(focusMapGroup)
focusMapGroup.add(waterGroup)
focusMapGroup.add(lineWaterGroup)
focusMapGroup.position.set(0, 0, -0.01) focusMapGroup.position.set(0, 0, -0.01)
focusMapGroup.scale.set(1, 1, 0) focusMapGroup.scale.set(1, 1, 0)
focusMapGroup.name = "focusMapGroup" focusMapGroup.name = "focusMapGroup"
...@@ -1358,7 +1362,7 @@ export class World extends Mini3d { ...@@ -1358,7 +1362,7 @@ export class World extends Mini3d {
// 创建geoJson // 创建geoJson
createGeoJson() { createGeoJson() {
this.FileLoader = new FileLoader() this.FileLoader = new FileLoader()
this.FileLoader.load("../../../public/assets/json/road.geojson", (data) => { this.FileLoader.load("../../../public/assets/json/surfacewater.json", (data) => {
let jsonData = JSON.parse(data) let jsonData = JSON.parse(data)
console.log("jsonData", jsonData); console.log("jsonData", jsonData);
const roadGeoJson = new Group(); const roadGeoJson = new Group();
...@@ -1416,41 +1420,6 @@ export class World extends Mini3d { ...@@ -1416,41 +1420,6 @@ export class World extends Mini3d {
} }
// createTagLine() {
// // 创建材质
// const material = new LineBasicMaterial({ color: 0xff0000 });
// // 创建空几何体
// const geometry = new THREE.BufferGeometry()
// const points = [];
// points.push(new THREE.Vector3(20, 20, 0));
// points.push(new THREE.Vector3(20, -20, 0));
// points.push(new THREE.Vector3(-20, -20, 0));
// points.push(new THREE.Vector3(-20, 20, 0));
// // 绑定顶点到空几何体
// geometry.setFromPoints(points);
// const line = new THREE.Line(geometry, material);
// this.scene.add(line);
// // const length = 0.018; // 假设每条线的长度为0.018
// // const distance = length * 2; // 移动的距离
// // const maxDistance = distance * 2.5; // 移动的距离
// // const color = 0x2a6f72; // 线的颜色
// // const { group: tagLineGroup, tween: tagLineTween } = tagLine(color, distance, maxDistance, length, 4, true)
// // 直接加到场景或你需要的父级
// // this.scene.add(tagLineGroup);
// // 启动动画
// // tagLineTween.start();
// // tagLineTweenGroup.add(tagLineTween)
// // this.scene.add(tagGroup)
// // tagLineTweenGroup.getAll().forEach((tween) => {
// // tween.start()
// // })
// // this.scene.add(tagLineTweenGroup)
// }
// createSmoothLine(lngLatArr) { // createSmoothLine(lngLatArr) {
// const z = this.depth + 0.5; // const z = this.depth + 0.5;
// const points = lngLatArr.map(([lng, lat]) => { // const points = lngLatArr.map(([lng, lat]) => {
...@@ -1590,6 +1559,392 @@ createSmoothLine(lngLatArr) { ...@@ -1590,6 +1559,392 @@ createSmoothLine(lngLatArr) {
}); });
return mesh; return mesh;
} }
// 创建水面
createWater() {
// 获取水面GeoJSON数据
let mapJsonData = this.assets.instance.getResource("surfaceWater");
let waterJson;
try {
waterJson = typeof mapJsonData === "string" ? JSON.parse(mapJsonData) : mapJsonData;
} catch (e) {
console.error("surfaceWater 解析失败", e);
return { waterGroup: null };
}
// 创建水面组
const waterGroup = new Group();
const projection = geoMercator().center(this.geoProjectionCenter).scale(this.geoProjectionScale).translate([0, 0]);
// 加载法线贴图
const textureLoader = new THREE.TextureLoader();
let base_url = import.meta.env.BASE_URL || "/";
const normalMap = textureLoader.load(base_url + "assets/json/waternormals.jpg");
normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
// 可选:加载一张水面颜色贴图
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
// waterMap.wrapS = waterMap.wrapT = THREE.RepeatWrapping;
// 动画流动
this.time.on("tick", () => {
normalMap.offset.x += 0.002; // 控制流动速度和方向
normalMap.offset.y += 0.001;
// 如果有颜色贴图,也可以流动
// waterMap.offset.x += 0.001;
});
(waterJson.features || []).forEach((feature) => {
const geometry = feature.geometry;
if (!geometry) return;
if (geometry.type === "Polygon" || geometry.type === "MultiPolygon") {
const polygons = geometry.type === "Polygon" ? [geometry.coordinates] : geometry.coordinates;
polygons.forEach((polygon) => {
polygon.forEach((ring) => {
const shape = new Shape();
ring.forEach(([lng, lat], idx) => {
const [x, y] = projection([lng, lat]);
if (idx === 0) {
shape.moveTo(x, -y);
} else {
shape.lineTo(x, -y);
}
});
const shapeGeometry = new THREE.ShapeGeometry(shape);
const material = new THREE.MeshStandardMaterial({
color: 0x153e7e,
transparent: true,
opacity: 0.5,
side: DoubleSide,
depthWrite: false,
normalMap: normalMap,
normalScale: new THREE.Vector2(1, 1), // 可调节凹凸强度
// map: waterMap, // 如果有颜色贴图可加上
metalness: 0.3,
roughness: 0.7,
});
const mesh = new Mesh(shapeGeometry, material);
mesh.position.set(0, 0, this.depth + 0.25);
mesh.renderOrder = 10;
waterGroup.add(mesh);
});
});
}
});
return {
waterGroup,
};
}
createLineWater() {
// 获取水的GeoJSON线数据
let mapJsonData = this.assets.instance.getResource("linewater");
let lineWaterJson;
try {
lineWaterJson = typeof mapJsonData === "string" ? JSON.parse(mapJsonData) : mapJsonData;
} catch (e) {
console.error("linewater 解析失败", e);
return { lineWaterGroup: null };
}
// 加载法线贴图
const textureLoader = new THREE.TextureLoader();
let base_url = import.meta.env.BASE_URL || "/";
const normalMap = textureLoader.load(base_url + "assets/json/waternormals.jpg");
normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
// 可选:加载一张水面颜色贴图
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
// waterMap.wrapS = waterMap.wrapT = THREE.RepeatWrapping;
// 动画流动
this.time.on("tick", () => {
normalMap.offset.x += 0.002; // 控制流动速度和方向
normalMap.offset.y += 0.001;
// 如果有颜色贴图,也可以流动
// waterMap.offset.x += 0.001;
});
// 创建线水组
const lineWaterGroup = new Group();
const projection = geoMercator().center(this.geoProjectionCenter).scale(this.geoProjectionScale).translate([0, 0]);
(lineWaterJson.features || []).forEach((feature) => {
const geometry = feature.geometry;
if (!geometry) return;
let lines = [];
if (geometry.type === "LineString") {
lines = [geometry.coordinates];
} else if (geometry.type === "MultiLineString") {
lines = geometry.coordinates;
}
lines.forEach((line) => {
const points = line.map(([lng, lat]) => {
const [x, y] = projection([lng, lat]);
return new THREE.Vector3(x, -y, this.depth + 0.26); // 保证高于地表
});
const geometryLine = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({
color: 0x3bb9ff,
linewidth: 2,
transparent: true,
opacity: 0.8,
depthWrite: false,
});
const lineObj = new THREE.Line(geometryLine, material);
lineObj.renderOrder = 11;
lineWaterGroup.add(lineObj);
});
// lines.forEach((line) => {
// const points = line.map(([lng, lat]) => {
// const [x, y] = projection([lng, lat]);
// return new THREE.Vector3(x, -y, this.depth + 0.26);
// });
// if (points.length < 2) return;
// const curve = new THREE.CatmullRomCurve3(points);
// const tubeGeometry = new THREE.TubeGeometry(curve, 64, 0.05, 8); // 0.05为线粗
// // const material = new THREE.MeshBasicMaterial({
// // color: 0x3bb9ff,
// // transparent: true,
// // opacity: 0.8,
// // depthWrite: false,
// // });
// const material = new THREE.MeshStandardMaterial({
// color: 0x153e7e,
// transparent: true,
// opacity: 0.5,
// side: DoubleSide,
// depthWrite: false,
// normalMap: normalMap,
// normalScale: new THREE.Vector2(1, 1), // 可调节凹凸强度
// // map: waterMap, // 如果有颜色贴图可加上
// metalness: 0.3,
// roughness: 0.7,
// });
// const mesh = new THREE.Mesh(tubeGeometry, material);
// mesh.renderOrder = 11;
// lineWaterGroup.add(mesh);
// });
});
return {
lineWaterGroup,
};
}
// createLineWater() {
// // 获取水的GeoJSON线数据
// let mapJsonData = this.assets.instance.getResource("linewater");
// let lineWaterJson;
// try {
// lineWaterJson = typeof mapJsonData === "string" ? JSON.parse(mapJsonData) : mapJsonData;
// } catch (e) {
// console.error("linewater 解析失败", e);
// return { lineWaterGroup: null };
// }
// // 加载法线贴图
// const textureLoader = new THREE.TextureLoader();
// let base_url = import.meta.env.BASE_URL || "/";
// const normalMap = textureLoader.load(base_url + "assets/json/waternormals.jpg");
// normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png"); // 你需要准备一张水波纹PNG
// waterMap.wrapS = waterMap.wrapT = THREE.RepeatWrapping;
// // 动画流动
// this.time.on("tick", () => {
// normalMap.offset.x += 0.002;
// normalMap.offset.y += 0.001;
// waterMap.offset.x += 0.002; // 让颜色贴图也流动
// });
// // 创建线水组
// const lineWaterGroup = new Group();
// const projection = geoMercator().center(this.geoProjectionCenter).scale(this.geoProjectionScale).translate([0, 0]);
// (lineWaterJson.features || []).forEach((feature) => {
// const geometry = feature.geometry;
// if (!geometry) return;
// let lines = [];
// if (geometry.type === "LineString") {
// lines = [geometry.coordinates];
// } else if (geometry.type === "MultiLineString") {
// lines = geometry.coordinates;
// }
// lines.forEach((line) => {
// // 生成带宽度的水带
// const points = line.map(([lng, lat]) => {
// const [x, y] = projection([lng, lat]);
// return new THREE.Vector3(x, -y, this.depth + 0.26); // 保证高于地表
// });
// if (points.length < 2) return;
// // 用TubeGeometry生成带宽度的水带
// const curve = new THREE.CatmullRomCurve3(points);
// const tubeGeometry = new THREE.TubeGeometry(curve, Math.max(32, points.length * 2), 0.01, 16);
// const material = new THREE.MeshStandardMaterial({
// color: 0x4fc3ff,
// transparent: true,
// opacity: 0.35,
// side: DoubleSide,
// depthWrite: false,
// normalMap: normalMap,
// normalScale: new THREE.Vector2(2, 2),
// map: waterMap, // 使用颜色贴图
// metalness: 0.3,
// roughness: 0.7,
// });
// const mesh = new Mesh(tubeGeometry, material);
// mesh.renderOrder = 11;
// lineWaterGroup.add(mesh);
// });
// });
// return {
// lineWaterGroup,
// };
// }
// createLineWater() {
// let mapJsonData = this.assets.instance.getResource("linewater");
// let lineWaterJson;
// try {
// lineWaterJson = typeof mapJsonData === "string" ? JSON.parse(mapJsonData) : mapJsonData;
// } catch (e) {
// console.error("linewater 解析失败", e);
// return { lineWaterGroup: null };
// }
// const textureLoader = new THREE.TextureLoader();
// let base_url = import.meta.env.BASE_URL || "/";
// const normalMap = textureLoader.load(base_url + "assets/json/waternormals.jpg");
// normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
// const waterMap = textureLoader.load(base_url + "assets/json/watercolor.png");
// waterMap.wrapS = waterMap.wrapT = THREE.RepeatWrapping;
// // 流动速度更快
// this.time.on("tick", () => {
// normalMap.offset.x += 0.03;
// normalMap.offset.y += 0.015;
// waterMap.offset.x += 0.03;
// waterMap.offset.y += 0.015;
// });
// const lineWaterGroup = new Group();
// const projection = geoMercator().center(this.geoProjectionCenter).scale(this.geoProjectionScale).translate([0, 0]);
// (lineWaterJson.features || []).forEach((feature) => {
// const geometry = feature.geometry;
// if (!geometry) return;
// let lines = [];
// if (geometry.type === "LineString") {
// lines = [geometry.coordinates];
// } else if (geometry.type === "MultiLineString") {
// lines = geometry.coordinates;
// }
// lines.forEach((line) => {
// const points = line.map(([lng, lat]) => {
// const [x, y] = projection([lng, lat]);
// return new THREE.Vector3(x, -y, this.depth + 0.26);
// });
// if (points.length < 2) return;
// // 宽度渐变:首尾变窄
// const riverWidthMax = 0.08, riverWidthMin = 0.02;
// const lefts = [], rights = [];
// for (let i = 0; i < points.length; i++) {
// let t = points.length === 1 ? 0 : i / (points.length - 1);
// let width = riverWidthMin + (1 - Math.abs(t * 2 - 1)) * (riverWidthMax - riverWidthMin);
// let dir;
// if (i === 0) {
// dir = points[1].clone().sub(points[0]);
// } else if (i === points.length - 1) {
// dir = points[i].clone().sub(points[i - 1]);
// } else {
// dir = points[i + 1].clone().sub(points[i - 1]);
// }
// dir.z = 0;
// dir.normalize();
// const normal = new THREE.Vector3(-dir.y, dir.x, 0);
// lefts.push(points[i].clone().add(normal.clone().multiplyScalar(width / 2)));
// rights.push(points[i].clone().add(normal.clone().multiplyScalar(-width / 2)));
// }
// // 顶点、uv、透明度
// const vertices = [];
// const uvs = [];
// const alphas = [];
// let totalLen = 0;
// for (let i = 0; i < points.length; i++) {
// if (i > 0) totalLen += points[i].distanceTo(points[i - 1]);
// let t = points.length === 1 ? 0 : i / (points.length - 1);
// let edgeAlpha = 0.7 + 0.3 * (1 - Math.abs(t * 2 - 1));
// // 左点
// vertices.push(lefts[i]);
// uvs.push(totalLen * 2, 0); // UV缩放更密集
// alphas.push(edgeAlpha);
// // 右点
// vertices.push(rights[i]);
// uvs.push(totalLen * 2, 1);
// alphas.push(edgeAlpha);
// }
// const indices = [];
// for (let i = 0; i < points.length - 1; i++) {
// const a = i * 2, b = i * 2 + 1, c = i * 2 + 2, d = i * 2 + 3;
// indices.push(a, b, c, b, d, c);
// }
// const geometry = new THREE.BufferGeometry();
// const posArr = new Float32Array(vertices.length * 3);
// for (let i = 0; i < vertices.length; i++) {
// posArr[i * 3] = vertices[i].x;
// posArr[i * 3 + 1] = vertices[i].y;
// posArr[i * 3 + 2] = vertices[i].z;
// }
// geometry.setAttribute('position', new THREE.BufferAttribute(posArr, 3));
// geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2));
// geometry.setAttribute('alpha', new THREE.BufferAttribute(new Float32Array(alphas), 1));
// geometry.setIndex(indices);
// // ShaderMaterial实现边缘羽化和流动水波
// const material = new THREE.ShaderMaterial({
// uniforms: {
// map: { value: waterMap },
// normalMap: { value: normalMap },
// color: { value: new THREE.Color(0x4fc3ff) },
// opacity: { value: 0.5 },
// },
// vertexShader: `
// attribute float alpha;
// varying vec2 vUv;
// varying float vAlpha;
// void main() {
// vUv = uv;
// vAlpha = alpha;
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
// }
// `,
// fragmentShader: `
// uniform sampler2D map;
// uniform sampler2D normalMap;
// uniform vec3 color;
// uniform float opacity;
// varying vec2 vUv;
// varying float vAlpha;
// void main() {
// vec4 texColor = texture2D(map, vUv);
// float alpha = texColor.a * opacity * vAlpha;
// vec3 finalColor = mix(color, texColor.rgb, 0.8); // 贴图主导
// if(alpha < 0.05) discard;
// gl_FragColor = vec4(finalColor, alpha);
// }
// `,
// transparent: true,
// side: DoubleSide,
// depthWrite: false,
// });
// const mesh = new Mesh(geometry, material);
// mesh.renderOrder = 11;
// lineWaterGroup.add(mesh);
// });
// });
// return {
// lineWaterGroup,
// };
// }
// 跳转到指定group // 跳转到指定group
zoomToFocusMapGroup(group) { zoomToFocusMapGroup(group) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论