zoukankan      html  css  js  c++  java
  • [原]three.js (四)离散层次细节level of details

    LOD 处理比较大的外部地面场景中比较有用, 一般用于绘制地形。 首先通过可视体的切割删除不用的地形块,接着通过LOD 对照相机不同距离的地形块进行层次细节调整。

    这里采用最简单的LOD 方法。

    首先地形有n*n 的块构成, 这些块共同构成一个大平面;

    首先根据每个块到照相机的距离 计算细节层次, 

    例如假设由5*5 个块构成地形, 每个块1*1大小, 有4个细节层次, 

    当块距离照相机 小于2 层次 0

    距离小于4  层次 1

    小于6 层次 2

    其它层次 3

    首先构造一个Object3D 作为整个地面的代表。

    myGame.Earth = function(){
        THREE.Object3D.call(this);
        this.curPatches = [];
        this.patches = [];
        this.width = 5;
        this.height = 5;
        this.patch_width = 1;
        this.patch_height = 1;
        for(var i = 0; i < this.height; i++)
        {
            for(var j = 0; j < this.width; j++)
            {
                this.patches.push(1);//distance ---> detail 0 1*1
            }
        }
    };
    
    
    myGame.Earth.prototype = new THREE.Object3D();
    


    var earth = new myGame.Earth();

    earth中的每一个块是 一个Mesh 对象,底层的几何体是一个PlaneGeometry

    curPatches 用于存放当前组成earth的块, 当细节层次需要改变的时候这些块将被丢弃,而重新构造新的块。

    patches用于存储当前块的细节层次。


    关键的setDetails 函数用于调节块的细节, 首先计算所有块到照相机的距离 得到细节层次; 接着删除旧的所有平面, 接着再构建新的块加入到场景中。 


    myGame.Earth.prototype.setDetails = function(camera){
        var diff = new THREE.Vector3();
        var standard = this.patch_width;
        var pos = new THREE.Vector3();
        for(var i = 0; i < this.height; i++)
        {
            for(var j = 0; j < this.width; j++)
            {
                pos.set(-this.width/2*this.patch_width+j*this.patch_width+this.patch_width/2, 
                        0, 
                        -this.height/2*this.patch_height+i*this.patch_height+this.patch_height/2); 
    
                var dist = diff.sub(camera.position, pos).length();
                if(dist < 2*standard)
                    this.patches[i*this.width+j] = 0;
                else if(dist < 4*standard)
                    this.patches[i*this.width+j] = 1;
                else if(dist < 6*standard)
                    this.patches[i*this.width+j] = 2;
                else
                    this.patches[i*this.width+j] = 3;
            }
        }
        for(var i = 0; i < this.curPatches.length; i++)
        {
            this.remove(this.curPatches[i]);
        }
        var mat = new THREE.MeshBasicMaterial({color:0xff0000, wireframe:true});
        for(var i = 0; i < this.patches.length; i++)
        {
            var pl;
            var detail = this.patches[i];
            console.log(detail);
            if(detail == 0)
                pl = new THREE.PlaneGeometry(this.patch_width, this.patch_height, 10, 10);
            else if(detail == 1)
                pl = new THREE.PlaneGeometry(this.patch_width, this.patch_height, 5, 5);
            else if(detail == 2)
                pl = new THREE.PlaneGeometry(this.patch_width, this.patch_height, 2, 2);
            else
                pl = new THREE.PlaneGeometry(this.patch_width, this.patch_height, 1, 1);
            var obj = new THREE.Mesh(pl, mat);
            obj.position.set(-this.width/2*this.patch_width+i%this.width*this.patch_width+this.patch_width/2, 
                            -this.height/2*this.patch_height+ (this.height-~~(i/this.width))*this.patch_height+this.patch_height/2,
                            0);
            this.curPatches.push(obj);
            this.add(obj);
        }
    };
    


    在每帧更新的时候, 通过检测照相机新旧位置的距离差, 如果足够大 则更新整个场景的块。

    function animate()
    {
        requestAnimationFrame(animate);
        controls.update(clock.getDelta());
        var vec = new THREE.Vector3();
        var dist = vec.sub(camera.position, camera.oldPosition).length();
        if(dist > earth.patch_width)
        {
            camera.oldPosition.copy(camera.position);
            earth.setDetails(camera);
        }
        render();
    }
    



    作者:liyong748 发表于2012/9/10 22:50:42 原文链接
    阅读:635 评论:0 查看评论
  • 相关阅读:
    Java 基础
    Java 数据类型
    Spring 拦截器实现事物
    SSH 配置日记
    Hibernate 知识提高
    Jsp、Servlet
    leetcode 97. Interleaving String
    leetcode 750. Number Of Corner Rectangles
    leetcode 748. Shortest Completing Word
    leetcode 746. Min Cost Climbing Stairs
  • 原文地址:https://www.cnblogs.com/liyonghelpme/p/4273568.html
Copyright © 2011-2022 走看看