记录--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 ...
随机推荐
- HWS山大专区PWN双一血 & CRYPTO-WP
2023.11.18 两天半的比赛,就打了半天(因为要赶去打香山杯决赛了),不过结果还算好,人生第一次拿了两个一血hhh.写wp的时候人在中大南校北门的酒店里:) controller 格式化字符串泄 ...
- OpenStack调度器
计算使用 nova-scheduler 服务来确定如何调度计算请求 默认配置中,调度程序会考虑以下所有条件的主机: 位于请求的可用区 (map_az_to_placement_aggregate) 放 ...
- Oracle本地管理对比数据字典管理表空间
Locally vs. Dictionary Managed Tablespaces 整理自:http://www.orafaq.com/node/3. When Oracleallocates sp ...
- Android里使用AspectJ实现双击自定义注解
创建注解 首先创建一个双击注解. import java.lang.annotation.ElementType; import java.lang.annotation.Retention; imp ...
- win32-UpdateLayeredWindow
创建半透明的窗口,以及在窗口上绘制不透明的文本 方法: 创建Bitmap具有PixelFormat32bppPARGB像素格式的GDI + 对象. 创建一个Graphics对象以绘制该Bitmap对象 ...
- VS Code实现SSH远程开发
最近收获一台新台式机,但是个人主要还是使用自己的笔记本,用了几天远程控制,感觉各种不方便,最终决定配置一下VS Code实现SSH远程开发,特此记录. 首先介绍一下环境,控制端是Windows 11, ...
- queryset高级用法:select_related
在提取某个模型的数据的同时,也提前将相关联的数据提取出来.比如提取文章数据,可以使用select_related将author信息提取出来,以后再次使用article.author的时候就不需要再次去 ...
- MySQL基础3-数据库增删改操作
一.SQL通用语法 SQL 语法可以单行或者多行书写,以分号结尾. SQL 语句可以使用空格/缩进来增强语句的可读性. MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写. 注释: 单 ...
- 【Azure 环境】 介绍两种常规的方法来监视Window系统的CPU高时的进程信息: Performance Monitor 和 Powershell Get-Counter
问题描述 部署在Azure上的VM资源,偶尔CPU飙高,但是发现的时候已经恢复,无法判断当时High CPU原因. 在Windows系统中,有什么方式能记录CPU被进程占用情况,查找出当时是排名前列的 ...
- Hugo 建站经验之谈
前言 建站工具,早已不是一个新颖的话题,抛开可视化建站单论开发层面,各类语言都有推出广受欢迎的建站框架,比如 Python 开发的 Pelican,JavaScript 开发的 Hexo,以及市场份额 ...