草庐IT

记录--Three.js入门教程——教不会算我输

林恒 2023-03-28 原文

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

在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入门教程——教不会算我输的更多相关文章

  1. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. Ruby 元类 : why three when defined singleton methods? - 2

    让我们计算MRI范围内的类别:defcount_classesObjectSpace.count_objects[:T_CLASS]endk=count_classes用类方法定义类:classAdefself.foonilendend然后运行:putscount_classes-k#=>3请解释一下,为什么是三个? 最佳答案 查看MRI代码,每次你创建一个Class时,在Ruby中它是Class类型的对象,ruby会自动为这个新类创建“元类”类,这是另一个单例类型的Class对象。C函数调用(class.c)是:rb_define

  4. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  5. ruby-on-rails - Rails 5 Active Record 记录无效错误 - 2

    我有两个Rails模型,即Invoice和Invoice_details。一个Invoice_details属于Invoice,一个Invoice有多个Invoice_details。我无法使用accepts_nested_attributes_forinInvoice通过Invoice模型保存Invoice_details。我收到以下错误:(0.2ms)BEGIN(0.2ms)ROLLBACKCompleted422UnprocessableEntityin25ms(ActiveRecord:4.0ms)ActiveRecord::RecordInvalid(Validationfa

  6. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  7. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  8. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  9. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  10. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

随机推荐