一、挖空原理说明

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. [转]Docker(三):Dockerfile 命令详解

    本文转自:https://blog.csdn.net/ityouknow/article/details/79600406 上一篇文章Docker(二):Dockerfile 使用介绍介绍了 Dock ...

  2. IDEA更换主题

    更换IDEA主题只需要3步 1. 下载主题 在主题网站上IDEA Color Themes 上浏览喜欢的主题并下载该主题.(如果网址有变更,google IDEA themes即可.)  2. 导入主 ...

  3. 类型,对象,线程栈,托管堆在运行时的关系,以及clr如何调用静态方法,实例方法,和虚方法(第二次修改)

    1.线程栈 window的一个进程加载clr.该进程可能含有多个线程,线程创建的时候会分配1MB的栈空间. 如图: void Method() { string name="zhangsan ...

  4. python网络聊天器多线程版

    在之前的一篇文章(python网络编程-udp)中实现了一个简单的udp聊天器,只能在单线程下进行收发数据,在学习完多线程之后,实现一个能同时收发数据的udp聊天器. 说明: 编写一个有2个线程的程序 ...

  5. js 正则表达式之环视结构

    一.环视 1:环视不“占用”字符,只匹配字符所在的特定位置. 2:正则表达式是从左向右进行匹配的. 二.肯定顺序环视(?=....) 子表达式匹配当前位置的右侧字符 图中:红色表示当前位置,绿色表示正 ...

  6. nodeJs express mongodb 建站(linux 版)

    一.环境安装 1.安装node wget http://nodejs.org/dist/v0.12.2/node-v0.12.2-linux-x64.tar.gz //下载tar xvf node-v ...

  7. [jQuery]循环遍历改变a标签的href

    把info类下面所有的a标签链接后天加"#article". jQuery(document).ready(function($){ $('.info a').each(funct ...

  8. 快速上手ABP - Angular部分 - 如何最快速度了解相关API。

    不是google,不是angular官网,而是在Visual Studio Code选中这个API对象,鼠标右键,选"Go to Definition" 例子:要想了解FormGr ...

  9. Boostrap模态框,以及通过jquery绑定td的值,使模态框回显

    做页面不管是登录或是修改信息,难免会使用到模态框,在此分享一个比较漂亮的模态框 Boostrap模态框 使用之前首先导入jquery-3.2.1.min.js,和bootstrap.min.js 先添 ...

  10. Centos 7下VMware三台虚拟机Hadoop集群初体验

    一.下载并安装Centos 7 传送门:https://www.centos.org/download/    注:下载DVD ISO镜像 这里详解一下VMware安装中的两个过程 网卡配置 是Add ...