赞
踩
Scene场景
指包含了所有要渲染和呈现的三维对象、光源、相机以及其他相关元素的环境;场景可以被渲染引擎或图形库加载和处理,以生成最终的图像或动画
- scene.background = new THREE.Color(0x000000); // 设置背景颜色为黑色
-
- scene.fog = new THREE.Fog(0x000000, 0.1, 100); // 创建线性雾效,颜色为黑色,起始距离为0.1,结束距离为100
- scene.add(mesh); // 将名为mesh的对象添加到场景中
-
- scene.remove(mesh); // 从场景中移除名为mesh的对象
-
- var obj = scene.getObjectByName('mesh'); // 获取名称为mesh的对象
-
- scene.traverse(function(object) {
- // 对每个对象执行的操作
- console.log(object);
- });
-
- scene.dispose(); // 清除场景及其相关资源
Geometry
几何体指的是表示和描述三维对象形状的数据,描述了对象的形状
常用的Geometry(几何体):
Material
材质指的是给定几何体表面外观的属性和特征,定义了对象的外观属性
常用的Material(材质):
Mesh
网格模型是由几何体和材质组合而成的实体,将几何体和材质组合成一个完整的实体
- mesh.material = new THREE.MeshBasicMaterial({ color: 0xff0000 }); // 设置网格的材质为红色基础材质
-
- mesh.rotation.set(Math.PI / 2, 0, 0); // 设置网格绕X轴旋转90度
-
- mesh.rotateY(Math.PI / 4); // 将网格绕Y轴旋转45度
-
- mesh.position.set(0, 0, 0); // 设置网格的位置为原点
-
- mesh.visible = false; // 隐藏网格
-
- mesh.material.opacity = 0.5; // 将网格材质的透明度设置为0.5
用于模拟人眼视角和观察场景的虚拟设备
常用的Camera 相机:
方法举例:
- camera.lookAt(new THREE.Vector3(0, 0, 0)); // 将相机对准场景原点
-
- camera.updateProjectionMatrix(); // 更新相机的投影矩阵
-
- const newCamera = camera.clone(); // 克隆相机
属性举例:
- camera.position.set(0, 0, 10); // 设置相机在场景中的位置
-
- camera.rotation.set(0, Math.PI / 2, 0); // 设置相机的旋转角度
-
- camera.fov = 60; // 设置透视相机的视角大小为60度
-
- camera.zoom = 2; // 将正交相机设置为缩放倍数为2
AmbientLight(环境光):环境光是一个均匀无方向的光源,用于模拟场景中无处不在的环境光照射。它不会产生阴影,对场景中的所有物体都产生均匀的照明效果。
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); // 环境光
PointLight(点光源):点光源是一个从一个点向四面八方发射光线的光源。会在场景中产生逐渐减弱的光照效果,并且可以投射阴影。通常用于模拟灯泡、蜡烛等点光源
- const pointLight = new THREE.PointLight(0xff0000, 1, 10); // 红色点光源
- pointLight.position.set(0, 3, 0)
DirectionalLight(平行光):平行光是一种无限远、平行的光源,模拟太阳光。它是从一个特定的方向射来的光,所有光线都是平行的。平行光可以产生阴影,对场景中的物体产生类似于自然光的直射效果
- const directionalLight = new THREE.DirectionalLight(0x00ff00, 1); // 绿色平行光
- directionalLight.position.set(-1, 2, 4);
SpotLight(聚光灯):聚光灯是一个从一个点射出的光锥,具有指定的方向和光束角度。它可以投射出锥形的光束,并且可以产生阴影。聚光灯通常用于模拟手电筒、舞台灯光等
- const spotLight = new THREE.SpotLight(0x0000ff, 1, 10, Math.PI / 4, 0.5); // 蓝色聚光灯
- spotLight.position.set(2, 3, 0);
- spotLight.target.position.set(0, 0, 0);
WebGLRenderer
渲染器用于在Web浏览器中使用WebGL绘制和呈现3D图形
使用户可以通过鼠标或触摸手势来旋转、缩放和平移相机,以改变场景的视角
属性举例:
- controls.enabled = true; // 启用控制器
-
- controls.minZoom = 0.5; // 设置相机的最小缩放倍数为0.5
- controls.maxZoom = 2; // 设置相机的最大缩放倍数为2
-
- controls.enableRotate = true; // 启用旋转操作
- controls.enableZoom = true; // 启用缩放操作
- controls.enablePan = true; // 启用平移操作
path.js
- function path() {
- return [{
- name: "中式",
- styleObj: {
- background: '#409EFF'
- },
- children: [{
- name: "客餐厅",
- styleObj: {
- background: '#409EFF'
- },
- jpgNameArr: ["00125.jpg"]
- }, {
- name: "客厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "餐厨",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卧室",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卫浴",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "书房",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }]
- }, {
- name: "现代",
- styleObj: {
- background: null
- },
- children: [{
- name: "客餐厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "客厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "餐厨",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卧室",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卫浴",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }]
- }, {
- name: "新古典",
- styleObj: {
- background: null
- },
- children: [{
- name: "客餐厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "客厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "餐厨",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卧室",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卫浴",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }]
- }, {
- name: "欧式",
- styleObj: {
- background: null
- },
- children: [{
- name: "客餐厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "客厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "餐厨",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卧室",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卫浴",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }]
- }, {
- name: "美式",
- styleObj: {
- background: null
- },
- children: [{
- name: "客餐厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "客厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "餐厨",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卧室",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "卫浴",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }]
- }, {
- name: "北欧",
- styleObj: {
- background: null
- },
- children: [{
- name: "客餐厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "客厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- },{
- name: "卧室",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }]
- }, {
- name: "法式",
- styleObj: {
- background: null
- },
- children: [{
- name: "客厅",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }, {
- name: "餐厨",
- styleObj: {
- background: null
- },
- jpgNameArr: ["0011.jpg"]
- }]
- }]
-
- }
index.html
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <title>Three.js-webgl室内设计效果全景在线预览</title>
- <style>
- body {
- margin: 0;
- overflow: hidden;
- }
-
- #menu {
- position: absolute;
- bottom: 0px;
- color: #fff;
- background: rgba(0, 0, 0, 0.5);
- padding: 10px;
- z-index: 102;
- width: 500px;
- height: 80px
- }
-
- #menu>div {
- padding: 5px;
- }
-
- #menu span {
- display: inline-block;
- padding: 5px 10px;
- cursor: pointer;
- }
-
- .el-button--danger {
- font-size: 25px !important;
- background: rgba(0, 0, 0, 0.5) !important;
- border-width: 0px !important;
- width: 50px !important;
- height: 50px !important;
- }
-
- [v-cloak] {
- display: none;
- }
- </style>
- <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.min.js"></script>
- <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>
- <script src="http://www.yanhuangxueyuan.com/js/vue@2.5.16.min.js"></script>
- <!-- 主要用于功能按钮 -->
- <script src="http://www.yanhuangxueyuan.com/js/element-ui/index.js"></script>
- <!-- 主要用于弹出框 -->
- <link rel="stylesheet" href="http://www.yanhuangxueyuan.com/js/element-ui/index.css">
- <script src="path.js"></script>
- </head>
-
- <body>
- <div id="app" z-index="105">
- <!-- 底部选择栏 -->
- <div id="menu" :style="{left:width/2 + -250+'px'}">
- <div><span style="font-weight:bold;cursor:default;"> 风格:</span><span v-for="obj in styleArr"
- @click="styleClick(obj)" :style="obj.styleObj"> {{ obj.name }}</span></div>
- <div><span style="font-weight:bold;cursor:default;"> 位置:</span><span v-for="obj in posArr"
- @click="posClick(obj)" :style="obj.styleObj" v-if="obj.jpgNameArr.length"> {{ obj.name }}</span>
- </div>
- </div>
- <!-- 顶部功能栏 使用的element-->
- <div style="position: absolute;right:20px;top:20px">
- <el-button type="danger" circle @click="audioClick()"><i><img
- :src="(audioBoool)?('./UI/打开声音.png'):('./UI/关闭声音.png')" alt="" height="20"
- width="20"></i></el-button>
- <el-button type="danger" circle @click="ScreenClick()"><i><img
- :src="(ScreenBoool)?('./UI/全屏5.png'):('./UI/退出全屏.png')" alt="" width="18"
- height="18"></i></el-button>
- <el-button type="danger" circle @click="rotateClick()"><i><img
- :src="(rotateBoool)?('./UI/旋转.png'):('./UI/停止旋转.png')" alt="" width="20"
- height="20"></i></el-button>
- <el-button type="danger" circle @click="questionClick()"><i><img src="./UI/帮助5.png" alt="" width="22"
- height="22"></i></el-button>
- </div>
- </div>
- <script>
- // 创建场景
- var scene = new THREE.Scene();
- // 创建一个球体(Sphere)几何体
- var box = new THREE.SphereGeometry(25, 50, 50);
- // 创建一个基本网格材质
- var material = new THREE.MeshBasicMaterial({
- color: 0xffffff,
- side: THREE.BackSide,
- });
- // 创建了一个网格对象实例
- var mesh = new THREE.Mesh(box, material);
- // 将网格对象添加到场景中,以便在渲染时呈现出来
- scene.add(mesh);
- // 创建了一个纹理加载器实例
- var textureLoader = new THREE.TextureLoader();
- // 创建了一个音频监听器实例
- var listener = new THREE.AudioListener();
- // 创建一个用于播放音频的对象
- var audio = new THREE.Audio(listener);
- // 创建一个纹理加载器,并调用 load() 方法加载指定路径的纹理图像
- var texture = textureLoader.load('./风格/中式/客餐厅/00125.jpg', function (obj) {
- vm.loading.close();
- // 创建一个音频加载器
- var audioLoader = new THREE.AudioLoader();
- audioLoader.load('./音乐/琵琶语.mp3', function (AudioBuffer) {
- // 将加载的音频数据设置给 audio 对象
- audio.setBuffer(AudioBuffer);
- // 设置音频循环播放
- audio.setLoop(true);
- // 设置音频音量
- audio.setVolume(0.3);
- // 开始播放音频
- audio.play()
- });
- // 执行渲染
- render()
- });
- // 网格对象将使用加载的纹理作为材质的贴图
- mesh.material.map = texture;
- // 当前窗口的宽度
- var width = window.innerWidth;
- // 获取当前窗口的高度
- var height = window.innerHeight;
- // 计算宽高比
- var k = width / height;
- // 创建相机
- var camera = new THREE.PerspectiveCamera(60, k, 1, 1000);
- // 设置相机的缩放比例为 1。表示相机的视野不进行缩放
- camera.zoom = 1;
- // 修改相机的属性后,需要调用该方法来更新相机的投影矩阵,确保改变后的属性生效
- camera.updateProjectionMatrix();
- // 设置相机的位置坐标 通过设置相机的位置,可以决定场景中的视角
- camera.position.set(-0.87, 0.03, 0.4);
- // 设置相机的视线方向朝向场景的原点
- camera.lookAt(scene.position);
- // 创建一个基于 WebGL 的渲染器对象
- var renderer = new THREE.WebGLRenderer({
- // 开启抗锯齿效果,提高渲染的质量
- antialias: true,
- });
- // 设置渲染器的输出画布大小为窗口的宽度和高度
- renderer.setSize(width, height);
- // 将渲染器的 canvas 元素添加到页面的 body 中
- document.body.appendChild(renderer.domElement);
- // 创建时钟对象 用于跟踪时间的流逝,可以用来控制动画和其他与时间相关的操作
- var clock = new THREE.Clock();
- // 表示每秒帧数,这里设置为 30 帧
- var FPS = 30;
- // 计算每帧的时间间隔
- var 刷新时间 = 1 / FPS;
- var timeS = 0;
-
- function render() {
- // 浏览器执行下一次渲染时调用 render 函数
- requestAnimationFrame(render);
- // getDelta() 返回上一次调用之后的时间差,即两次渲染之间的时间间隔
- var 渲染间隔 = clock.getDelta();
- timeS = timeS + 渲染间隔;
- // 总运行时间是否大于刷新时间
- if (timeS > 刷新时间) {
- // 使用渲染器对象 renderer 来渲染场景 scene 和相机 camera
- renderer.render(scene, camera);
- if (vm.rotateBoool) {
- // mesh 沿 Y 轴旋转 0.002 弧度
- mesh.rotateY(0.002)
- }
- timeS = 0
- }
- }
- render();
- // 创建了一个控制器对象,用于控制相机的旋转、缩放和平移等操作
- var controls = new THREE.OrbitControls(camera);
- // 禁用 OrbitControls 控制器对象的平移功能
- controls.enablePan = false;
- // 获取本地数据
- var styleObjArr = path();
- var vm = new Vue({
- el: "#app",
- data: {
- loading: null,
- styleArr: styleObjArr,
- styleChoose: null,
- posArr: null,
- posChoose: null,
- width: window.innerWidth,
- height: window.innerHeight,
- classPath: '中式/客餐厅',
- path: '',
- audioBoool: true,
- ScreenBoool: true,
- rotateBoool: true,
- N: styleObjArr[0].children[0].jpgNameArr.length,
- num: 1,
- },
- methods: {
- audioClick: function () {
- // 播放音乐
- if (this.audioBoool) {
- this.audioBoool = false;
- audio.pause()
- } else {
- // 暂停音乐
- this.audioBoool = true;
- audio.play()
- }
- },
- // 全屏方法
- ScreenClick: function () {
- if (this.ScreenBoool) {
- this.ScreenBoool = false;
- requestFullScreen()
- } else {
- this.ScreenBoool = true;
- exitFullscreen()
- }
- },
- questionClick: function () {
- // element弹框的的this.$alert
- this.$alert('按住左键不放上下左右拖动,可以旋转整个场景', '旋转操作', {})
- },
- // 旋转
- rotateClick: function () {
- if (this.rotateBoool) {
- this.rotateBoool = false
- } else {
- this.rotateBoool = true
- }
- },
- nextClick: function () {
- if (this.num < this.N) {
- this.num += 1
- } else {
- this.num = 1
- }
- },
- upClick: function () {
- if (this.num > 1) {
- this.num -= 1
- } else {
- this.num = this.N
- }
- },
- // 风格选择
- styleClick: function (styleObj) {
- this.loading = this.$loading({
- lock: true,
- text: 'Loading',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- });
- this.num = 1;
- this.styleChoose.styleObj.background = null;
- this.posChoose.styleObj.background = null;
- this.styleChoose = styleObj;
- this.styleChoose.styleObj.background = '#409EFF';
- this.posArr = this.styleChoose.children;
- this.posChoose = this.posArr[0];
- this.posArr[0].styleObj.background = '#409EFF';
- this.N = this.posChoose.jpgNameArr.length;
- this.classPath = this.styleChoose.name + '/' + this.posChoose.name;
- this.path = this.classPath + '/' + this.posChoose.jpgNameArr[this.num - 1];
- var texture = textureLoader.load('./风格/' + this.path, function (obj) {
- // 关闭加载中的提示框
- vm.loading.close();
- render()
- });
- mesh.material.map = texture
- },
- // 位置选择
- posClick: function (posObj) {
- this.loading = this.$loading({
- lock: true,
- text: 'Loading',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- });
- this.num = 1;
- this.posChoose.styleObj.background = null;
- this.posChoose = posObj;
- this.N = this.posChoose.jpgNameArr.length;
- this.posChoose.styleObj.background = '#409EFF';
- this.classPath = this.styleChoose.name + '/' + this.posChoose.name;
- this.path = this.classPath + '/' + this.posChoose.jpgNameArr[this.num - 1];
- var texture = textureLoader.load('./风格/' + this.path, function (obj) {
- vm.loading.close();
- render()
- });
- mesh.material.map = texture
- }
- },
- watch: {
- num: function (value) {
- this.loading = this.$loading({
- lock: true,
- text: 'Loading',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- });
- this.path = this.classPath + '/' + this.posChoose.jpgNameArr[this.num - 1];
- console.log(this.path);
- var texture = textureLoader.load('./风格/' + this.path, function (obj) {
- vm.loading.close();
- render()
- });
- mesh.material.map = texture;
- render()
- }
- },
- created() {
- this.posArr = styleObjArr[0].children;
- this.styleChoose = this.styleArr[0];
- this.posChoose = styleObjArr[0].children[0];
- this.loading = this.$loading({
- lock: true,
- text: 'Loading',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- })
- }
- });
-
- window.onresize = onresizeFun;
- function onresizeFun() {
- renderer.setSize(window.innerWidth, window.innerHeight);
- // 设置相机的视图比例(即宽高比)
- camera.aspect = window.innerWidth / window.innerHeight;
- // 修改相机的属性后,需要调用该方法来更新相机的投影矩阵,确保改变后的属性生效
- camera.updateProjectionMatrix();
- vm.width = window.innerWidth;
- vm.height = window.innerHeight;
- };
-
- function requestFullScreen() {
- // 获取文档的根元素
- var de = document.documentElement;
- // 检查当前浏览器是否支持 requestFullscreen 方法
- if (de.requestFullscreen) {
- // 全屏显示模式
- de.requestFullscreen()
- } else if (de.mozRequestFullScreen) { //进一步检查当前浏览器是否支持 mozRequestFullScreen 方法
- de.mozRequestFullScreen()
- } else if (de.webkitRequestFullScreen) { //再进一步检查当前浏览器是否支持 webkitRequestFullScreen 方法
- de.webkitRequestFullScreen()
- }
- }
- // 与上相反 退出全屏
- function exitFullscreen() {
- var de = document;
- if (de.exitFullscreen) {
- de.exitFullscreen()
- } else if (de.mozCancelFullScreen) {
- de.mozCancelFullScreen()
- } else if (de.webkitCancelFullScreen) {
- de.webkitCancelFullScreen()
- }
- }
- </script>
- </body>
-
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。