three.js - Three.js / 反应三纤维 | 如何在 BufferGeometry(costum SphereGeometry)上均匀分布 PointsMaterial 并将顶点与图像数据进行比较
问题描述
我尝试通过他们提供的示例(https://github.blog/2020- 12-21-我们如何建造-github-globe/ )。我的目标是实现这一点,唯一不同的是,使用three.js pointsMaterial 并隐藏那些与地球图像上的水具有相同坐标的材料。抱歉英语不好或拼写错误(英语不是我的母语),这也是我的第一个 stackoverflow 问题。所以如果有什么不清楚或我不够具体,请告诉我,我会尽力纠正它。提前感谢您的帮助!
我的问题是:
- 你如何沿着不同的纬度分布这三个.js点,在这种情况下,从南到北极。
- 例如,您将如何将图像颜色 / alpha 值与 pointsMaterial 进行比较,并决定它是否应该可见(陆地)或不可见(水)
我在上面的 Github 解释中使用了我在查看天数中找到的代码,但不知道如何翻译它,所以我可以使用它:
for (let lat = -90; lat <= 90; lat += 180/rows) {
const radius = Math.cos(Math.abs(lat) * DEG2RAD) * GLOBE_RADIUS; // espacially this part what would DEG2RAD and GLOBE_RADIUS mean?
const circumference = radius * Math.PI * 2;
const dotsForLat = circumference * dotDensity;
for (let x = 0; x < dotsForLat; x++) {
const long = -180 + x*360/dotsForLat;
if (!this.visibilityForCoordinate(long, lat)) continue;
// Setup and save circle matrix data
}
}
目前,我设法从我们星球的图像中获取一些数据,方法是创建一个未渲染的画布,为其创建上下文,在其中绘制图像并使用 .getImageData() 从中获取值。我能够通过对 BufferGeometry 的顶点位置使用 for 循环来创建光环,但我想您会在下面提供的图像/代码中看到它。
import { useEffect } from "react";
import * as THREE from "three";
// Had some troubles with setting up loaders in next.js, so I used Three / react-three-fiber
const Box = () => {
// Loading and append image to get values of it from a not rendered canvas
useEffect(() => {
const textureLoader = new THREE.TextureLoader();
textureLoader.load("/globe/earth.png", (texture) => {
const width = texture.image.width;
const height = texture.image.height;
const img = texture.image;
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
ctx.scale(1, -1);
ctx.drawImage(img, 0, 0, width, height * -1);
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
console.log(imgData);
});
}, []);
// Creating Geometry / Material
const count = 500;
const vertices = new Float32Array(count * 3);
// Looping to get values for vertices
for (let x = 0; x < count * 3; x++) {
const value = Math.cos(Math.abs(x));
vertices[x] = value;
}
const material = new THREE.PointsMaterial({ color: "white", size: 0.005 });
const geometry = new THREE.BufferGeometry();
geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
// Returning to render on canvas in index file
return <points material={material} geometry={geometry}></points>;
};
export default Box;
解决方案
推荐阅读
- c - 制作可用于不同大小结构的通用链表实现
- android - Android JobScheduler setRequiresDeviceIdle 作业未触发
- lua - 电晕中的随机生成位置
- ruby-on-rails - 为什么我的参数为零?
- netty - 估计 Netty 客户端的吞吐量
- c# - 自引用实体框架错误
- rxjs - 未捕获的 TypeError:NativePromise.resolve 不是函数
- node.js - Node Red UI - 如何获取登录的用户名?
- asp.net - 如何更改 Razor Pages 中的表单控件 ID 和名称
- angular - 寻找一种将全文搜索添加到 Firestore 的廉价方法