ThreeJS入门(一)初始化THREE工作环境
本帖最后由 马黑黑 于 2025-5-22 13:19 编辑 <br /><br /><style>.artBox { font-size: 18px; }
.artBox > p { margin: 10px 0; }
</style>
<div class="artBox">
<p>使用 ThreeJS 绘制3d图形,需要先引用 three.js 核心库,使用 ES6 模块的话可以用 import 导入该库,一句代码的事情,但应保证库文件的来源可靠:</p>
<div class="hEdiv"><pre class="hEpre">
import * as THREE from 'https://esm.sh/three';
// import * as THREE from 'https://unpkg.ihwx.cn/three@0.176.0/build/three.module.js'; // 备选
</pre></div>
<p>接着就是简单三步就可以搭建出 ThreeJS 的工作环境:</p>
<h2>第一步:搭建场景</h2>
<p>场景叫 Scene,ThreeJS 将其封装为 THREE.Scene 对象,实例化该对象即可:
<div class="hEdiv"><pre class="hEpre">var scene = new THREE.Scene;</pre></div>
<h2>第二步:架设摄像机</h2>
<p>摄像机(后续统统叫相机)叫 Camera,ThreeJS 封装有多种,最常用到的是 THREE.PerspectiveCamera 即正投相机,和普通的相机差不多。相机对象在实例化时一般要设置四个参数,一般都像这样:</p>
<div class="hEdiv"><pre class="hEpre">var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);</pre></div>
<p>第一个参数 fov - 相机视锥体垂直视野角度,其值对最终图像的大小有影响;第二个参数 aspect - 摄像机视锥体长宽比,一般都是场景父元素的宽高比(后面有进一步说明);第三个参数 near - 摄像机视锥体近端面,一般取较小的浮点数;第四个参数 far - 摄像机视锥体远端面,一般取值 1000。这些参数都可以缺省,不过拍出的效果如何就难说了,所以,就像使用手机拍照一样,拿来就拍和设置好各种参数再拍效果总是有区别的。</p>
<p>相机要在Z轴上与场景拉开距离,同时还应该把镜头对准场景特定的地方。这些设置可以稍后再做,也可以直接跟在实例化摄像机之后做,还可以在动画等后续运行环境中动态改变:
<div class="hEdiv"><pre class="hEpre">
camera.position.set(0, 0, 5);
camera.lookAt(0, 0, 0);
</pre></div>
<p>相机的位置(position)XY轴都设为 0(中心),Z轴是正向的 5(5个距离单位);相机“看”(lookAt)的地方都设在XYZ轴上的中心0(0个距离单位),相当于聚焦在三维场景 Scene 的正中心。</p>
<h2>第三步:实现拍摄</h2>
<p>就是实例化 ThreeJS 的渲染器对象,即为 THREE.Renderer,renderer 是渲染器之意,它提供有渲染方法 render() 和设置渲染范围 setSize(),前者相当于相机的快门按钮、后者可以理解后相机的取景范围。渲染器可以配置一些 options 参数,即花括号包裹的键值对,例如开启反锯齿和 alpha 通道,{ antialias: true, alpha: true },一切根据需要配置。渲染器还要设置渲染范围:</p>
<div class="hEdiv"><pre class="hEpre">
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
</pre></div>
<p>这里,我们第二次看到 window.innerWidth、window.innerHeight,得说明一下了:这是JS的东东,window 是视窗,两个单词的意思就是视窗的内部宽度、高度。这个渲染范围设置意味着将整个场景XY二维面作为渲染器的宽高范围。</p>
<p>最后,渲染器要作为一个 dom 元素(标签)加入到场景的父元素,可以是 body 标签,也可以是某个 div 元素(当为 div 元素时,视窗的宽高通常对应替换为 div 的宽高):</p>
<div class="hEdiv"><pre class="hEpre">document.body.appendChild(renderer.domElement);</pre></div>
<p>renderer.domElement 实际上是渲染器所寄生的元素,一个 JS canvas画布 —— ThreeJS就是在 canvas 画布上使用 WebGL 或 WebGPU 技术作画。</p>
<p>以下是 ThreeJS 初始化工作环境的参考代码:</p>
<div class="hEdiv"><pre class="hEpre">
<script type="module">
import * as THREE from 'https://esm.sh/three';
var scene = new THREE.Scene;
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 5);
camera.lookAt(0, 0, 0);
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
</script>
</pre></div>
<p>当然,这只是准备工作,运行上面的代码只看到一片空白。</p>
</div>
<script type="module">
import hlight from 'https://638183.freep.cn/638183/web/helight/helight1.js';
const pres = document.querySelectorAll('.hEpre');
const divs = document.querySelectorAll('.hEdiv');
divs.forEach( (div, key) => hlight.hl(div, pres));
</script> 这个章节的讲解特别好,前面一直在用,却都是糊里糊涂的,这个把工作环境相关的内容讲得特别详细{:4_199:} “第一个参数 fov - 相机视锥体垂直视野角度”
摄像机设置里的第一个参数一直不知道是什么,现在知道了。太好了{:4_187:} 这个渲染器可以加入到父元素或某个 div 元素中呢,嗯,这篇讲解太好了,深入浅出,讲得特别清楚明白{:4_199:} 我虽然不懂,但还是要支持老师一下。辛苦了! 举重若轻,提纲挈领,深入浅出,跟着马老师好好学习、天天向上,马老师辛苦了{:4_191:} 杨帆 发表于 2025-5-22 14:45
举重若轻,提纲挈领,深入浅出,跟着马老师好好学习、天天向上,马老师辛苦了
{:4_190:} innerWidth, window.innerHeight
这个宽高不需要对应的值么。。还是默认的大小 camera.position.set(0, 0, 5);
camera.lookAt(0, 0, 0);
第一行相机位置每个贴子里都能看到,第二行是新的这个教程才看到。。{:4_173:}或者又是我之前错过了 ThreeJS入门教程开讲了。。得喝一杯庆祝一下{:4_173:} 花飞飞 发表于 2025-5-22 20:16
ThreeJS入门教程开讲了。。得喝一杯庆祝一下
{:4_191:} 花飞飞 发表于 2025-5-22 20:16
camera.position.set(0, 0, 5);
camera.lookAt(0, 0, 0);
第一行相机位置每个贴子里都能看到,第二行是新 ...
这本身是默认的。如果没有动态变化,或者,如果相机的 xy 方向都是0,则它设置与否都无所谓。 花飞飞 发表于 2025-5-22 20:13
innerWidth, window.innerHeight
这个宽高不需要对应的值么。。还是默认的大小
就是视窗的宽、高,这是JS内置的东东 马黑黑 发表于 2025-5-22 20:24
爽快。。喝得开心不{:4_173:} 马黑黑 发表于 2025-5-22 20:25
这本身是默认的。如果没有动态变化,或者,如果相机的 xy 方向都是0,则它设置与否都无所谓。
{:4_173:}好哒,都0就是默认,这个位置是最好的
虽然现在还面生,等慢慢学了教程会熟起来的吧 花飞飞 发表于 2025-5-22 20:31
好哒,都0就是默认,这个位置是最好的
虽然现在还面生,等慢慢学了教程会熟起来的吧
其实可以改一改,某个数据不是0,会有不同的结果 花飞飞 发表于 2025-5-22 20:30
爽快。。喝得开心不
还行 马黑黑 发表于 2025-5-22 20:25
就是视窗的宽、高,这是JS内置的东东
感觉应是封在包包里看不到的。。{:4_173:}
这个JS封得好高级。
备选和首选差别在 哪里,是不一样的存在空间对不? 马黑黑 发表于 2025-5-22 20:33
其实可以改一改,某个数据不是0,会有不同的结果
这两天可改它了。。
{:4_173:}又要比例正确,看上去正圆,又要位置合适。。
花飞飞 发表于 2025-5-22 20:33
感觉应是封在包包里看不到的。。
这个JS封得好高级。
备选和首选差别在 哪里,是不一样的存在 ...
JS有很多内置的东东,比如这里说的 window.innerWidth、window.innerHeight,应有尽有。这就是 JS 的厉害,也是 JS 难学的原因之一。