记录--Three.js入门教程——教不会算我输
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

在javascript中使用Three.js设计并且实现3D场景是一个很有意思的事情,因为在浏览器中就能够渲染出3D场景,非常简单和轻便。接下来就总结以下我学习Three.js过程中的心得。
1 建立基本场景
在Three.js中有三要素:场景、摄像机和渲染器,只有以上三者结合才能渲染出可见的内容。当然在这之前你需要先下载Three.js文件,直接百度搜索Three.js到官网下载即可,下载完成之后新建一个html文件并且引入Three.js即可。一个最基本的使用Three.js的html文件应该是这样子的:
<!DOCTYPE html>
<html>
<head>
<title>Wonanut 3D</title>
<style type="text/css">
body { margin: 0; }
canvas { width: 100%; height: 100%; }
</style>
</head>
<body>
<script type="text/javascript" src="js/three.js"></script>
<script type="text/javascript">
// 场景
var scene = new THREE.Scene(); // 摄像机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5; // 渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// 渲染器 end // 物体
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00} );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
// 物体 end </script>
</body>
</html>
我们打开浏览器看一下:

哦天哪,发生了什么,浏览器上黑乎乎一片什么都没有啊。
别急,这是因为我们只是设置了三要素,但并没有渲染,只有使用渲染器scene和camera进行渲染之后才能看到内容,在scene.add( cube ); 后面添加一句:
renderer.render(scene, camera);
再试试效果如何:

快看,现在屏幕中出现了一个正方形,这正是我们所期待的!
但是,我们使用的Three.js不应该是三维场景吗,为什么现在只有平面效果?不急,接下来我们使用requestAnimationFrame让画面动起来!
2 让画面动起来
将上一步中最后一句代码:
renderer.render(scene, camera);
替换为:
// 动画
function animate() { cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera ); requestAnimationFrame( animate );
}
animate();
再到浏览器看看效果,如果没有什么问题的话,现在你所看到的画面应该是一个旋转的立方体:

不过我对这个效果还是不满意,它看起来像是一个 正方体,但缺少了阴影灯光效果,接下来我们添加灯光效果。
3 添加光效
使用点光源THREE.SpotLight,代码如下:
// 光源
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( -40, 60, -10 );
scene.add( spotLight );
// 光源 end
同时将cube的材质从MeshBasicMaterial换为MeshLamberMaterial,因为最基本的MeshBasicMaterial材质对光源不会有任何反应。
// 物体
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshLambertMaterial( { color: 0x00ff00} );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
// 物体 end

4 添加阴影效果
为了渲染阴影效果,需要对代码做如下修改:
renderer.setClearColor(new THREE.Color(0x000000, 1.0));
renderer.shadowMap.enabled = true;
同时要给立方体设置投射阴影:
cube.castShadow = true;
设置地面接受阴影:
plane.receiveShadow = true;
设置spotLight投射阴影:
spotLight.castShadow = true;
为了添加阴影效果,我们需要设置一个平面来接受阴影,因此重新创建一个场景,源码如下:
<!DOCTYPE html>
<html>
<head>
<title>Wonanut 3D</title>
<style type="text/css">
body { margin: 0; }
canvas { width: 100%; height: 100%; }
</style>
</head>
<body>
<script type="text/javascript" src="js/three.js"></script>
<script type="text/javascript" src="js/stats.js"></script>
<script type="text/javascript">
场景-----------------------
var scene = new THREE.Scene();
-------------------------- 摄像机---------------------
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30
camera.lookAt(scene.position);
-------------------------- 渲染器--------------------
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement ); // 设置渲染器渲染阴影效果
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
渲染器 end---------------- 坐标轴--------------------
var axes = new THREE.AxesHelper(20);
scene.add(axes);
------------------------- 平面---------------------
var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xcccccc});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 15
plane.position.y = 0
plane.position.z = 0
scene.add(plane); // 设置投影
plane.receiveShadow = true;
-------------------------- 物体----------------------
var geometry = new THREE.BoxGeometry(4, 4, 4);
var material = new THREE.MeshLambertMaterial( { color: 0x00ff00} );
var cube = new THREE.Mesh( geometry, material );
cube.position.x = 0;
cube.position.y = 2;
cube.position.z = 0; // 设置投影
cube.castShadow = true;
scene.add( cube );
物体 end ------------------ 光源-----------------------
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( -40, 60, -10 );
scene.add( spotLight ); // 设置投影
spotLight.castShadow = true;
光源 end ------------------- 状态监视器-------------------
var stats = new Stats();
stats.showPanel( 0 );
document.body.appendChild( stats.dom );
状态监视器 end -------------- renderer.render( scene, camera ); </script>
</body>
</html>
渲染结果如下图:

阴影是有了,但总觉得阴影不太对劲,比较模糊。通过查阅资料,我找到了答案:
光源的位置一定要距离合适,否则容易引起阴影模糊粗糙的像打马赛克一样
所以嘛,这个东西还是要自己去调的(其实具体原因我也不清楚,反正我没调好)
本文转载于:
https://blog.csdn.net/qq_26822029/article/details/91353209
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--Three.js入门教程——教不会算我输的更多相关文章
- D3.js 入门教程
最近需要用到d3, 记录下d3的教程 网上搜了几个关于d3的教程 D3.js 入门教程 http://wiki.jikexueyuan.com/project/d3wiki/author.h ...
- Ember.js入门教程、博文汇总
第一章 对象模型 Ember.js 入门指南——类的定义.初始化.继承 Ember.js 入门指南——类的扩展(reopen) Ember.js 入门指南——计算属性(compute properti ...
- 【特别推荐】Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- Vue.js 入门教程
Vue.js 入门教程:https://cn.vuejs.org/v2/guide/index.html
- 网页3D引擎“Babylon.JS”入门教程翻译总结
使用三个月的业余时间把官方教程的入门部分译为中文并上传到github,在下一步编程前做一个总结. 历程: 最早接触游戏编程是在大三下学期,用汇编语言和实验室里的单片机.触摸屏.电机(提供声效)编的打地 ...
- Backbone.js入门教程
原文: Getting Started with Backbone.js 不像其它的Web开发语言,过去Javascript很少可用的架构.令人感到高兴的是,最近几年这种情况得到非常大的改善. 今天我 ...
- node.js 入门教程(beginnder guide
非常好的教程: node入门: JavaScript与Node.js JavaScript与你 简短申明 服务器端JavaScript “Hello World” 一个完整的基于Node.js的web ...
- 前端框架React Js入门教程【精】
现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...
- [转]Vue.js 入门教程
本文转自:http://www.runoob.com/w3cnote/vue-js-quickstart.html 什么是 Vue.js? Vue.js 是用于构建交互式的 Web 界面的库. Vu ...
随机推荐
- 【译】.NET 8 网络改进(三)
原文 | Máňa,Natalia Kondratyeva 翻译 | 郑子铭 简化的 SocketsHttpHandler 配置 .NET 8 添加了更方便.更流畅的方式来使用 SocketsHttp ...
- cached地址和uncached地址的区别
cached地址和uncached地址的区别是 对cached地址的访问是委托给CPU进行的,也就是说你的操作到底是提交给真正的外设或内存,还是转到CPU缓存,是由CPU决定的.CPU有一套缓存策略来 ...
- SSD 简介—— NAND 芯片介绍
制作 存储芯片的制作和其他芯片制作大致相同,从沙子中提取单晶硅制作晶圆再封装芯片. 闪存芯片从架构上分为NOR和NAND NOR Flash的source line把每个cell都并联起来,而NAND ...
- Vdbench 使用说明
一. vdbench简介 vdbench是一个 I/O 工作负载生成器,用于验证数据完整性和度量直接附加和网络连接的存储的性能.它是一个免费的工具,容易使用,而且常常用于测试和基准测试. 可以使用vd ...
- 轻松玩转makefile | 函数的使用
前言 在上一篇文章中,尽管使用了变量和模式,但还是有不够好的地方,在Makefile中要指明每一个源文件,我们接下来利用函数对其进行优化,并介绍其他常用的一些函数. 依旧是以fun.c ,main.c ...
- Js模块化导入导出
Js模块化导入导出 CommonJs.AMD.CMD.ES6都是用于模块化定义中使用的规范,其为了规范化模块的引入与处理模块之间的依赖关系以及解决命名冲突问题,并使用模块化方案来使复杂系统分解为代码结 ...
- Eclipse文本编码格式修改为UTF-8 的方法
整理自网络,亲测可用,记录一下,方便下次查. 一般Java文件编码格式是UTF-8的.以下以默认GBK改为UTF-8为例. 1.改变整个工作空间的编码格式,这样以后新建的文件也是新设置的编码格式. e ...
- ORACLE查询优化及gather_plan_statistics hint
查询优化手段和gather_plan_statistics hint: 在10g以后我们可以通过利用gather_plan_statistics提示来了解更多的SQL执行统计信息,具体使用方法如下: ...
- WriteFile 奇怪的现象
项目中有个需求是要对文本内容检索并重写,我们使用的是 WriteFile 覆盖旧的文本内容 最小示例: #include <Windows.h> #include <iostream ...
- [WEB安全] CSRF攻击和防御
一.什么是CSRF 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或 ...