前言
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. 浏览器路径: 

浏览器启动参数,因为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 = , ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = ;
camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
scene.add(camera);
camera.position.set(, , );
cameraRadius = Math.sqrt(camera.position.x * camera.position.x + camera.position.z * camera.position.z);
camera.up.set(, , );
camera.lookAt(new THREE.Vector3(, , ));

关于相机比较难理解的是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});
else
renderer = 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(, );
// 将材质包装成表面材料,设置正反两面都要铺上
var floorMaterial = new THREE.MeshBasicMaterial({map: floorTexture, side: THREE.DoubleSide});
// 平面对象
var floorGeometry = new THREE.PlaneGeometry(, , , );
// 把对象和材料包装成Mesh
floor = new THREE.Mesh(floorGeometry, floorMaterial);
// 设置位置放入场景啦
floor.position.y = -0.5;
floor.rotation.x = Math.PI / ;
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) * - ;
mouse.y = -(e.clientY / window.innerHeight) * + ;
//新建一个三维单位向量 假设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方法用于获得场景中可以被选中的所有Mesh
var intersects = raycaster.intersectObjects(getMeshs()); if (intersects.length > ) {
// outlineMesh是物体边框组件,每次只会有一个物体被选中,就把这个东西定义为全局的
// 每次选中另一个物体之前先删除,相当于取消前一个物体的选中
scene.remove(outlineMesh);
//选中第一个射线相交的物体
var SELECTED = intersects[].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. babel从入门到入门

    babel从入门到入门 来源 http://www.cnblogs.com/gg1234/p/7168750.html 博客讲解内容如下: 1.babel是什么 2.javascript制作规范 3. ...

  2. Android视频录制从不入门到入门系列教程(一)————简介

    一.WHY Android SDK提供了MediaRecorder帮助开发者进行视频的录制,不过这个类很鸡肋,实际项目中应该很少用到它,最大的原因我觉得莫过于其输出的视频分辨率太有限了,满足不了项目的 ...

  3. Android视频录制从不入门到入门系列教程(三)————视频方向

    运行Android视频录制从不入门到入门系列教程(二)————显示视频图像中的Demo后,我们应该能发现视频的方向是错误的. 由于Android中,Camera给我们的视频图片的原始方向是下图这个样子 ...

  4. springboot + kafka 入门实例 入门demo

    springboot + kafka 入门实例 入门demo 版本说明 springboot版本:2.3.3.RELEASE kakfa服务端版本:kafka_2.12-2.6.0.tgz zooke ...

  5. springboot + mybatisPlus 入门实例 入门demo

    springboot + mybatisPlus 入门实例 入门demo 使用mybatisPlus的优势 集成mybatisplus后,简单的CRUD就不用写了,如果没有特别的sql,就可以不用ma ...

  6. spring入门--spring入门案例

    spring是一个框架,这个框架可以干很多很多的事情.感觉特别吊.但是,对于初学者来说,很难理解spring到底是干什么的.我刚开始的时候也不懂,后来就跟着敲,在后来虽然懂了,但是依然说不明白它到底是 ...

  7. 《图说VR入门》——入门汇总

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/53818922 作者:car ...

  8. 09Vue.js快速入门-Vue入门之Vuex实战

    9.1. 引言 Vue组件化做的确实非常彻底,它独有的vue单文件组件也是做的非常有特色.组件化的同时带来的是:组件之间的数据共享和通信的难题. 尤其Vue组件设计的就是,父组件通过子组件的prop进 ...

  9. Python该怎么入门?Python入门教程(非常详细)

    Python要学多久可以学会,达到精通呢? 任何知识都是基础入门比较快,达到通晓的程序是需求时日的,这是一个逐渐激烈的进程. 通晓任何一门编程语言,都需求通过大量的实践来积累经验,解决遇到的各种疑难问 ...

随机推荐

  1. Springboot使用Undertow

    Springboot使用Undertow Undertow 是红帽公司开发的一款基于 NIO 的高性能 Web 嵌入式服务器 Undertow的特点: 轻量级:它是一个 Web 服务器,但不像传统的 ...

  2. Symantec NBU :Unable to retrieve version of the server xxx.xxx.xxx

    Symantec NetBackup  是赛门铁克收购的veritas公司的一款产品,该产品功能强大,据称堪称备份界的鼻祖. 其具体原理和备份方式可见:https://blog.51cto.com/s ...

  3. hdu1253胜利大逃亡(城堡的怪物太狠,主角难免天天逃亡)

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1253/ 其实就是二维扩展到三维了,增加了搜索方向,其他的没什么不同. 代码如下: #include<bit ...

  4. 手把手教你用java实现syslog消息的收发,学不会你打我喽!

    大家好,我是道哥,专注于后端java开发,喜欢写作和分享.如果觉得文章对你有用,那就点个赞呗!如果能转发那是对道哥最大的支持! syslog的定义 见文知义,syslog,从英文名字上可以看出是指系统 ...

  5. upload-labs学习笔记

    项目地址:https://github.com/c0ny1/upload-labs   运行环境 操作系统:windows.Linux php版本:推荐5.2.17(其他版本可能会导致部分Pass无法 ...

  6. 图片OCR(Optical Character Recognition)

    目录 Photo OCR问题描述 滑动窗口(Sliding Windows) 获得大量数据和人工数据(Getting Logs of Data and Artificial Data) 瓶颈分析:需要 ...

  7. Building Applications with Force.com and VisualForce (DEV401) (二十):Visualforce Pages: Visualforce Componets (Tags)

    Dev401-021:Visualforce Pages: Visualforce Componets (Tags) Module Agenda1.Tag Basics2.Tag Bindings T ...

  8. 使用 NLTK 对文本进行清洗,索引工具

    使用 NLTK 对文本进行清洗,索引工具 EN_WHITELIST = '0123456789abcdefghijklmnopqrstuvwxyz ' # space is included in w ...

  9. 推荐 | 7个你最应该知道的机器学习相关github项目

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 磐石 目录: 介绍 Person Blocker(人体自动遮挡) ...

  10. liunx 上安装redis

    目录 1.安装包 2.解压:tar xzf redis-5.0.5.tar.gz 3.安装 4.编辑redis.conf文件 5.配置密码 6.启动配置: 7.配置公网链接 8.杀掉redis进程 9 ...