如何使用three.js中的高度图在地形顶部绘制随机网格?

时间:2017-03-17 03:35:23

标签: javascript three.js

因此,标题声明我想知道如何在y位置绘制随机生成的网格,该网格与three.js中地形相应的y位置相匹配。我查看了文档并觉得使用raycaster可能会有效,但我只能看到将检测用作鼠标事件的示例,而不是渲染之前,所以我不确定如何实现它。

这是我到目前为止的地形,高度图和网格绘图的代码。这一切都在技术上有效,但正如你可以看到的情节,因为你现在看到y位置只是坐在零位。任何见解都会非常感激,我对three.js很新。

地形:

    function plotAsset(texturefile, amount, size, array) {
    console.log(array);
    var loader = new THREE.TextureLoader();
    loader.load(
        "assets/textures/objects/" + texturefile,
        function(texturefile) {
            var geometry = new THREE.PlaneGeometry(size, size, 10, 1);
            var material = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                map: texturefile,
                side: THREE.DoubleSide,
                transparent: true,
                depthWrite: false,
                depthTest: false,
                alphaTest: 0.5,
            });

            var uniforms = { texture:  { value: texturefile } };
            var vertexShader = document.getElementById( 'vertexShaderDepth' ).textContent;
            var fragmentShader = document.getElementById( 'fragmentShaderDepth' ).textContent;

            // add bunch o' stuff
            for (var i = 0; i < amount; i++) {
                var scale = Math.random() * (1 - 0.8 + 1) + 0.8;
                var object = new THREE.Mesh(geometry, material);
                var x = Math.random() * 400 - 400 / 2;
                var z = Math.random() * 400 - 400 / 2;
                object.rotation.y = 180 * Math.PI / 180;
                //object.position.y = size * scale / 2;
                object.position.x = x;
                object.position.z = z;
                object.position.y = 0;
                object.castShadow = true;

                object.scale.x = scale; // random scale
                object.scale.y = scale;
                object.scale.z = scale;

                scene.add(object);

                object.customDepthMaterial = new THREE.ShaderMaterial( {
                uniforms: uniforms,
                vertexShader: vertexShader,
                fragmentShader: fragmentShader,
                side: THREE.DoubleSide
                } );
            }
        }
    );
}

绘制资产:

    function getHeightData(img) {
    var canvas = document.createElement('canvas');
    canvas.width = 2048 / 8;
    canvas.height = 2048 / 8;
    var context = canvas.getContext('2d');

    var size = 2048 / 8 * 2048 / 8,
        data = new Float32Array(size);

    context.drawImage(img, 0, 0);

    for (var i = 0; i < size; i++) {
        data[i] = 0
    }

    var imgd = context.getImageData(0, 0, 2048 / 8, 2048 / 8);
    var pix = imgd.data;

    var j = 0;
    for (var i = 0, n = pix.length; i < n; i += (4)) {
        var all = pix[i] + pix[i + 1] + pix[i + 2];
        data[j++] = all / 40;
    }

    return data;
}

高度数据:

 var site_url = '<?=base_url()?>';
 var id = $(this).find("option:selected").attr('value');
     $.ajax({
                type : 'POST',
                dataType : 'json',
                url: '<?=base_url()?>'+'index.php/talika_12/get_data_by_id_ajax',
                data: {user_id:id},
                success: function(data) {
                   alert(data);
                   $('#inst_name').text(data.talika_12_user_name);
                   $('#inst_account_no').text(data.talika_12_user_account_no);
            }
       });

1 个答案:

答案 0 :(得分:1)

是的,使用THREE.Raycaster()效果很好。 raycaster采用.set(origin, direction)方法。这里你唯一需要做的就是将原点设置为高于高度图的最高点。

var n = new THREE.Mesh(...); // the object we want to aling along y-axis
var collider = new THREE.Raycaster();
var shiftY = new THREE.Vector3();
var colliderDir = new THREE.Vector3(0, -1, 0); // down along y-axis to the mesh of height map

shiftY.set(n.position.x, 100, n.position.z); // set the point of the origin
collider.set(shiftY, colliderDir);  //set the ray of the raycaster
colliderIntersects = collider.intersectObject(plane); // plane is the mesh of height map
if (colliderIntersects.length > 0){
    n.position.y = colliderIntersects[0].point.y; // set the position of the object
}

jsfiddle示例