前言

threejs官网:https://threejs.org/
github各个版本:https://github.com/mrdoob/three.js/tags
版本更迭很快,我用的时候还是r90秒秒钟r91出来了

刚入门的时候可以看看这个教程:http://www.hewebgl.com/article/articledir/1
初级教程是免费的,中高级是收费的,写的不是很枯燥,也不用跟着敲代码,有个相机,渲染器,场景,光源的概念就可以了。它适配的版本是比较旧的,我当时用新版本跟着写有些demo无法完成,新手更谈不上根据版本之间的差别找到问题,慢慢就失去兴趣了。

我的这个教程用的是r90版本,它有个比较好的地方是,当你使用高版本的threejs却使用低版本的语法时,浏览器console会有警告告诉你新的写法是什么样的。

我的DEMO下载

演示地址: 太穷了,带宽很小,加载卡顿请谅解(哭泣)
相机转动做的比较仓促没有考虑细节,导致鼠标拖拽或是放大缩小卡顿,emmm小问题暂时不想改了
https://www.hugeoyzy.top/threejs/src/demo1.html
https://www.hugeoyzy.top/threejs/src/demo2.html
下载:https://download.csdn.net/download/u010588262/10288776

开发工具

因为我主要是做java开发,所以就用idea了,因为idea写js也是有提示的,所以还挺方便,就建个Static Web项目就可以了:

我的项目结构是这样的:

调试需要做两点配置:
1. 浏览器路径:

  1. 浏览器启动参数,因为threejs要加载本地的图片文件,obj文件之类的,看网上教程都说是不允许的,要部署在apache和tomcat之类的,我没试,看到说可以加启动参数就加了,调试没问题
    –allow-file-access-from-files

调试的时候就在html文件上鼠标移到右上角,点击相应的浏览器图标就可以了

如果修改了html的话直接保存文件在浏览器刷新就能看到效果了,但是修改了js的话就要关闭页面重新点击浏览器图标。

官方DEMO(肥肠重要)

我入门最快的时候就是找到了官方DEMO之后

一个是:http://stemkoski.github.io/Three.js/#hello-world
这里的demo很入门,很好理解,页面最上方有github地址,可以去下载。唯一不好的是使用的版本很老。r60版本的,不过对于初学者一开始最重要的是理解大概的使用,不用纠结于最新版本。

还有一个是:https://threejs.org/examples/#webgl_animation_cloth
这里的demo相比第一个是比较高大上的,源代码就在你下载的threejs包里的examples目录下

代码讲解

这一块针对初学者中的初学者了,只要看过前言中的初级教程之后再看我的demo应该没问题了,demo的代码也比较整洁。

demo中的css,fonts,images和objs基本都是从官方demo中搞过来的,页面上引用的js分别是什么作用也做了注释了:

util.js是我把公用的东西放在一起了,要看懂util.js需要对threejs基本的组件有一些了解。

threejs的三围坐标是这样的,比如你现在对着电脑屏幕吧,把你屏幕的左下角想象成二维坐标原点,那往右就是x正方向,网上就是y正方向,从屏幕往外直盖脸的就是z正方向了。

最上面的src()是用来初始化场景,相机和渲染器的,最开始的textureLoader = new THREE.TextureLoader();是用来加载图片材质的,在大多数教程里用的都是ImageUtils来加载的,这个是新版本的改动,我说一下我对这仨玩意儿的理解吧

场景:就是一个黑盒子呗,把你要展示的东西全往里面装,地板啊,天花板啊,盒子啊,球啊,货架啊,三D字体啊全塞进去。为什么是黑盒子?因为你看不见它,也不看不见塞进去的东西。场景的初始化很简答就一句话scene = new THREE.Scene();

相机:相机可以在任意的位置,任意的角度”拍摄”黑盒子里的场景,相机的初始化稍微复杂一些。

    var SCREEN_WIDTH = window.innerWidth;var SCREEN_HEIGHT = window.innerHeight;var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);scene.add(camera);camera.position.set(0, 600, 1000);cameraRadius = Math.sqrt(camera.position.x * camera.position.x + camera.position.z * camera.position.z);camera.up.set(0, 1, 0);camera.lookAt(new THREE.Vector3(0, 0, 0));

关于相机比较难理解的是position,up和lookAt的关系。你可看看这个视频http://www.hewebgl.com/video/2,虽然我看完了也没怎么看懂。
尝试解释一下吧。
现在,把你的手机打开摄像头,正对着屏幕,想象它就像单反一样上面右边有个快门,这就是threejs中相机的初始方向,就是从z轴正方向看向z轴负方向。position是什么意思呢,现在把手机往右平移,意思是position.x在增加。lookAt也很容易,就是相机往哪儿拍呗。比较难理解的是up,好现在把手机位置固定,只能旋转哦,也就是说position固定了,好了现在把手机旋转镜头对着屏幕左下角,也就是咱们的三维坐标原点,也就是说lookAt也固定了。up的作用就是你现在可以旋转手机了,保持镜头对着屏幕左下角的方向,手机的中心点位置不要变,旋转手机,拍出来的画面就会是正的,或者斜着的,或者上下倒过来的。随着你旋转手机快门的朝向也在变是吧,默认快门是对着Y轴正方向的,也就是(0,1,0)如果把手机颠倒,up就变成了(0,-1,0),拍出来的画面也就是上下颠倒的,因为你虽然可以倒着手机拍,但是看照片的时候得把手机正过来看,画面也就是反的咯。

渲染器
可以看到相机的初始化过程中没有与场景绑定,他们俩就像在两个平行世界一样,看似在一起,其实没在一起,需要用渲染器把他们俩关联起来,这样,相机就拍到了场景里的东西,再通过渲染器展示在浏览器上被我们看到了。Decetor是通过Detector.js引入进来的东西,用于判断浏览器兼容性的。

    if (Detector.webgl)renderer = new THREE.WebGLRenderer({antialias: true});elserenderer = new THREE.CanvasRenderer();renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);container = document.getElementById('ThreeJS');container.appendChild(renderer.domElement);

以地板为例怎么搞一个东西放在场景里,CSDN的代码注释没有这么详细,写博客的时候加的,对不住只下资源不看文章的朋友。PlaneGeometry就是一个平面,SphereGeometry就是一个球,CubeGeometry就是一个立方体…….感兴趣的可以百度多了解一下其他组件。材质就是各种Material,也有很多种,有受光照影响的,有不受光照影响的。把组件和材质组合起来就是一个完整的物体啦,就是THREE.Mesh这个方法把他们组合起来,第一个参数是组件,第二个参数是材质,材质还可以传入一个数组,你可能觉得设置多个有啥意义啊一个盖住一个的,材质是可以设置透明度的,明白了吧。

function addfloor() {// 加载图片作为地板材质var floorTexture = textureLoader.load('images/checkerboard.jpg');// 沿x方向和Y方向都重复填充floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;// x方向和y方向各重复几次,不理解的话改改这个值看看效果就知道了floorTexture.repeat.set(4, 4);// 将材质包装成表面材料,设置正反两面都要铺上var floorMaterial = new THREE.MeshBasicMaterial({map: floorTexture, side: THREE.DoubleSide});// 平面对象var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 1, 1);// 把对象和材料包装成Meshfloor = new THREE.Mesh(floorGeometry, floorMaterial);// 设置位置放入场景啦floor.position.y = -0.5;floor.rotation.x = Math.PI / 2;scene.add(floor);
}

others()方法里是一些可有可无的辅助,看注释就明白了。
animate()就是开始持续渲染,渲染就是通过renderer.render(scene, camera);把渲染器搞到的东西放在浏览器上给你看,持续渲染就是通过重复调用方法本身可以实现动画的效果requestAnimationFrame(animate);,除了这两个东西还调用了update();方法,update方法里就是慢慢的移动组件或者刷新其他需要更新得组件。requestAnimationFrame方法是比较平滑的动画,我之前想用Tween.js实现相机转动的效果,很卡顿,不流畅。

woodycube()就是封装了获得木箱,因为两个demo里都用到了木头箱子。

后面有空再说一下demo中的代码

2018年3月16日
更新了一下util.js中的代码,把鼠标点击选中事件和getMeshed方法从demo2中移到util里面了
点击事件

document.addEventListener("mousedown", onDocumentMouseDown, false);
function onDocumentMouseDown(e) {e.preventDefault();// 点击页面时停止相机旋转,因为相机旋转的时候无法选中物体,这个问题没有解决,有点麻烦rotate = false;//将鼠标点击位置的屏幕坐标转成threejs中的标准坐标,具体解释见代码释义var mouse = {};mouse.x = (e.clientX / window.innerWidth) * 2 - 1;mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;//新建一个三维单位向量 假设z方向就是0.5//根据照相机,把这个向量转换到视点坐标系var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5).unproject(camera);var sub = vector.sub(camera.position);=var param2 = sub.normalize();var raycaster = new THREE.Raycaster(camera.position, param2);//射线和模型求交,选中一系列直线,getMeshs方法用于获得场景中可以被选中的所有Meshvar intersects = raycaster.intersectObjects(getMeshs());if (intersects.length > 0) {// outlineMesh是物体边框组件,每次只会有一个物体被选中,就把这个东西定义为全局的// 每次选中另一个物体之前先删除,相当于取消前一个物体的选中scene.remove(outlineMesh);//选中第一个射线相交的物体var SELECTED = intersects[0].object;var outlineMaterial2 = new THREE.MeshBasicMaterial({color: 0x00ff00, side: THREE.BackSide});outlineMesh = new THREE.Mesh(SELECTED.geometry.clone(), outlineMaterial2);outlineMesh.position.set(SELECTED.position.x, SELECTED.position.y, SELECTED.position.z);outlineMesh.scale.multiplyScalar(1.05);scene.add(outlineMesh);}
}

Threejs从入门到。。。。。。。还是入门相关推荐

  1. Python从入门到精通 - 入门篇 (下)

    上一讲回顾:Python从入门到精通 - 入门篇 (上) 接着上篇继续后面两个章节,函数和解析式. 4 函数 Python 里函数太重要了 (说的好像在别的语言中函数不重要似的).函数的通用好处就不用 ...

  2. python快速编程入门课后简答题答案-编程python入门 编程python入门课后习题

    编程python入门 编程python入门课后习题 米粒妈咪课堂小编整理了填空.选择.判断等一些课后习题答案,供大家参考学习. 第一章 一.填空题 Python是一种面向对象的高级语言. Python ...

  3. 半小时入门MATLAB编程入门基础知识:

    https://learnxinyminutes.com/docs/zh-cn/matlab-cn/ 半小时入门MATLAB编程入门基础知识: % 以百分号作为注释符 %{ 多行注释 可以 这样 表示 ...

  4. python编程入门指南-编程入门指南

    编程入门指南 ----------------------------------------------- 编程入门指南 v1.5 --- https://zhuanlan.zhihu.com/p/ ...

  5. flink入门_Flink从入门到放弃-入门篇

    大数据成神之路: 点我去成神之路系列目录^_^ Java高级特性增强-集合 Java高级特性增强-多线程 Java高级特性增强-Synchronized Java高级特性增强-volatile Jav ...

  6. Apache NIFI入门(读完即入门)

    Apache NIFI入门(读完即入门) 编辑人(全网同名):酷酷的诚 邮箱:zhangchengk@foxmail.com 我将在本文中介绍: 什么是ApacheNIFI,应在什么情况下使用它,理解 ...

  7. 推荐系统从入门到接着入门

    本文转载自:推荐系统从入门到接着入门-张小磊(北京交通大学 计算机科学与技术博士在读) 推荐系统从入门到接着入门 一.前言 二.简介 搜索引擎 推荐引擎 三.所属领域 四.会议介绍 五.推荐系统分类 ...

  8. 第一章 程序设计入门--算法竞赛入门经典

    第一章 程序设计入门–算法竞赛入门经典 知识点一: int m=25; printf("%d\n",m); printf("%03d\n",m); 输出如下: ...

  9. 【Python刷题篇】Python从0到入门3|循环、条件复习、元组入门、字典入门

    Python从0到入门3目录 前言 Q1:团队分组 Q2:禁止重复注册 Q3:元组-牛客运动会 Q4:字典-遍历字典 Q5:字典-毕业生就业调查 Q6:姓名与学号 总结 前言 - 本期是Python从 ...

  10. 基金投资入门教程-----基金入门

    基金投资入门教程-----基金入门 基金投资入门教程-----基金入门 1.基金入门 什么是基金 基金的三大优势 基金的风险 基金投资入门教程-----基金入门 1.基金入门 什么是基金 基金的三大优 ...

最新文章

  1. js获取网页高度(详细整理)
  2. MVC ---- EF的延迟加载
  3. Oracle会话及连接数优化
  4. 通用单向链表设计(三)——接口的测试
  5. Redis运维和开发学习笔记-全书思维导图
  6. java项目如何更改路径_Java修改eclipse中web项目的server部署路径问题
  7. npm 删除依赖包_npm 和 yarn 你选哪个?
  8. selenium_java
  9. linux系统如何更改输入法切换快捷键,linux中什么快捷键可实现中英文的切换
  10. 广州科二化龙考场_广州市机动车驾驶人化龙考场交通路线攻略
  11. uniapp——点击图片放大预览
  12. 【自动驾驶】RTK(高精度的GPS测量)
  13. 目标检测之RFB Net
  14. python pip中的Fatal error in launcher错误及解决
  15. Openwrt/Lede软路由设置为旁路由模式
  16. 全网变灰白,网站变黑白,网站首页变灰白,黑白
  17. 微信小程序能用php框架吗,WeiPhp框架在微信小程序后台开发的优势与使用方法
  18. c语言nba球星信息系统,NBA:超神控卫
  19. 求阶乘问题c语言编程,求阶乘问题
  20. hc05与单片机连接图_基于proteus的51单片机开发实例37-DAC0832

热门文章

  1. springboot+基于微信小程序的心理医生系统的设计实现 毕业设计-附源码191610
  2. 揭开木马的神秘面纱 1
  3. 数据库SQL Server基本认识
  4. 《印制电路板(PCB)设计技术与实践》这本书真烂!!
  5. 有啊网页诊断工具相关总结
  6. 计算机等级考 之 三级网络技术 理论知识 学习
  7. script引入方式
  8. 4个要点,解析MVP产品怎么做?
  9. “数据+算法”双轮驱动,自助分析平台助银行实现“智慧转型”
  10. 跑步打卡!(2023-4-9)