一、挖空原理说明

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 {
width: 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>

使用Three.js挖空安装门来解决重叠闪烁的问题的更多相关文章

  1. windows下node.js+sublime中安装coffeescript

    node.js中安装Coffeescript 1.我的node.js安装目录 2.node.js 全局模块所在目录   3.node.js安装coffeescript npm install -g c ...

  2. node.js的npm安装

    我不打算引进node.js的npm安装,但发现node.js通过管理一些包npm实现,或给一个简短的npm. 1.npm什么        npm是一个node包管理和分发工具,已经成为了非官方的公布 ...

  3. Node.js 多版本安装

    Node.js 多版本安装 Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine(Node.js 是一个基于 ...

  4. <亲测>CentOS 7.3下Node.js 8.6安装配置(含NPM以及PM2)

    CentOS 7.3下Node.js 8.6安装配置 2017年09月30日 14:12:02 阅读数:2245更多 个人分类: Nodejs   版权声明:本文为博主原创文章,未经博主允许不得转载. ...

  5. ArcGIS案例学习笔记-批处理擦除挖空挖除相减

    ArcGIS案例学习笔记-批处理擦除挖空挖除相减 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 目的:批处理擦除.挖空.挖除.相减 数据源:chp13/ex5/pa ...

  6. ArcGIS案例学习笔记-手动编辑擦除挖空挖除相减

    ArcGIS案例学习笔记-手动编辑擦除挖空挖除相减 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 目的:手动编辑擦除.挖空.挖除.相减 1. 选中内部要素 2. c ...

  7. js判断是否安装flash player及当前版本 和 检查flash版本是否需要升级

    一.js检查flash版本升级 for (var i = 0, len = navigator.plugins.length; i < len; i++) { var plugin = navi ...

  8. light,node.js,webStorm 安装项目搭建

    light,是一个移动应用开发平台,旨在降低H5.APP的开发门槛.运维成本.提升移动应用产品的持续交付能力. 用light可以做什么 快速组织移动H5应用的协作开发.调试.应用发布,发布的应用可直接 ...

  9. vue.js 2.0 --- 安装node环境,webpack和脚手架(入门篇)

    1.环境搭建 1.1.安装node.js 1.2 安装过程很简单,一路“下一步”就可以了.安装完成之后,打开命令行工具(win+r,然后输入cmd),输入 node -v,如下图,如果出现相应的版本号 ...

随机推荐

  1. [转]Ubuntu18.04下使用Docker Registry快速搭建私有镜像仓库

    本文转自:https://blog.csdn.net/BigData_Mining/article/details/88233015 1.背景 在 Docker 中,当我们执行 docker pull ...

  2. vs 中引用自己创建程序集出现小叹号

    出现的问题: 原因是.net frame work版本不一致 解决方法: 项目单击右键-->属性: 改为与你要引用的项目的程序集的版本一致即可

  3. JQuery官方学习资料(译):操作元素

      获取和设置元素的信息     有很多种方式可以改变现有的元素,最常见的是改变HTML内容或者元素的属性.JQuery提供了简单的夸浏览器的方法来帮助你实现元素信息的获取和设置. .html():获 ...

  4. Jquery操作ul的一些操作笔记

    1.html标记 <ul id="attachText"> <li data-text="111"><a href="# ...

  5. Android开发过程中的坑及解决方法收录(二)

    bug 1: bug描述: 无法成功地将edittext中的内容传入数据库中 bug动图: 经过: 最近写了个项目,项目要使用到SQL数据库,由于没有相关知识,便是找到了各种资料开始了自学之旅,在de ...

  6. 数据结构——基于java的链表实现(真正理解链表这种数据结构)

    原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10759599.html,否则将追究法律责任!!! 一.链表介绍 1.什么是链表? 链表是一 ...

  7. mongodb与spring mvc 整合

    1.pom文件添加对mongodb的倚赖 <dependency> <groupId>org.mongodb</groupId> <artifactId> ...

  8. 记录一些日常windows命令或操作技巧

    一.远程连接 通常我们发布项目的时候会先发布成本地文件然后通过远程服务器连接放到测试服务器发布成站点,这里就涉及到对远程发布的一些操作. 1. 点击运行,输入 mstsc /admin (这里的adm ...

  9. 【CSS学习】--- 文本水平对齐属性text-align和元素垂直对齐属性vertical-align

    一.文本水平对齐属性---text-align text-align属性是将块级标签以及单元格里面的内容进行相应的对齐,块级标签里的内联元素会被整体进行移动,而子块级元素或子单元格则会继承父元素的te ...

  10. CentOS7防火墙firewalld设置

    添加80端口  重启后永久生效 firewall-cmd --zone=public --add-port=80/tcp --permanent   查看防火墙状态 systemctl status ...