zoukankan      html  css  js  c++  java
  • 使用Three.js挖空安装门来解决重叠闪烁的问题

        一、挖空原理说明

    subtract 用墙面减去与门重叠的部分,产生一个新的对象,导入材质安装门即可

    //参与减去几何体 
    //平行于x轴门
    var meshH4Door = new ThreeBSP( meshHDoor );  
    //平行x轴横墙面
    var meshWall4 = new ThreeBSP( meshH4 );
    
    //平行x轴横墙面meshWall4对象 减去与meshH4Door门重叠部分  
    var subtract_bsp = meshWall4.subtract( meshH4Door );
    var result = subtract_bsp.toMesh( new THREE.MeshLambertMaterial({ 
    	shading: THREE.SmoothShading,
    	map: THREE.ImageUtils.loadTexture('./img/floor-1.jpg'),
    	color: 0xff0000}) );
    result.geometry.computeVertexNormals();
    //添加至场景中
    scene.add( result );   

    效果图

    源代码如下

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>threejs中挖空解决闪烁bug</title>
            <style>
                #canvas-frame {
                     100%;
                    height: 450px;
                }
            </style>
        </head>
        <body onload="threeStart()">
            <div id="canvas-frame" ></div>
        </body>
        <script type="text/javascript" src="./lib/three.js" ></script>
        <!-- 运算挖门 解决闪烁bug -->
        <script type="text/javascript" src="lib/ThreeCSG.js"></script>
        <script type="text/javascript">
                var renderer, //渲染器
                    width = document.getElementById('canvas-frame').clientWidth, //画布宽
                    height = document.getElementById('canvas-frame').clientHeight; //画布高
                //照相机配置
                var fov = 45,//拍摄距离  视野角值越大,场景中的物体越小
                    near = 1,//最小范围
                    far = 1000;//最大范围
                //DOM对象
                var canvas = null;
                //初始化DOM对象   
                function initDOM(){
                    canvas = document.getElementById("canvas-frame");
                }
                //初始化渲染器
                function initThree(){
                    renderer = new THREE.WebGLRenderer({
                         antialias : true
                         //canvas: document.getElementById('canvas-frame')
                    });
                    renderer.setSize(width, height);
                    renderer.setClearColor(0xFFFFFF, 1.0);
                    document.getElementById('canvas-frame').appendChild(renderer.domElement);
                        renderer.setClearColor(0xFFFFFF, 1.0);
                }
                //初始化场景
                var scene;
                function initScene(){
                    scene = new THREE.Scene();
                }
                var camera;
                function initCamera() {  //透视相机
                    camera = new THREE.PerspectiveCamera(fov,  width/height , near, far);
                    camera.position.x = 150;
                    camera.position.y = 150;
                    camera.position.z =450;
                    camera.up.x = 0;
                    camera.up.y = 1; //相机朝向--相机上方为y轴
                    camera.up.z = 0;
                    camera.lookAt({  //相机的中心点
                        x : 0,
                        y : 0,
                        z : 0
                    });
                }
                function initLight(){
                    // light--这里使用环境光
                    //var light = new THREE.DirectionalLight(0xffffff); /*方向性光源*/
                    //light.position.set(600, 1000, 800);
                    var light = new THREE.AmbientLight(0xffffff); //模拟漫反射光源
                    light.position.set(600, 1000, 800); //使用Ambient Light时可以忽略方向和角度,只考虑光源的位置
                    scene.add(light);
                }
                function initObject(){  //初始化对象
                    //初始化地板
                    initFloor();
                    initWall();
                }
                function initGrid(){ //辅助网格
                    var helper = new THREE.GridHelper( 1000, 50 );
                    helper.setColors( 0x0000ff, 0x808080 );
                    scene.add( helper );
                }
                function initFloor(){
                	
                	 //导入材质
                    var texture = THREE.ImageUtils.loadTexture('img/floor-1.jpg', {}, function() {
                        renderer.render(scene, camera);
                    });
                    /**
                     * 关于material材料注意点说明 
                     * MeshBasicMaterial:对光照无感,给几何体一种简单的颜色或显示线框。
                     * MeshLambertMaterial:这种材质对光照有反应,用于创建暗淡的不发光的物体。
                     * MeshPhongMaterial:这种材质对光照也有反应,用于创建金属类明亮的物体。
                     */
                    var material = new THREE.MeshLambertMaterial({
                        map: texture
                    });
                    
                    //创建一个立方体
                    var geometry = new THREE.BoxGeometry(400, 20, 400);
                     for ( var i = 0; i < geometry.faces.length; i += 2 ) {
                        var hex = Math.random() * 0xffffff;
                        geometry.faces[ i ].color.setHex( hex );
                        geometry.faces[ i + 1 ].color.setHex( hex );
                    }
                    //var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors} );
                    //将material材料添加到几何体geometry
                    var mesh = new THREE.Mesh(geometry, material);
                    mesh.position = new THREE.Vector3(0,0,0);
                    scene.add(mesh);
                }
                //墙面
                function initWall(){
                	
                	 //导入墙面材质(后面墙面共用)
                    var texture = THREE.ImageUtils.loadTexture('img/floor-1.jpg', {}, function() {
                        renderer.render(scene, camera);
                    });
                    /**
                     * 关于material材料注意点说明 
                     * MeshBasicMaterial:对光照无感,给几何体一种简单的颜色或显示线框。
                     * MeshLambertMaterial:这种材质对光照有反应,用于创建暗淡的不发光的物体。
                     * MeshPhongMaterial:这种材质对光照也有反应,用于创建金属类明亮的物体。
                     */
                    var material = new THREE.MeshLambertMaterial({
                        map: texture
                    });
                    
                    /*--------平行z轴横墙面3、x轴为墙面的厚度、 z轴为墙面长度、y轴为墙面高度--------------------*/
                	//平行z轴横墙面1   x轴为墙面厚度
                	var geometryH1 = new THREE.BoxGeometry(10, 65, 360);
                	/*var materialH1 = new THREE.MeshBasicMaterial( { color:0xFF0000 } );*/
                	//将material材料添加到几何体geometry
    	            var meshH1 = new THREE.Mesh(geometryH1, material);
    	            meshH1.position.x = 180;
    	            meshH1.position.y = 45;
    	            //scene.add(meshH1);
    	            var meshWall1 = new ThreeBSP( meshH1 );
    	            
    	            var geometryHDoor1 = new THREE.BoxGeometry(10, 56, 35);
                	var materialHDoor1 = new THREE.MeshBasicMaterial( { color:0x00BBAA} );
                	//将material材料添加到几何体geometry
    	            var meshHDoor1 = new THREE.Mesh(geometryHDoor1, materialHDoor1);
    	            meshHDoor1.position.x = 180;
    	            meshHDoor1.position.y = 45;
    	            meshHDoor1.position.z = 0;
    	            //scene.add(meshHDoor2);
    	            var meshHDoor1 = new ThreeBSP( meshHDoor1 );
    	            //墙面减去重叠的门
    	            subtractMesh(meshHDoor1, meshWall1);
    	            
    	            //为墙面1安装门
    	            var geometryHDoor1 = new THREE.BoxGeometry(10, 56, 35);
    	            //加载材质
    	            var textureDoor1 = THREE.ImageUtils.loadTexture('img/door.png', {}, function() {
    	                renderer.render(scene, camera);
    	            });
    	            var materialDoor1 = new THREE.MeshBasicMaterial({
    	                map: textureDoor1
    	            });
                	//var materialHDoor2 = new THREE.MeshBasicMaterial( { color:0x00BBAA} );
                	//将material材料添加到几何体geometry
    	            var meshHDoor1 = new THREE.Mesh(geometryHDoor1, materialDoor1);
    	            meshHDoor1.position.x = 180;
    	            meshHDoor1.position.y = 45;
    	            meshHDoor1.position.z = 0;
    	            scene.add(meshHDoor1);
    	            
    	            //平行z轴横墙面2 x轴为墙面厚度
                	var geometryH2 = new THREE.BoxGeometry(10, 65, 360);
                	var materialH2 = new THREE.MeshBasicMaterial( { color:0xFF00FF } );
                	//将material材料添加到几何体geometry
    	            var meshH2 = new THREE.Mesh(geometryH2, materialH2);
    	            meshH2.position.x = -180;
    	            meshH2.position.y = 45;
    	            var meshWall2 = new ThreeBSP( meshH2 );
    	            //scene.add(meshH2);
    	            
    	            var geometryHDoor2 = new THREE.BoxGeometry(10, 56, 35);
                	var materialHDoor2 = new THREE.MeshBasicMaterial( { color:0x00BBAA} );
                	//将material材料添加到几何体geometry
    	            var meshHDoor2 = new THREE.Mesh(geometryHDoor2, materialHDoor2);
    	            meshHDoor2.position.x = -180;
    	            meshHDoor2.position.y = 45;
    	            meshHDoor2.position.z = 0;
    	            var meshHDoor2 = new ThreeBSP( meshHDoor2 );
    	            //scene.add(meshHDoor2);
    	            //墙面减去重叠的门
    	            subtractMesh(meshHDoor2, meshWall2);
    	            
    	            
    	            //为墙面2安装门
    	            var geometryHDoor2 = new THREE.BoxGeometry(10, 56, 35);
    	            //加载材质
    	            var textureDoor2 = THREE.ImageUtils.loadTexture('img/door.png', {}, function() {
    	                renderer.render(scene, camera);
    	            });
    	            var materialDoor2 = new THREE.MeshBasicMaterial({
    	                map: textureDoor2
    	            });
                	//var materialHDoor2 = new THREE.MeshBasicMaterial( { color:0x00BBAA} );
                	//将material材料添加到几何体geometry
    	            var meshHDoor2 = new THREE.Mesh(geometryHDoor2, materialDoor2);
    	            meshHDoor2.position.x = -180;
    	            meshHDoor2.position.y = 45;
    	            meshHDoor2.position.z = 0;
    	            scene.add(meshHDoor2);
    	        /*--------平行z轴横墙面3、x轴为墙面的厚度、 z轴为墙面长度、y轴为墙面高度--------------------*/
    	            
    	            
    	       /*--------平行x轴横墙面3、x轴为墙面长度、 z轴为墙面厚度、y轴为墙面高度--------------------*/
    	       //平行x轴横墙面3   z轴为墙面厚度
                	var geometryH3 = new THREE.BoxGeometry(365, 65, 10);
                	var materialH3 = new THREE.MeshBasicMaterial( { color:0x808080 } );
                	//将material材料添加到几何体geometry
    	        var meshH3 = new THREE.Mesh(geometryH3, material);
    	            meshH3.position.x = 0;
    	            meshH3.position.y = 45;
    	            meshH3.position.z = -180;
    	            var meshWall3 = new ThreeBSP( meshH3 );
    	            //scene.add(meshH3);
    	            
    	            //平行x轴横重叠门3 z轴为墙面厚度
                	var geometryHDoor = new THREE.BoxGeometry(35, 50, 10);
                	var materialHDoor = new THREE.MeshBasicMaterial( { color:0x00BBAA} );
                	//将material材料添加到几何体geometry
    	            var meshHDoor = new THREE.Mesh(geometryHDoor, materialHDoor);
    	            meshHDoor.position.x = 0;
    	            meshHDoor.position.y = 45;
    	            meshHDoor.position.z = -180;
    	            var meshHDoor3 = new ThreeBSP( meshHDoor );
    	            //scene.add(meshHDoor);
    	            //墙面减去重叠的门
    	            subtractMesh(meshHDoor3, meshWall3);
    	            
    	            //平行x轴横墙面3安装门
                    var geometryDoor3 = new THREE.BoxGeometry(35, 50, 10);
                    //加载材质
    	            var textureDoor3 = THREE.ImageUtils.loadTexture('img/door.png', {}, function() {
    	                renderer.render(scene, camera);
    	            });
    	            var materialDoor3 = new THREE.MeshBasicMaterial({
    	                map: textureDoor3
    	            });
                    door3 = new THREE.Mesh( geometryDoor3,materialDoor3);
                    door3.position.x = 0;
    	            door3.position.y = 45;
    	            door3.position.z = -180;
                    scene.add(door3);
                     /*--------平行x轴横墙面3、 z轴为墙面厚度、y轴为墙面高度--------------------*/
    	            
    	            /*--------平行x轴横墙面4、 z轴为墙面厚度、y轴为墙面高度--------------------*/
    	            //平行x轴横墙面4 z轴为墙面厚度
                	var geometryH4 = new THREE.BoxGeometry(365, 65, 10);
                	var materialH4 = new THREE.MeshBasicMaterial( { color:0x00AABB,  wireframe: true} );
                	//将material材料添加到几何体geometry
    	            var meshH4 = new THREE.Mesh(geometryH4, materialH4);
    	            meshH4.position.x = 0;
    	            meshH4.position.y = 45;
    	            meshH4.position.z = 180;
    	            //平行x轴横墙面4  挖出一道门
    				var meshWall4 = new ThreeBSP( meshH4 );
    	            //scene.add(meshH4);
    	            
    	            //平行x轴横重叠门4 z轴为墙面厚度
                	var geometryHDoor = new THREE.BoxGeometry(35, 50, 10);
                	var materialHDoor = new THREE.MeshBasicMaterial( { color:0x00BBAA} );
                	//将material材料添加到几何体geometry
    	            var meshHDoor = new THREE.Mesh(geometryHDoor, materialHDoor);
    	            meshHDoor.position.x = 0;
    	            meshHDoor.position.y = 45;
    	            meshHDoor.position.z = 180;
    	            //scene.add(meshHDoor);
    	            //重叠门
    	            var meshHDoor4 = new ThreeBSP( meshHDoor );
    	            //墙面减去重叠的门
    	            subtractMesh(meshHDoor4, meshWall4);
    	            
    				//平行x轴横墙面4安装门
                    var geometryDoor4 = new THREE.BoxGeometry(35, 50, 10);
                    //加载材质
    	            var textureDoor4 = THREE.ImageUtils.loadTexture('img/door.png', {}, function() {
    	                renderer.render(scene, camera);
    	            });
    	            var materialDoor4 = new THREE.MeshBasicMaterial({
    	                map: textureDoor4
    	            });
                    door4 = new THREE.Mesh( geometryDoor4,materialDoor4);
                    door4.position.x = 0;
    	            door4.position.y = 45;
    	            door4.position.z = 180;
                    scene.add(door4);
                    /*--------平行x轴横墙面3、x轴为墙面长度、 z轴为墙面厚度、y轴为墙面高度-------------------*/
                    
                }
                
                //运算减去
                /*
                 * meshDoor 门面
                 * meshWall 墙面  
                 */
                function subtractMesh(meshDoor,meshWall){
                	//平行x轴横墙面4减去与meshHDoor门重叠部分
    				var subtract_bsp = meshWall.subtract( meshDoor );
    				var result = subtract_bsp.toMesh( new THREE.MeshLambertMaterial({
    					shading: THREE.SmoothShading, 
    					map: THREE.ImageUtils.loadTexture('./img/floor-1.jpg') 
    				}));
    				result.geometry.computeVertexNormals();
    				scene.add( result );
                }
                //初始化页面加载
                function threeStart(){
                    //初始化DOM对象
                    initDOM();
                    //初始化渲染器
                    initThree();
                    //初始化场景
                    initScene();
                    //初始透视化相机
                    initCamera();
                    //初始化光源
                    initLight();
                    //模型对象
                    initObject();
                    //初始化网格辅助线
                    initGrid();
                    //渲染
                    //renderer.render(scene, camera);
                    //实时动画
                    animation();
                    //监听鼠标滚动事件
                    canvas.addEventListener('mousewheel', mousewheel, false);
                }
                function animation(){
                    //相机围绕y轴旋转,并且保持场景中的物体一直再相机的视野中
                    //实时渲染成像
                    var timer = Date.now()*0.0001;
                    camera.position.x = Math.cos(timer)*400;
                    camera.position.z = Math.sin(timer)*400;
                    camera.lookAt(scene.position);
                    renderer.render(scene, camera);
                    requestAnimationFrame(animation);
                }
    	        //鼠标滑轮-鼠标上下滑轮实现放大缩小效果
    	        function mousewheel(e) {
    	            e.preventDefault();
    	            //e.stopPropagation();
    	            if (e.wheelDelta) {  //判断浏览器IE,谷歌滑轮事件
    	                if (e.wheelDelta > 0) { //当滑轮向上滚动时
    	                    fov -= (near < fov ? 1 : 0);
    	                }
    	                if (e.wheelDelta < 0) { //当滑轮向下滚动时
    	                    fov += (fov < far ? 1 : 0);
    	                }
    	            } else if (e.detail) {  //Firefox滑轮事件
    	                if (e.detail > 0) { //当滑轮向上滚动时
    	                    fov -= 1;
    	                }
    	                if (e.detail < 0) { //当滑轮向下滚动时
    	                    fov += 1;
    	                }
    	            }
    	            //改变fov值,并更新场景的渲染
    	            camera.fov = fov;
    	            camera.updateProjectionMatrix();
    	            renderer.render(scene, camera);
    	            //updateinfo();
    	        }
        </script>
    </html>
  • 相关阅读:
    pandas 排序替换总结
    pandas 布尔值筛选总结
    矩阵的常见4中分解总结
    六,投资管理流程有投资者需求
    五,另类投资
    四 衍生工具
    使用webOffice开源js的一些先修知识
    文档填充遇到一些问题
    Swagger的配置与使用
    彻底刷新chrome浏览器的操作
  • 原文地址:https://www.cnblogs.com/zjf-1992/p/6278547.html
Copyright © 2011-2022 走看看