【Threejs学习】材质灯光投影

一、光源分类

  1. 环境光(AmbientLight):会均匀的照亮场景中的所有物体。无方向,不能投射阴影。
  2. 平行光(DirectionalLight):沿特定方向散发的光,发出的光线都是平行的。例如太阳光,可投射阴影。
  3. 点光源(PointLight):从一个点向各个方向发散的光源。例如火柴、灯泡,可投射阴影。
  4. 聚光灯(SpotLight):光线从一个点沿一个方向射出,例如顶灯、手电筒,可投射阴影。
  5. ......

以下三种是常见光:

二、环境光 - AmbientLight

环境光: 会均匀的照亮场景中的所有物体,环境光不能用来投射阴影。

环境光结合其他常见的光和材质使用可以打造更真实立体的效果。

1.构造器

AmbientLight( color : Color, intensity : Float)

参数:颜色(默认0xffffff)、光照强度(默认为1,数值越大物体越亮)

2.代码示例

vue 复制代码
const light = new THREE.AmbientLight(0xffffff, 1) // 柔和的白光
scene.add(light)

三、点光源 - PointLight

点光源: 从一个点向各个方向发射的光源,例如火柴、灯泡,可以投射阴影。

1.构造器

PointLight( color : Color, intensity : Float, distance : Number, decay : Float )

参数:

  1. 颜色:默认0xffffff
  2. 光照强度:默认值为 1
  3. 光源照射的最大距离:默认值为 0(无限远)
  4. 沿着光照距离的衰退量:默认值为 2

属性:

  1. castShadow:此属性设置为 true 灯光将投射阴影。需要通过调整让阴影看起来正确。
  2. ......

2.代码示例

vue 复制代码
const pointLight = new THREE.PointLight(0xffffff, 100, 100)
pointLight.position.set(5, 3, 5)
// 让灯光投射阴影
pointLight.castShadow = true
scene.add(pointLight)

四、材质、灯光(环境光+点光源) 阴影效果示例

1.效果图:

2.实现步骤:


  1. 设置阴影:
    1. 让物体能够接收光源,呈现阴影效果: cube.castShadow = true
    2. 开启灯光投射阴影: pointLight.castShadow = true
    3. 地面要设置可接收光源: meshFloor.receiveShadow = true
    4. 设置渲染器开启阴影贴图: renderer.shadowMap.enabled = true

3.完整代码:

vue 复制代码
<template>
  <div id="container" ref="threeRef" class="w-100% h-100%"></div>
</template>

<script setup>
// 引入three.js
import * as THREE from 'three'
// 引入轨道控制器
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { onMounted, ref, reactive } from 'vue'

let threeRef = ref(null)
const datGuiRef = ref(null)

// 1.创建场景,并添加背景颜色(灰色)
const scene = new THREE.Scene()
scene.background = new THREE.Color(0x666666)

// 2.创建相机
const camera = new THREE.PerspectiveCamera()
camera.position.y = 3
camera.position.z = 10

// 3.1创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1)

// 3.2创建材质:选择能够与灯光产生反应的材质-漫反射材质、高光反射材质
const material = new THREE.MeshPhongMaterial({
  color: 0x0099ff, // 蓝色
  shininess: 1000, // 默认是30
})
// 3.3创建网格,连接物体和材质
const cube = new THREE.Mesh(geometry, material)
cube.position.set(0, 0.5, 0)
scene.add(cube)
  
// 6.1 让物体投射光源
cube.castShadow = true

// 4.创建地面几何体:屏幕缓冲几何体
const meshFloor = new THREE.Mesh(
  new THREE.PlaneGeometry(10, 10),
  new THREE.MeshLambertMaterial({
    color: 0x1b5e20,
    side: THREE.DoubleSide,
  })
)
// 当前位置旋转90度
meshFloor.rotation.x = -Math.PI / 2
scene.add(meshFloor)
// 6.3 地面同样要设置接受光源
meshFloor.receiveShadow = true
  
// 5.添加灯光效果:
// 5.1添加环境光-AmbientLight
const light = new THREE.AmbientLight(0xffffff, 1) // 柔和的白光
scene.add(light)

// 5.2添加点光源-PointLight
const pointLight = new THREE.PointLight(0xffffff, 100, 100)
pointLight.position.set(5, 3, 5)
// 6.2让灯光投射阴影
pointLight.castShadow = true
scene.add(pointLight)

// 添加坐标轴
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)

onMounted(() => {
  // 创建渲染器
  const renderer = new THREE.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  // 6.4 让渲染器渲染灯光效果
  renderer.shadowMap.enabled = true
  // 将渲染器添加到页面中
  document.getElementById('container').appendChild(renderer.domElement)
  // 添加轨道控制器
  const controls = new OrbitControls(camera, renderer.domElement)

  function animate() {
    //循环调用: 切换到其他页面时会暂停
    requestAnimationFrame(animate)
    // 调用轨道控制器的更新方法
    controls.update()
    //渲染
    renderer.render(scene, camera)
  }
  animate()
})
</script>
相关推荐
CV实验室31 分钟前
TIP 2025 | 哈工大&哈佛等提出 TripleMixer:攻克雨雪雾干扰的3D点云去噪网络!
人工智能·计算机视觉·3d·论文
哆啦A梦15882 小时前
搜索页面布局
前端·vue.js·node.js
_院长大人_2 小时前
el-table-column show-overflow-tooltip 只能显示纯文本,无法渲染 <p> 标签
前端·javascript·vue.js
Main. 242 小时前
从0到1学习Qt -- 创建第一个Hello World项目
学习
壹号用户3 小时前
python学习之生成器&三者关系
学习
new coder3 小时前
[c++语法学习]Day10:c++引用
开发语言·c++·学习
星域智链3 小时前
宠物智能用品:当毛孩子遇上 AI,是便利还是过度?
人工智能·科技·学习·宠物
哆啦A梦15883 小时前
axios 的二次封装
前端·vue.js·node.js
小Tomkk3 小时前
Rokid 开发空间小程序 实战
3d·小程序·rokid·jsar
阿珊和她的猫3 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式