Threejs_13 聚光灯和点光源的使用

聚光灯就如同手电筒一样,点光源就如同一个电灯泡甚至是萤火虫那样。如何使用他们呢?

我们还是一样,先做一个小球和一个平面,用来展示光线。并且加入基本的环境光。

// 做一个球体
const SphereGeometry = new THREE.SphereGeometry(1, 20, 20);
// 材质
const material = new THREE.MeshStandardMaterial();
const sphere = new THREE.Mesh(SphereGeometry, material);
// 投射阴影
sphere.castShadow = true;
scene.add(sphere);

// 创建平面
const planeGeometry = new THREE.PlaneGeometry(50, 50);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
// 接收阴影
plane.receiveShadow = true;
scene.add(plane);

// 灯光
// 环境光
const light = new THREE.AmbientLight(0xffffff);

scene.add(light);

聚光灯

Threejs 聚光灯手册

使用聚光灯就将之前的直线光源换成聚光灯就可以,当然,聚光灯有一些新的属性,比如说角度、衰减、半影衰减、沿着光照距离衰减等。我们可以直接使用gui做测试。

// 聚光源
const spotLight = new THREE.SpotLight(0xffffff, 2);
spotLight.position.set(5, 5, 5);
spotLight.intensity = 2;
// 设置直线光源产生阴影
spotLight.castShadow = true;
//设置阴影贴图模糊度
spotLight.shadow.radius = 20;
//设置阴影贴图的分辨率(让它变得更加细致)
spotLight.shadow.mapSize.set(4096, 4096);
//设置打在小球上
spotLight.target = sphere;
//聚光灯的角度
spotLight.angle = Math.PI / 6;
//聚光灯的衰减
spotLight.distance = 0;
//聚光灯的半影的衰减
spotLight.penumbra = 0.5;
//聚光灯 沿着光照距离的衰减
spotLight.decay = 0;
// 透视相机的属性设置(一般不用更改)

scene.add(spotLight);

gui.add(sphere.position, "x").min(-5).max(5).step(0.1);
gui
  .add(spotLight, "angle")
  .min(0)
  .max(Math.PI / 2)
  .step(0.01);
gui.add(spotLight, "distance").min(0).max(10).step(0.1);
gui.add(spotLight, "penumbra").min(0).max(10).step(0.1);
gui.add(spotLight, "decay").min(0).max(1).step(0.1);

这里我们要注意,需要将我们的物理渲染器打开

//开启物理渲染器
renderer.physicallyCorrectLights = true;

聚光灯全部代码

//点光源(灯泡) 和 聚光灯(手电筒)
//导入 threejs
import * as THREE from "three";
//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
//导入lil.gui
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";
// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比 窗口的宽高进行设置的
  0.1, // 近平面   相机最近最近能看到的物体
  1000 // 远平面   相机最远能看到的物体
);

//设置相机位置
camera.position.set(0, 0, 10);

scene.add(camera);

// 创建渲染器
const renderer = new THREE.WebGLRenderer();

// 设置渲染器的大小  (窗口大小)
renderer.setSize(window.innerWidth, window.innerHeight);

// 开启场景中的阴影贴图
renderer.shadowMap.enabled = true;

//开启物理渲染器
renderer.physicallyCorrectLights = true;

// 将渲染器的dom元素添加到body中
document.body.appendChild(renderer.domElement);

//添加世界坐标辅助器  (红色x轴,绿色y轴,蓝色z轴)一个线段 参数为 线段长度
const axesHelper = new THREE.AxesHelper(6);

//添加到场景之中
scene.add(axesHelper);

// 添加轨道控制器 (修改侦听位置)  一般监听画布的事件  不监听document.body
const controls = new OrbitControls(camera, renderer.domElement);

//渲染函数
function animate() {
  controls.update();
  //请求动画帧
  requestAnimationFrame(animate);
  //渲染
  renderer.render(scene, camera);
}

//渲染
animate();

// 监听窗口的变化 重新设置渲染器的大小 画布自适应窗口
window.addEventListener("resize", () => {
  // 重新设置渲染器的大小
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 重新设置相机的宽高比
  camera.aspect = window.innerWidth / window.innerHeight;
  // 重新计算相机的投影矩阵
  camera.updateProjectionMatrix();
});
//创建gui实例
const gui = new GUI();

// 做一个球体
const SphereGeometry = new THREE.SphereGeometry(1, 20, 20);
// 材质
const material = new THREE.MeshStandardMaterial();
const sphere = new THREE.Mesh(SphereGeometry, material);
// 投射阴影
sphere.castShadow = true;
scene.add(sphere);

// 创建平面
const planeGeometry = new THREE.PlaneGeometry(50, 50);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
// 接收阴影
plane.receiveShadow = true;
scene.add(plane);

// 灯光
// 环境光
const light = new THREE.AmbientLight(0xffffff);

// 聚光源
const spotLight = new THREE.SpotLight(0xffffff, 2);
spotLight.position.set(5, 5, 5);
spotLight.intensity = 2;
// 设置直线光源产生阴影
spotLight.castShadow = true;
//设置阴影贴图模糊度
spotLight.shadow.radius = 20;
//设置阴影贴图的分辨率(让它变得更加细致)
spotLight.shadow.mapSize.set(4096, 4096);
//设置打在小球上
spotLight.target = sphere;
//聚光灯的角度
spotLight.angle = Math.PI / 6;
//聚光灯的衰减
spotLight.distance = 0;
//聚光灯的半影的衰减
spotLight.penumbra = 0.5;
//聚光灯 沿着光照距离的衰减
spotLight.decay = 0;
// 透视相机的属性设置(一般不用更改)

scene.add(spotLight);
scene.add(light);
gui.add(sphere.position, "x").min(-5).max(5).step(0.1).name("球体x轴位置");
gui
  .add(spotLight, "angle")
  .min(0)
  .max(Math.PI / 2)
  .step(0.01)
  .name("聚光灯角度");
gui.add(spotLight, "distance").min(0).max(10).step(0.1).name("聚光灯距离");
gui.add(spotLight, "penumbra").min(0).max(10).step(0.1).name("聚光灯半影");
gui.add(spotLight, "decay").min(0).max(1).step(0.1).name("聚光灯衰减");

点光源

Threejs 点光源手册

点光源就相当于我们生活中的萤火虫 或者电灯泡。这里我们直接将聚光灯的代码换成点光源。

聚光灯中的部分属性在点光源中是没有的,比如说角度,半影。

const pointLight = new THREE.PointLight(0xff0000, 2);
pointLight.position.set(2, 2, 2);

//光照强度
// pointLight.intensity = 2;
// 设置直线光源产生阴影
pointLight.castShadow = true;
//设置阴影贴图模糊度
pointLight.shadow.radius = 20;
//设置阴影贴图的分辨率(让它变得更加细致)
pointLight.shadow.mapSize.set(512, 512);

scene.add(pointLight);

然后我们可以用gui控制点光源的部分属性。

gui.add(pointLight.position, "x").min(-5).max(5).step(0.1);
gui.add(pointLight, "distance").min(0).max(5).step(0.001);

gui.add(pointLight, "decay").min(0).max(1).step(0.1);

我们做出一个灯光,但是看不到灯光的源头,不过我们可以做一个更小的小球,来模拟灯光的出口,并且可以利用它做出一些效果。

const smallBox = new THREE.Mesh(
  new THREE.SphereGeometry(0.1, 20, 20),
  new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
smallBox.position.set(2, 2, 2);
// 点光源
const pointLight = new THREE.PointLight(0xff0000, 2);
//光照强度
// pointLight.intensity = 2;
// 设置直线光源产生阴影
pointLight.castShadow = true;
//设置阴影贴图模糊度
pointLight.shadow.radius = 20;
//设置阴影贴图的分辨率(让它变得更加细致)
pointLight.shadow.mapSize.set(512, 512);

smallBox.add(pointLight);
scene.add(smallBox);

我们可以利用时钟。来让这个点光源旋转。

//设置时钟
const clock = new THREE.Clock();
//渲染函数
function render() {
  let time = clock.getElapsedTime();
  //通过时间设置小球的位置
  smallBox.position.x = Math.sin(time) * 3;
  smallBox.position.z = Math.cos(time) * 3;
  smallBox.position.y = 2 + Math.sin(time*10);


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

点光源全部代码

//点光源(灯泡) 和 聚光灯(手电筒)
//导入 threejs
import * as THREE from "three";
//导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
//导入lil.gui
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比 窗口的宽高进行设置的
  0.1, // 近平面   相机最近最近能看到的物体
  1000 // 远平面   相机最远能看到的物体
);
//设置相机位置
camera.position.set(0, 0, 10);
scene.add(camera);
// 监听窗口的变化 重新设置渲染器的大小 画布自适应窗口
window.addEventListener("resize", () => {
  // 重新设置渲染器的大小
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 重新设置相机的宽高比
  camera.aspect = window.innerWidth / window.innerHeight;
  // 重新计算相机的投影矩阵
  camera.updateProjectionMatrix();
});
//创建gui实例
const gui = new GUI();
// 做一个球体
const SphereGeometry = new THREE.SphereGeometry(1, 20, 20);
// 材质
const material = new THREE.MeshStandardMaterial();
const sphere = new THREE.Mesh(SphereGeometry, material);
// 投射阴影
sphere.castShadow = true;
scene.add(sphere);
// 创建平面
const planeGeometry = new THREE.PlaneGeometry(50, 50);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
// 接收阴影
scene.add(plane);
// 灯光
// 环境光
const light = new THREE.AmbientLight(0xffffff);
const smallBox = new THREE.Mesh(
  new THREE.SphereGeometry(0.1, 20, 20),
  new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
smallBox.position.set(2, 2, 2);
// 点光源
const pointLight = new THREE.PointLight(0xff0000, 2);
pointLight.position.set(2, 2, 2);
//光照强度
// pointLight.intensity = 2;
// 设置直线光源产生阴影
pointLight.castShadow = true;
//设置阴影贴图模糊度
pointLight.shadow.radius = 20;
//设置阴影贴图的分辨率(让它变得更加细致)
pointLight.shadow.mapSize.set(512, 512);
smallBox.add(pointLight);
scene.add(smallBox);
scene.add(light);
gui.add(pointLight.position, "x").min(-5).max(5).step(0.1);
gui.add(pointLight, "distance").min(0).max(5).step(0.001);
gui.add(pointLight, "decay").min(0).max(1).step(0.1);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器的大小  (窗口大小)
renderer.setSize(window.innerWidth, window.innerHeight);
// 开启场景中的阴影贴图
renderer.shadowMap.enabled = true;
// 将渲染器的dom元素添加到body中
document.body.appendChild(renderer.domElement);
//添加世界坐标辅助器  (红色x轴,绿色y轴,蓝色z轴)一个线段 参数为 线段长度
const axesHelper = new THREE.AxesHelper(6);
//添加到场景之中
scene.add(axesHelper);
// 添加轨道控制器 (修改侦听位置)  一般监听画布的事件  不监听document.body
const controls = new OrbitControls(camera, renderer.domElement);

//设置时钟
const clock = new THREE.Clock();
//渲染函数
function render() {
  let time = clock.getElapsedTime();
  //通过时间设置小球的位置
  smallBox.position.x = Math.sin(time) * 3;
  smallBox.position.z = Math.cos(time) * 3;
  smallBox.position.y = 2 + Math.sin(time*10);
  controls.update();
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

//渲染
render();

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

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

相关文章

Vue中使用Echarts实现数据可视化

文章目录 引言一、安装Echarts二、引入Echarts三、创建图表容器四、初始化Echarts实例五、配置图表选项和数据六、实现图表更新七、Vue实例代码结语我是将军,我一直都在,。! 引言 接着上一篇内容,我将继续分享有关数据可视化的相…

docker安装mysql挂着目录和mysql备份和恢复

第一,镜像拉取,运行镜像并挂载目录,尝试挂bin下,启动不了,不知为啥 docker run --privilegedtrue -itd --namevmysql -p 3306:3306 -v /home/vmysql:/home/vmysql -e MYSQL_ROOT_PASSWORD123456 mysql(图…

为何设计师都在用这个原型样机资源网站?

谈论原型样机素材模板,这个话题对设计师来说如同老朋友一般熟悉。设计师们在创作完毕后,为了更淋漓尽致地展示他们的设计成果,通常会将其放置在真实的样机素材模板中。这种原型样机素材可以让设计作品迅速且清晰地呈现在真实环境中。找到一个…

福州大学《嵌入式系统综合设计》实验五:图像裁剪及尺寸变换

一、实验目的 在深度学习中,往往需要从一张大图中裁剪出一张张小图,以便适应网络输入图像的尺寸,这可以通过bmcv_image_crop函数实现。 实践中,经常需要对输入图像的尺寸进行调整,以适用于网络输入图片尺寸&#xff0…

计网(复习自用)

计算机网络 1.概述 1.1概念 含义 计算机网络:是一个将分散的。具有独立功能的计算机系统,通过通信设备和线路连接起来,由功能完善的软件实现资源共享和信息传递的系统。 简单点说,计算机网络是互联的,自治的计算机集…

低成本打造便携式无线网络攻防学习环境

1.摘要 一直以来, 无线网络安全问题与大众的个人隐私息息相关, 例如: 为了节省流量, 连接到一个看似安全的免费WiFi, 在使用过程中泄露自己的各类密码信息甚至银行卡账号密码信息。随着家用智能电器的普及, 家中的各类智能设备连入家里的无线网络, 却突然失灵, 甚至无法正常连…

碳化硅MOS/超结MOS在直流充电桩上的应用-REASUNOS瑞森半导体

一、前言 直流充电桩是新能源汽车直流充电桩的简称,一般也被叫做“快充”。直流充电桩一般与交流电网连接,可作为非车载电动汽车的动力补充,是一种直流工作电源的电源控制装置,可以提供充足的电量,输出电压和电流可以…

Windows日常故障自我排查:用工具eventvwr.msc(事件查看器)分析问题故障

windows故障排查方法一: 工具用法 系统故障问题时,找不到解决方法 首先, 在搜索栏输入: 事件查看器(eventvwr.msc) 打开程序 根据程序找到程序运行的LOG 根据程序Operational筛选出错误日志: 日志中找错误原因&…

itext - PDF模板套打

项目需求:获取列表数据之后直接将数据生成一个pdf。因此需要使用到 itext 对pdf进行直接操作。 环境配置 需要为pdf添加文字域,因此需要安装Adobe Acrobat 准备一个空的PDF文件,如果有现成的模板更好 依赖配置,我们使用itext的7版…

揭示卡尔曼滤波器的威力

一、说明 作为一名数据科学家,我们偶尔会遇到需要对趋势进行建模以预测未来值的情况。虽然人们倾向于关注基于统计或机器学习的算法,但我在这里提出一个不同的选择:卡尔曼滤波器(KF)。 1960 年代初期,Rudol…

基于H1ve一分钟搭好CTF靶场

写在前面 ◉ ‿ ◉ 上一篇文章给大家详细介绍了基于H1ve搭建CTF靶场,以及过程中可能遇到的报错及解决方法,那么这篇文章,我总结了一下,将不会遇到报错的方法给到大家,但是前提是你的服务器最好是一个全新的哦~~~ 我…

小程序订阅消息

wx.requestSubscribeMessage({tmplIds: [2IdqlWrqSbjAurzIuW8imeK-ftS8gbhYdZ0icdE],success(res) {console.log(res);// 处理用户授权结果},fail(err) {console.error(err);// 处理授权请求失败}});

淡入淡出transition: right 1s

transition: right 1s; //重点直接改变right值 操作过快 这里用该方法实现1s内淡入淡出 达到效果目标

20230511 Windows Ubuntu vscode remote-ssh 连接配置

参考 : VSCode SSH 连接远程ubuntu Linux 主机 VSCode通过Remote SSH扩展连接到内网Ubuntu主机 Ubuntu 安装 sudo apt-get install openssh-server vscode: 安装remote-ssh 插件 连接到服务器IP 免密登录的公钥密钥传递用filezillaUbuntu 和 Windows 文件互传 …

ios(swiftui) 画中画

一、环境 要实现画中画 ios系统必须是 iOS14 本文开发环境 xcode14.2 二、权限配置 在项目导航器中单击项目,然后单击Signing & Capabilities。单击 Capabilit搜索Background Modes,然后双击将其添加为功能。在新添加的Background Modes部分&a…

chatglm3部署使用

chatglm3部署使用 1.部署2.使用3.接入微信4.vue前端 1.部署 1.首先去github下载chatglm3代码。Huggingface下载模型一直失败,所以用阿里的魔塔社区下载。 git clone https://github.com/THUDM/ChatGLM3.git git clone https://www.modelscope.cn/ZhipuAI/chatglm3…

SpringMVC 基础知识

学习目标 掌握基于 SpringMVC 获取请求参数与响应 json 数据操作熟练应用基于 REST 风格的请求路径设置与参数传递能够根据实际业务建立前后端开发通信协议并进行实现基于 SSM 整合技术开发任意业务模块功能 1 SpringMVC 简介 1.1 概述 1.1.1 web程序开发流程 【执行过程】…

Hook+jsdom 解决cookie逆向

前言 记录下如何破cookie逆向 目标 目标网址:https://q.10jqka.com.cn/ 目标接口:http://q.10jqka.com.cn/index/index/board/all/field/zdf/order/desc/page/2/ajax/1/ 对抗:cookie反爬虫处理,关键字v,如图 解决步骤 1、JS中关键字查找 如上,我们找到了关键字 v,…

etoken是什么意思,有什么作用?

EToken是一种数字货币,它是由以太坊区块链平台发行的智能合约,旨在为以太坊生态系统提供一种安全、可靠、去中心化的交易媒介。EToken具有多种作用,下面将详细介绍。 一、EToken的定义和发行 EToken是由以太坊智能合约创建的数字货币&#xf…

交易宝订单系统使用心得

简介 交易宝是管理订单支付的软件系统,可对多个应用的支付业务进行统一管理和运营,为你节省时间和精力,让你专注于核心业务,实现更高的效率和利润。 特点:无需开发,开箱即用,统一管理支付订单…