【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>
相关推荐
Komorebi.py1 小时前
【Linux】-学习笔记05
linux·笔记·学习
Mr_Xuhhh1 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
永乐春秋2 小时前
WEB攻防-通用漏洞&文件上传&js验证&mime&user.ini&语言特性
前端
鸽鸽程序猿2 小时前
【前端】CSS
前端·css
ggdpzhk2 小时前
VUE:基于MVVN的前端js框架
前端·javascript·vue.js
学不会•4 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜6 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点6 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow6 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o6 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app