Three.js垂直于球体

时间:2014-10-19 23:08:46

标签: javascript html5 three.js

我的目标是创建一个具有与表面垂直的线条的交互式地球,以便您可以点击它们,并提取我的医疗团队从世界各地拍摄的照片。我对世界进行了完全编码(或者更准确地说是其他人做了这件事,我做了一些小改动)。

以下是符合预期功能的地球代码。我想知道的是如何使线条垂直于曲面并使它们可以被点击。如果线条在地球背面旋转或者用户旋转地球并且用户看不到褪色的边线上的线条消失和消失,那将是最佳的。

我想过制作一系列城市,并在球体上有一个位置与它相关联,但我不确定如何做到这一点。我是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 个答案:

答案 0 :(得分:1)

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

  1. 使用GIMP将图片添加到this template并保存为PNG。
  2. 这些图像在Js应用程序中作为纹理加载。
  3. 使用加载的纹理创建精灵。
  4. 精灵被添加到Object3D并且其位置设置为(0,0,radiusOfTheEarthSphere)
  5. 将Object3D添加到球体中,并旋转直到精灵的中心位于您希望它所在的地球位置。
  6. 每个帧,从地球中心到摄像机的矢量和从地球中心到每个精灵的矢量之间的点积用于计算精灵的不透明度。
  7. 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会在控制台中出现一些错误,直到加载所有纹理,因为我快速编写它只是为了向您展示我的实现想法。