WEB 3D技术 three.js 聚光灯

本文 我们来说说 点光源和聚光灯

点光源 就像一个电灯泡一样 想四周发散光
而聚光灯就像手电筒一样 像一个方向射过去 距离越远范围越大 光越弱

我们先来看一个聚光灯的效果
我们可以编写代码如下

import './style.css'
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

// 创建相机
const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
);
const scene = new THREE.Scene();

// 环境光
const light = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(light);

// 聚光灯光源
const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.position.set(0, 2, 1);
spotlight.castShadow = true;
scene.add(spotlight);

// 创建球形几何体
const sphere1 = new THREE.Mesh(
  new THREE.SphereGeometry(0.7, 32, 32),
  new THREE.MeshStandardMaterial({})
);
sphere1.castShadow = true;
sphere1.receiveShadow = true;
scene.add(sphere1);

// 添加平面
const plane = new THREE.Mesh(
  new THREE.PlaneGeometry(3, 3),
  new THREE.MeshStandardMaterial({ color: 0xeeeeee })
);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add(plane);

// 创建一个canvas容器并追加到body上
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);

// 设置相机位置
camera.position.z = 5;
camera.lookAt(0, 0, 0);

// 添加控制器
const controls = new OrbitControls(camera, renderer.domElement);

function animate() {
    controls.update();
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();

SpotLight 聚光灯
然后通过 position 设置一下光的位置
运行代码如下
在这里插入图片描述
目前看 我们光是从直线照过来的 但其实 我们可以不通过position去算位置
可以直接通过 target 告诉它我们灯的目标是谁
我们将代码改成这样

// 环境光
const light = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(light);

// 创建球形几何体
const sphere1 = new THREE.Mesh(
  new THREE.SphereGeometry(0.7, 32, 32),
  new THREE.MeshStandardMaterial({})
);
sphere1.castShadow = true;
sphere1.receiveShadow = true;
scene.add(sphere1);

// 聚光灯光源
const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.castShadow = true;
spotlight.target = sphere1;
scene.add(spotlight);

这里 我们直接不设置它的position了 直接让他打在我们 sphere1这个球体上了
在这里插入图片描述
angle 可以调整它的角度
在这里插入图片描述
我们调成这样

const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.position.set(1, 2, 0.5);
spotlight.castShadow = true;
scene.add(spotlight);

在这里插入图片描述
然后 我们修改一下角度

const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.position.set(1, 0, 2);
spotlight.castShadow = true;
spotlight.angle = Math.PI / 6;
scene.add(spotlight);

在这里插入图片描述
我们将他改成 1
在这里插入图片描述
大概效果就是这样
在这里插入图片描述
值越小 它聚焦的范围就越小

distance 设置光照距离 简单说 就是 设置你这个光 它能设多远
聚光灯的话 光照范围会越远越扩大 但聚焦越来越弱光照变弱 那么 就是在你设置的距离中 沿途不断扩大范围光强度慢慢变弱 直到到了你的指定位置 完全消失
在这里插入图片描述

例如 我们这里这样写

const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.position.set(1, 0, 2);
spotlight.castShadow = true;
spotlight.angle = 1;
spotlight.distance = 3;
scene.add(spotlight);

它的光照距离就只能到3
在这里插入图片描述
我们改 两百

const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.position.set(1, 0, 2);
spotlight.castShadow = true;
spotlight.angle = 1;
spotlight.distance = 200;
scene.add(spotlight);

明显就把我们物体后面的阴影整个照出来了
在这里插入图片描述
penumbra 设置光周围的一个衰减效果
在这里插入图片描述
这个值是 0 到 1

const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.position.set(1, 0, 2);
spotlight.castShadow = true;
spotlight.angle = 1;
spotlight.distance = 200;
spotlight.penumbra = 0;
scene.add(spotlight);

默认值就是 0 效果不太明显
在这里插入图片描述
我们来个 0.9

const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.position.set(1, 0, 2);
spotlight.castShadow = true;
spotlight.angle = 1;
spotlight.distance = 200;
spotlight.penumbra = 0.9;
scene.add(spotlight);

在这里插入图片描述
就是 光线的两侧效果光会值越大越弱

decay 沿着光照的距离衰减
在这里插入图片描述
默认值是2 会比较符合现实中的情况

我们给个 0

const spotlight = new THREE.SpotLight(0xffffff, 1);
spotlight.position.set(1, 0, 2);
spotlight.castShadow = true;
spotlight.angle = 1;
spotlight.distance = 200;
spotlight.decay = 0;
scene.add(spotlight);

光照效果衰减的就基本没有 就会显得前后都很亮
在这里插入图片描述
我们调成2 光照缩减明显就变快了
在这里插入图片描述
调成 10 基本一下就缩没了
在这里插入图片描述
但 如果你想在逻辑事件中 例如 GUI 中去修改 decay 就要开启 渲染器的光照计算 physicallyCorrectLights字段 给个true就行
在这里插入图片描述
intensity 的话 也可以控制我们光的强度
在这里插入图片描述
它的默认值 就是个 1
我们这里来个10
在这里插入图片描述
效果就变得非常明显了
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/317860.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序开发学习笔记《12》下拉刷新事件

微信小程序开发学习笔记《12》下拉刷新事件 博主正在学习微信小程序开发,希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读官方文档 一、什么是下拉刷新 下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,…

2024年前端最新面试题-vue3(持续更新中)

文章目录 前言正文什么是 MVVC什么是 MVVM什么是 SPA什么是SFC为什么 data 选项是一个函数Vue 组件通讯(传值)有哪些方式Vue 的生命周期方法有哪些如何理解 Vue 的单项数据流如何理解 Vue 的双向数据绑定Vue3的响应式原理是什么介绍一下 Vue 的虚拟 DOM介…

opencv-4.8.0编译及使用

1 编译 opencv的编译总体来说比较简单,但必须记住一点:opencv的版本必须和opencv_contrib的版本保持一致。例如opencv使用4.8.0,opencv_contrib也必须使用4.8.0。 进入opencv和opencv_contrib的github页面后,默认看到的是git分支&…

【机器学习前置知识】狄利克雷分布

在阅读本文前,建议先食用以下几篇文章以能更好地理解狄利克雷分布: 二项分布 Beta分布 多项分布 共轭分布 狄利克雷分布 狄利克雷分布(Dirichlet distribution)是Beta分布的扩展,把Beta分布从二元扩展到多元形式就是狄利克雷分布&#…

jar包部署到linux虚拟机的docker中之后连不上mysql

前言: 跟着黑马学习docker的时候,将java项目部署到了docker中,运行访问报错,反馈连不上mysql。 错误描述: 方法解决: 概述:在虚拟中中,我进入项目容器的内部,尝试ping…

myql进阶-一条查询sql在mysql的执行过程

目录 1. 流程图 2. 各个过程 2.1 连接器 2.2 分析器 2.3 优化器 2.4 执行器 2.5 注意点 1. 流程图 2. 各个过程 假设我们执行一条sql语句如下: select * from t_good where good_id 1 2.1 连接器 首先我们会和mysql建立连接,此时就会执行到连接…

#mysql 8.0 踩坑日记

事情发生在,修改一个已有功能的时候,正常的参数传递进去接口异常了。查看日志报的 Column date cannot be null 。因为是一直未修改过的功能,首先排除了程序代码问题,首先想到是不是升级过程序的jar包版本,检查下来发…

vivado 使用源文件

使用源文件 概述 源文件包括从AMD IP添加的设计源、知识产权(IP)源目录、RTL设计源、从系统添加的数字信号处理(DSP)源生成器工具和IP子系统,也称为块设计,由IP集成商创建AMD Vivado的功能™ 设计套件。源…

FreeRTOS系统配置

一、前言 在实际使用FreeRTOS 的时候我们时常需要根据自己需求来配置FreeRTOS,而且不同架构 的MCU在使用的时候配置也不同。FreeRTOS的系统配置文件为FreeRTOSConfig.h,在此配置文件中可以完成FreeRTOS的裁剪和配置,这是非常重要的一个文件&a…

年终关账四大财务处理技巧|柯桥会计做账,财税知识

2023年即将落下帷幕,无数公司最忙碌就是“年终关账“这件事了。 “年终关账”不仅是企业内部结算一年经营结果的事,还与企业所得税汇算清缴息息相关,甚至还可能关乎企业税负高低与企业是否依法纳税,千万不可小觑。 同时&#xff0…

K8S存储卷和数据卷

目录 三种存储方式 查看同一容器不同副本的log emptyDir ​编辑 hostPath NFS共享存储 PVC和PV Pv和pvc之间是有生命周期管理的 Pv的状态有四种 支持的读写方式有几种 回收策略 资源回收 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的&#xff0…

Rust-变量

Rust的变量必须先声明后使用。对于局部变量,最常见的声明语法为: let variable:i32 100;与传统的C/C语言相比,Rust的变量声明语法不同。这样设计主要有以下几个方面的考虑。 语法分析更容易 从语法分析的角度来说,Rust的变量声明…

uniapp 实战 -- 创建 uni-admin 项目,部署到 uniCloud 前端网页托管(免费云空间)

创建 uni-admin 项目 可见 只能创建一个超级管理员,创建过后,登录页将不再显示 注册管理员账号 部署到 uniCloud 前端网页托管 部署成功,访问地址可预览效果! https://static-mp-7b65169e-151f-4fbb-a5ba-2125d4f56e3f.next.bs…

ES的索引库操作

索引库操作 索引库就类似数据库表,mapping映射就类似表的结构。 我们要向es中存储数据,必须先创建“库”和“表”。 1.mapping映射属性 mapping是对索引库中文档的约束,常见的mapping属性包括: type:字段数据类型&a…

面试宝典之JVM优化

J01、类加载的几个过程? 加载、验证、准备、解析、初始化。然后是使用和卸载了 J02、Minor GC 与 Full GC 分别在什么时候发生? 新生代内存不够用时候发生 MGC 也叫 YGC,JVM 内存不够的时候发生 FGC J03、java 中垃圾收集的方法有哪些? …

navicat for oracle

前言 Oracle中的概念并不是创建数据库,而是创建一个表空间,然后再创建一个用户,设置该用户的默认表空间为我们新创建的表空间,这些操作之后,便和你之前用过的mysql数据库创建完数据库一模一样了。 创建数据库 使用O…

C++20结构化绑定应用实例(二百五十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

微信订阅号 服务号区别

服务号和订阅号有什么区别?服务号转为订阅号有哪些作用?很多小伙伴想把服务号改为订阅号,但是不知道改了之后具体有什么作用,今天跟大家具体讲解一下。首先我们知道服务号一个月只能发四次文章,但是订阅号每天都可以发…

瑞吉外卖笔记系列(2) —— 完善员工的后台系统登录功能,实现员工信息管理

本文档主要 完善员工的后台系统登录功能,新增员工,员工信息分页查询,启用/禁用员工账号,编辑员工信息 一、完善后台系统登录功能 1.1 问题分析 目前存在的问题是:理论上,用户必须在 http://localhost:808…

宽度优先搜索算法(BFS)详解(超级详细讲解,附有大图)

目录 一.宽度优先搜索(BFS)是什么? 二.图解宽搜(BFS) 三.对比与发现 四。工具——队列 五.模板 六.最后 一.宽度优先搜索(BFS)是什么? 百度百科这样说: 宽度优先搜索…