WebGL 从 Three.js 开始系列 之 Three.js的三个概念

1,963 阅读3分钟

Three.js的三个概念

three.js 是一个基于WebGl的库,也是用的最多的库。

如何使用呢? 我们只需要知道三个步骤即可。创建场景与摄像机,然后进行渲染三大步骤。

// 创建场景
const scene = new THREE.Scene();

// 创建摄像机 ,也就是我们的可视角度
const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
    );

// 创建渲染的方式,虽然刚刚学3D,你可以理解是工作区吧渲染场景
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

Scene

scene 场景是一个重要的概念,与Pixelmator Pro(类似PS的软件)的创建文档,然后我们可以在文档中添加图层,只不过我们添加的是3D模型。

camera

camera也是一个重要的概念,我为此还学了一点摄影的技巧。他相当与我们的可视角度,你可以理解为我们眼睛能看到的物品,也就是说你想给观众呈现出什么样的景色。可是近距离观看?远距离的广角?仰角?你的Scene很大,但你想用户看到Scene的那些部分呢,就得通过Camera告知给用户。

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e8b803e673554a3db54472efdcd90f82~tplv-k3u1fbpfcp-zoom-1.image

如果你是制造游戏开发,或者说为了想往VR电影开发「我指得是互交势的电影体检」。所以我学了一点拍摄手法与视频剪辑的技术,只是为了未来可以把这种想法融入到电影中,现在的VR电影只是看,但无法做到互交,如果6G的到来于HTTP3的技术,我想这个想法有想法,能落实。

载入3D模型

有了场景,摄像机这些概念后,最后我们想让用户看到什么物品。而这个物品就是我们的模型。模型可通过各种建模工具进行绘制,比如3D MAX,Unit,虚幻5等等。好像后面两个不是同一个东西吧,但好像他们也有建模的功能。俗语有专攻,这个我还真没有怎么研究过,主要是太难了。

这里官方推荐使用GLFT格式。

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

const loader = new GLTFLoader();

loader.load(
        "path",
        (gltf) => {
            model = gltf.scene;
            scene.add(model);
            renderer.render(scene, camera);
        },
        undefined,
        (err) => {
            console.log(err);
        }
    );

当然如果有更多的Loader,需要我们自己下载更多的加载器。不过据我遇到的情况来看,使用GLTF与RBS进行渲染的模型是相对的高清。

当我们load完成完成一个模型后,回得到相对应的模型信息。不同的loader器得到的模型信息不一样。例如我现在使用的GLTF格式,它的模型信息存放在scene里面。拿到这个模型后模块可以对模型进行一些操作与信息的编辑,如果你是做动画与游戏开发,建议模型自己使用一个集合进行管理。要不你只能做一些全景功能「市场做烂的功能」。

拿到信息后,我们需要对scene进行add,把scene,camera信息告诉WebGL进行渲染操作即可。

scene.add(model);
renderer.render(scene, camera);

注意事项:

我们使用模型的时候,有时候倒入模型的时候,模型是黑色的。

image.png 这可能是我们的模型信息导出的时候,信息缺失了。模型缺失光的信息。最简单的做法是给模型自动补光。

Scene.add(new THREE.AmbientLight(0x666666))

gltf.scene.traverse( function ( child ) {
	if ( child.isMesh ) {
			child.material.emissive =  child.material.color;
			child.material.emissiveMap = child.material.map ;
		}
	});

image.png

如果你感觉你的模型看起来不够高清,多半是没有开启antialias。

antialias - 是否执行抗锯齿。默认为false