【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>
相关推荐
我要洋人死24 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人35 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人36 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR41 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香43 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
数据与后端架构提升之路1 小时前
从神经元到神经网络:深度学习的进化之旅
人工智能·神经网络·学习
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
一行11 小时前
电脑蓝屏debug学习
学习·电脑
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js