【问题标题】:Three.js lines normal to a sphere与球体垂直的三个.js 行
【发布时间】:2014-10-21 02:51:44
【问题描述】:

我的目标是创建一个交互式地球,它的线条与地表垂直,这样您就可以点击它们,它会调出我的医疗团队从世界各地拍摄的照片。我已经对世界进行了完全编码(或者更准确地说,是其他人完成的,我做了一些小改动)。

以下是按预期运行的地球代码。我想知道的是如何使线条垂直于表面并使它们可点击。如果线条在旋转到地球背面时褪色并消失,或者用户旋转地球并且用户看不到一侧的线条褪色,那将是最佳选择。

我想过制作一系列城市并在球体上关联一个位置,但我不太确定该怎么做。一般来说,我对 Three.js 和 HTML/JS 很陌生。

知道我正在使用 three.mins.js、Detector.js 和 TrackballControl.js 可能会有所帮助

代码如下:

(function () {

var webglEl = document.getElementById('webgl');

if (!Detector.webgl) {
    Detector.addGetWebGLMessage(webglEl);
    return;
}

var width  = window.innerWidth,
    height = window.innerHeight;

// Earth params
var radius   = 0.5,
    segments = 32,
    rotation = 6;  

var scene = new THREE.Scene();

var uniforms, mesh, meshes =[];

var camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 1000);
camera.position.z = 1.5;

var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);

scene.add(new THREE.AmbientLight(0x333333));

var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5,3,5);
scene.add(light);

var sphere = createSphere(radius, segments);
sphere.rotation.y = rotation; 
scene.add(sphere)

var clouds = createClouds(radius, segments);
clouds.rotation.y = rotation;
scene.add(clouds)

var stars = createStars(90, 64);
scene.add(stars);

var controls = new THREE.TrackballControls(camera);

webglEl.appendChild(renderer.domElement);

render();

function render() {
    controls.update();
    sphere.rotation.y += 0.0005;
    clouds.rotation.y += 0.0007;        
    requestAnimationFrame(render);
    renderer.render(scene, camera);
}

function createSphere(radius, segments) {
    return new THREE.Mesh(
        new THREE.SphereGeometry(radius, segments, segments),
        new THREE.MeshPhongMaterial({
            map:         THREE.ImageUtils.loadTexture('images/Color_Map.jpg'),
            bumpMap:     THREE.ImageUtils.loadTexture('images/elev_bump_4k.jpg'),
            bumpScale:   0.005,
            specularMap: THREE.ImageUtils.loadTexture('images/water_4k.png'),
            specular:    new THREE.Color('grey')                                
        })
    );
}

function createClouds(radius, segments) {
    return new THREE.Mesh(
        new THREE.SphereGeometry(radius + 0.003, segments, segments),           
        new THREE.MeshPhongMaterial({
            map:         THREE.ImageUtils.loadTexture('images/fair_clouds_4k.png'),
            transparent: true
        })
    );      
}

function createStars(radius, segments) {
    return new THREE.Mesh(
        new THREE.SphereGeometry(radius, segments, segments), 
        new THREE.MeshBasicMaterial({
            map:  THREE.ImageUtils.loadTexture('images/galaxy_starfield.png'), 
            side: THREE.BackSide
        })
    );
}

}());

希望它看起来像这个链接,但带有地球而不是建筑物 (http://3d.cl3ver.com/uWfsD?tryitlocation=3) [去那里时也点击探索]。

【问题讨论】:

  • 把你的任务分成几个,每个本身就是一个微不足道的中学几何: 1. 射线和球体的交点(从屏幕上的鼠标点射出的射线垂直于屏幕表面) 2. 在你知道了相交和你击中的多边形之后 - 获得它的法线也是微不足道的
  • @zerkms,他不想计算法线,你读过他的整个问题吗?
  • @LucasdeAlmeida 我有。 “我想知道的是如何使线条垂直于表面并使其可点击。” --- 请你不要那么讽刺,并指出我错在哪里吗?
  • @zerkms,您是否阅读过“希望它看起来像这个链接但带有地球而不是建筑物 (3d.cl3ver.com/uWfsD?tryitlocation=3) [去那里时也点击探索] 部分。” ?也许他没有尽可能地表达他的问题,但是如果您看到他给我们的链接,就可以理解他想要什么,而不是计算与交叉点垂直的线的问题。

标签: javascript html three.js


【解决方案1】:

我构建了一个快速演示,最忠实地代表了我认为您的需求。它显示了一些似乎通过线条连接到地球球体的图像。它使用精灵来创建这些图像(实际上是线条本身)。我认为它非常类似于您链接到的建筑物的演示。这是技术:

  1. 使用 GIMP 将图像添加到 this template 并保存为 PNG。
  2. 这些图像作为纹理加载到 Js 应用程序中。
  3. 使用加载的纹理创建精灵。
  4. 精灵被添加到 Object3D 并且其位置设置为 (0,0,radiusOfTheEarthSphere)
  5. Object3D 被添加到球体中并旋转,直到精灵的中心位于地球上您希望它停留的位置。
  6. 每一帧,从地球中心到相机的向量和从地球中心到每个精灵的向量之间的点积,用于计算精灵的不透明度。

6 中的等式是:

opacity = ((|cameraPosition - centerOfEarth| x |spriteCenter - centerOfEarth|) + 1) * 0.5

其中“x”是点积,“||”表示归一化。

还要注意,由于使用 Object3D 作为父对象,精灵中心与其位置不同,我使用 .localToWorld(vec) 方法计算其中心。

请在此处查看演示:https://33983769c6a202d6064de7bcf6c5ac7f51fd6d9e.googledrive.com/host/0B9scOMN0JFaXSE93YTZRTE5XeDQ/test.html

它托管在我的 Google 云端硬盘中,可能需要一些时间才能加载。 Three.js 会在控制台中出现一些错误,直到所有纹理都加载完毕,因为我快速编写代码只是为了向您展示我的实现思路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-27
    • 2015-04-26
    • 1970-01-01
    • 2021-11-18
    • 2019-08-09
    • 2015-07-18
    相关资源
    最近更新 更多