首页 > 解决方案 > Three.js / 反应三纤维 | 如何在 BufferGeometry(costum SphereGeometry)上均匀分布 PointsMaterial 并将顶点与图像数据进行比较

问题描述

我尝试通过他们提供的示例(https://github.blog/2020- 12-21-我们如何建造-github-globe/ )。我的目标是实现这一点,唯一不同的是,使用three.js pointsMaterial 并隐藏那些与地球图像上的水具有相同坐标的材料。抱歉英语不好或拼写错误(英语不是我的母语),这也是我的第一个 stackoverflow 问题。所以如果有什么不清楚或我不够具体,请告诉我,我会尽力纠正它。提前感谢您的帮助!

我的问题是:

我在上面的 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;

标签: three.js3dnext.jswebglreact-three-fiber

解决方案


推荐阅读