ThreeJS学习笔记一:场景、相机、渲染器、光源


前言

在three中,场景、相机、渲染器是最核心的三个概念。我们通过相机拍摄场景,再通过渲染器把场景呈现在视图中。


一、Scene 场景

场景:放置物体灯光摄像机的地方。

我们把场景理解为我们现实生活中的空间,在三维世界中我们创建了一个空间,这个空间中什么也没有。我们需要放置物体来点缀我们的空间,也需要光源来照亮我们的空间。


二、Camera 相机

相机是用来拍摄我们想展示的三维空间的内容,在图形学中常用相机分两类:透视相机正交相机

  • 透视相机是有近大远小的效果,更符合我们人眼的感官视觉效果。
    在这里插入图片描述

  • 正交相机则没有近大远小的效果,一般用于制图类软件中,如CAD软件。
    在这里插入图片描述


三、WebGLRenderer 渲染器

渲染器则是决定使用什么方式渲染出想要的视图效果,他的入参就是相机和场景,渲染结果从本质上来讲就是一个canvas对象。渲染对象中包含设置canvas画布大小,canvas背景色等多种方法。


四、光源

1. 环境光

环境光是没有方向的光源,立方体的六个面都会受到光线的影响。如果我们只设置环境光,没有设置平行光,那么我们会发现物体还是没有棱角,这是因为物体的六个面都是一样的亮度。

2. 平行光

平行光可以想象为太阳光,太阳光从远处射向地球,因为太阳距离地球太远了,所以太阳光抵达地球时光线的夹角可以忽略不计,光线之间是平行的。当我们设置了平行光后,物体就有了棱角,这是因为物体经过太阳光的照射后产生了反射光,物体不同的面经过不同的入射角后反射的光线也不一致,就有了明暗的区别。


五、threeJS实现3D场景

1. 准备

// 安装项目
yarn create vite three-learn --template react
// 进入目录
cd three-learn
// 安装依赖
yarn
// 安装three,版本为0.136
yarn add three@0.136
// 运行项目
yarn dev

2. 第一个3D场景

我们先绘制出第一个3D场景,让大家更好的理解场景、相机和渲染器的工作流程。

import * as THREE from 'three';
import { useEffect } from 'react'
import './App.css'

const App=()=> {
  useEffect(() => {
    /** 创建场景 */
    const scene = new THREE.Scene();

    /** 相机设置 */
    const width = window.innerWidth; //窗口宽度
    const height = window.innerHeight; //窗口高度
    const k = width / height; //窗口宽高比
    const s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大

    //创建相机对象
    const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.set(400, 200, 300); //设置相机位置
    camera.lookAt(scene.position); //设置相机方向(指向的场景对象)

    /** 创建渲染器对象 */
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height); //设置渲染区域尺寸
    // renderer.setClearColor(0x888888, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

    renderer.render(scene, camera); //执行渲染操作
  }, [])
  return (
    <div className="App"></div>
  )
}

export default App

这样我们就创建了第一个3D场景,但是访问页面时我们会发现页面上漆黑一片,什么也没显示。这时我们就需要运用到场景了。
在这里插入图片描述

3. 第二个3D场景

import * as THREE from 'three';

/** 创建场景 */
const scene = new THREE.Scene();
// 创建一个立方缓冲几何体
const geometry = new THREE.BoxGeometry( 100, 100, 100 )
// 创建材质
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
// 生成带有材质的物体
const cube = new THREE.Mesh( geometry, material );
// 把物体添加进场景中
scene.add( cube );

/** 相机设置 */
const width = window.innerWidth; //窗口宽度
const height = window.innerHeight; //窗口高度
const k = width / height; //窗口宽高比
const s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(400, 200, 300); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)

/** 创建渲染器对象 */
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置渲染区域尺寸
// renderer.setClearColor(0x888888, 1); //设置背景颜色
document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

renderer.render(scene, camera); //执行渲染操作
 
  • 和第一个3D场景对比,我们添加了一个物体在场景中,这时就可以在视图中看到一个立方体,但是你会发现该立方体没有立体感,这是因为我们没有设置光源的原因。

  • 物体(mesh)是three中最重要的一个部分,就好比我们摄影,物体才是我们最终想拍摄并展现的,光源,相机的摆放等一切都是为了拍摄物体做的准备。当然,这些也决定了我们拍摄出来的效果是否满意。

  • 在three中,mesh由几何图形(BufferGeometry)和材质(material)组成,其中几何图形决定物体的形状,材质决定物体的外观。three内置了几种几何形状的类和常用的材质类,也可以自定义扩展,我们后续会细说。

  • 这时就可以看出物体拥有了立体感。

  • 我们在该段代码中添加了两种光源,环境光(AmbientLight)和平行光(DirectionalLight)

在这里插入图片描述

4. 第三个3D场景

import * as THREE from 'three';

/** 创建场景 */
const scene = new THREE.Scene();
// 创建一个立方缓冲几何体
const geometry = new THREE.BoxGeometry( 100, 100, 100 )
// 创建材质
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
// 生成带有材质的物体
const cube = new THREE.Mesh( geometry, material );
// 把物体添加进场景中
scene.add( cube );
// 创建光源
// 环境光,没有特定的方向
const ambientLight = new THREE.AmbientLight(0x444444)
scene.add(ambientLight)
// 平行光,类似于生活中的太阳光
const directionalLight = new THREE.DirectionalLight(0x00ff00, 1)
directionalLight.position.set(400, 200, 300)
scene.add(directionalLight)
/** 相机设置 */
const width = window.innerWidth; //窗口宽度
const height = window.innerHeight; //窗口高度
const k = width / height; //窗口宽高比
const s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(400, 200, 300); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)

/** 创建渲染器对象 */
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置渲染区域尺寸
// renderer.setClearColor(0x888888, 1); //设置背景颜色
document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

renderer.render(scene, camera); //执行渲染操作
 

和第二个3D场景相比,我们添加了光源。但是似乎和没有添加光源并没有区别,这里需要提到下材质(material)。我们在代码中使用的是MeshBasicMaterial材质,这种材质不受光照的影响。我们可以把该材质换成MeshLambertMaterial材质。(8行修改材质)

在这里插入图片描述

总结

本文主要记录了threeJS中场景、相机、渲染器、光源的基本概念,以及实现了一个简单的3D场景。下次再见

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

剑九 六千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值