You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js如何获取射线与物体交点纹理颜色 系留环项目实践需求

以下是获取射线与地球纹理交点颜色的完整示例代码:

// 提前全局声明需要用到的变量
let earthTextureImage, offscreenCanvas, offscreenCtx, textureWidth, textureHeight;
const raycaster = new THREE.Raycaster();

// ========== 初始化部分:只需要执行一次 ==========
// 加载地球纹理,纹理加载完成后缓存到离屏canvas方便后续读取像素
const textureLoader = new THREE.TextureLoader();
const earthTexture = textureLoader.load('你的地球表面纹理路径.jpg', (loadedTexture) => {
  earthTextureImage = loadedTexture.image;
  textureWidth = earthTextureImage.width;
  textureHeight = earthTextureImage.height;
  // 初始化离屏画布
  offscreenCanvas = document.createElement('canvas');
  offscreenCanvas.width = textureWidth;
  offscreenCanvas.height = textureHeight;
  offscreenCtx = offscreenCanvas.getContext('2d');
  offscreenCtx.drawImage(earthTextureImage, 0, 0, textureWidth, textureHeight);
});
// 初始化地球Mesh,注意SphereGeometry默认自带uv属性,不需要额外配置
const earthGeometry = new THREE.SphereGeometry(6371, 64, 64); // 半径、分段数按你实际场景调整
const earthMaterial = new THREE.MeshStandardMaterial({ map: earthTexture });
const earthMesh = new THREE.Mesh(earthGeometry, earthMaterial);
scene.add(earthMesh);

// ========== 复用方法:每次需要检测交点颜色时调用 ==========
// 参数说明:rayOrigin 射线起点(系留环上的缆线锚点坐标),rayDirection 射线方向(建议指向地心)
function getIntersectionColor(rayOrigin, rayDirection) {
  // 若纹理还未加载完成,直接返回空
  if (!offscreenCtx) return null;
  // 设置射线参数
  raycaster.set(rayOrigin, rayDirection);
  // 仅检测地球Mesh,返回所有交点
  const intersects = raycaster.intersectObject(earthMesh);
  if (intersects.length === 0) return null;
  // 取第一个正面交点的uv坐标
  const hitUv = intersects[0].uv;
  // 转换uv坐标为纹理像素坐标,需翻转Y轴适配Three.js默认的纹理flipY规则
  const pixelX = Math.floor(hitUv.x * textureWidth);
  const pixelY = Math.floor((1 - hitUv.y) * textureHeight);
  // 读取对应像素的RGBA值
  const pixel = offscreenCtx.getImageData(pixelX, pixelY, 1, 1).data;
  // 返回归一化的Three.js颜色对象,方便后续和蓝色做阈值比对
  return new THREE.Color(pixel[0]/255, pixel[1]/255, pixel[2]/255);
}

// ========== 调用示例 ==========
// 假设系留环上的锚点坐标为(12000, 0, 0),地心为场景原点(0,0,0)
const tetherAnchor = new THREE.Vector3(12000, 0, 0);
const directionToCore = new THREE.Vector3().subVectors(new THREE.Vector3(0,0,0), tetherAnchor).normalize();
const hitColor = getIntersectionColor(tetherAnchor, directionToCore);
if (hitColor) {
  // 此处可直接执行第二步:将hitColor与海洋蓝色做阈值比对
  console.log('交点处纹理颜色:', hitColor);
}

注意事项

  • 请确保你用来采样颜色的纹理和实际渲染地球的纹理为同一张,避免陆地海洋位置匹配错误
  • 如果需要批量检测大量缆线锚点的交点颜色,建议一次性读取整个纹理的像素数据缓存到数组中,避免频繁调用getImageData产生性能损耗
  • 如果你的场景中地球存在自转逻辑,需要同步将自转角度换算为纹理uv的水平偏移,采样时对应调整pixelX的取值,避免位置错位

内容的提问来源于stack exchange,提问作者phil1008

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:15:03