【技术调研】三维(4)-ThreeJs阴影投射、光线投射及案例

阴影投射

阴影是灯光经过物体后产生的,几个关键的设置:

  • 灯光属性设置:.castShadow : Boolean 。此属性设置为 true 灯光将投射阴影。注意:这样做的代价比较高,需要通过调整让阴影看起来正确。 查看 DirectionalLightShadow 了解详细信息。 默认值为 false
  • 物体属性设置:
    • .castShadow : Boolean 对象是否被渲染到阴影贴图中。默认值为false
    • .receiveShadow : Boolean 材质是否接收阴影。默认值为false
  • 渲染器设置:.shadowMap : enabled: 如果设置开启,允许在场景中使用阴影贴图。默认是 false

阴影投射动画案例

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>My first three.js app</title><style>body {margin: 0;}</style>
</head><body><script type="module">import * as THREE from "three";import { OrbitControls } from 'three/addons/controls/OrbitControls.js';const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);camera.position.set(0, 50, 100);camera.lookAt(0, 0, 0);const renderer = new THREE.WebGLRenderer({antialias: true})renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMap.enabled = true;renderer.shadowMapType = THREE.PCFSoftShadowMap;document.body.appendChild(renderer.domElement);//创建坐标格辅助对象// const gridHelper = new THREE.GridHelper(100,20,0xffffff );// scene.add( gridHelper );/***  创建地面*/const geometry2 = new THREE.PlaneGeometry(100, 100);const material2 = new THREE.MeshStandardMaterial({ color: 0xffffff });const plane = new THREE.Mesh(geometry2, material2);plane.rotation.x = -Math.PI / 2;plane.receiveShadow = true;scene.add(plane);//旋转/***  创建一个立方体*/const geometry = new THREE.BoxGeometry(10, 10, 10);const textureLoader = new THREE.TextureLoader();const texture = textureLoader.load('./img/Banner.png');const material = new THREE.MeshStandardMaterial({ map: texture });const cube = new THREE.Mesh(geometry,material);cube.position.set(0, 5, 0);cube.castShadow = true;scene.add(cube);/*** 灯光*///环境光const ambientLight = new THREE.AmbientLight(0x404040); // 柔和的白光scene.add(ambientLight);// 平行光const directionLight = new THREE.DirectionalLight(0xffffff, 1);directionLight.castShadow = true;//让阴影更清晰directionLight.shadow.mapSize.width = 2048;directionLight.shadow.mapSize.height = 2048;//不设置以下内容看不见directionLight.shadow.camera.left = -100;directionLight.shadow.camera.right = 100;directionLight.shadow.camera.top = 100;directionLight.shadow.camera.bottom = -100;directionLight.position.set(150, 20, 0);const directionalLightHelper = new THREE.DirectionalLightHelper(directionLight, 5);scene.add(directionLight, directionalLightHelper);// 点光源const pointLight = new THREE.PointLight( 0xffffff, 500 );const pointLightHelper = new THREE.PointLightHelper(pointLight,1);pointLight.castShadow = true;pointLight.position.set( 10, 10, 0 );scene.add( pointLight,pointLightHelper );/*** 用于查看投射相机*/// const cam = directionLight.shadow.camera;// const cameraHelper = new THREE.CameraHelper(cam);// scene.add(cameraHelper);// cameraHelper.visible = true;const controls = new OrbitControls(camera, renderer.domElement);controls.enableDamping = true;let angle = 0;const animete = () => {angle += 0.01;pointLight.position.set(10*Math.cos(angle),pointLight.position.y,10*Math.sin(angle));requestAnimationFrame(animete);renderer.render(scene, camera);};animete();</script>
</body></html>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

光线投射

RayCaster可以向特定方向投射光线,并测试哪些对象与其相交。光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。

应用场景:

  1. 测试相机前方是否有一堵墙(障碍)
  2. 光线是否击中目标
  3. 当鼠标移动时测试是否有物体位于光标下方,以此模拟鼠标事件
  4. 当物体朝向特定某处时提示信息

光线投射动画

1.动态的三个小球使用了一个固定方向的光线投射,被光线穿透会变绿色。

2.静态的三个小球,使用的是鼠标+相机方向进行光线投射,鼠标点击时触发。即鼠标点击会变黄色。

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>My first three.js app</title><style>body {margin: 0;}</style></head><body><script type="module">import * as THREE from "three";import {OrbitControls} from 'three/addons/controls/OrbitControls.js';const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);camera.position.set(0, 5, 5);camera.lookAt(0, 0, 0);const renderer = new THREE.WebGLRenderer({antialias: true})renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMap.enabled = true;renderer.shadowMapType = THREE.PCFSoftShadowMap;document.body.appendChild(renderer.domElement);/***  创建地面*/const geometry2 = new THREE.PlaneGeometry(100, 100);const material2 = new THREE.MeshStandardMaterial({color: 0xffffff});const plane = new THREE.Mesh(geometry2, material2);//旋转plane.rotation.x = -Math.PI / 2;plane.receiveShadow = true;plane.position.y = -5;scene.add(plane);/*** 球1*/const sphere1 = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32),new THREE.MeshBasicMaterial({color: 0xff0000}))sphere1.position.x = -2const sphere2 = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32),new THREE.MeshBasicMaterial({color: 0xff0000}))const sphere3 = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32),new THREE.MeshBasicMaterial({color: 0xff0000}))sphere3.position.x = 2;scene.add(sphere1, sphere2, sphere3)const sphere4 = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32),new THREE.MeshBasicMaterial({color: 0xff0000}))sphere4.position.x = -2sphere4.position.z = -5const sphere5 = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32),new THREE.MeshBasicMaterial({color: 0xff0000}))sphere5.position.z = -5const sphere6 = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32),new THREE.MeshBasicMaterial({color: 0xff0000}))sphere6.position.x = 2;sphere6.position.z = -5scene.add(sphere4, sphere5, sphere6)/*** 灯光*///环境光const ambientLight = new THREE.AmbientLight(0x404040); // 柔和的白光scene.add(ambientLight);/*** 创建光线投射*/const raycaster = new THREE.Raycaster()//射线原点const rayOrigin = new THREE.Vector3(-3, 0, 0)//射线方向const rayDirection = new THREE.Vector3(10, 0, 0)//将该向量的方向设置为和原向量相同,但是其长度rayDirection.normalize()raycaster.set(rayOrigin, rayDirection)// 检测和射线相交的物体。const intersect = raycaster.intersectObject(sphere1)console.log(intersect)// 检测和射线相交的一组物体。const intersects = raycaster.intersectObjects([sphere1, sphere2, sphere3])console.log(intersects)console.log(raycaster)/*** 创建用于鼠标控制的光线投射*/const raycaster2 = new THREE.Raycaster();const objectsToTests = [sphere4, sphere5, sphere6];/*** 获取鼠标位置,转换为x,y形成射线原点*/const mouse = new THREE.Vector2();window.addEventListener("mousedown", (event) => {mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;//设置后会根据鼠标和相机 进行光线投射console.log(camera.position);raycaster2.setFromCamera(mouse, camera);console.log(raycaster2);console.log(mouse);const intersectObjects = raycaster2.intersectObjects(objectsToTests);console.log(intersectObjects);for (const object of objectsToTests) {object.material.color.set(0xff0000);}for (const intersect of intersectObjects) {intersect.object.material.color.set(0xFFFF00)}})const controls = new OrbitControls(camera, renderer.domElement);controls.enableDamping = true;const clock = new THREE.Clock()const animete = () => {const elapsedTime = clock.getElapsedTime();sphere1.position.y = Math.sin(elapsedTime * 0.3) * 1.5sphere2.position.y = Math.sin(elapsedTime * 0.7) * 1.5sphere3.position.y = Math.sin(elapsedTime * 1.4) * 1.5const objectsToTests = [sphere1, sphere2, sphere3]const intersectObjects = raycaster.intersectObjects(objectsToTests)for (const object of objectsToTests) {object.material.color.set(0xff0000)}for (const intersect of intersectObjects) {intersect.object.material.color.set(0x008000)}controls.update()requestAnimationFrame(animete);renderer.render(scene, camera);};animete();</script></body></html>

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

CAD_Electrical 2022使用记录

一、CAD软件实用调整 1、如何调节窗口背景颜色 例如&#xff1a;将图中白色的背景色调节为黑色。 步骤&#xff1a;在CAD空白区域点击右键 -> 点击选项 -> 在显示中点击颜色(窗口元素) -> 将二维模型空间统一背景的颜色修改成需要的颜色 2、如何调节关标大小 例如&a…

如何精确统计Pytorch模型推理时间

文章目录 0 背景1 精确统计方法2 手动synchronize和Event适用场景 0 背景 在分析模型性能时需要精确地统计出模型的推理时间&#xff0c;但仅仅通过在模型推理前后打时间戳然后相减得到的时间其实是Host侧向Device侧下发指令的时间。如下图所示&#xff0c;Host侧下发指令与De…

发展与监管协同发力 人工智能算法领域已形成良好生态

发展与监管协同发力 人工智能算法领域已形成良好生态 近日&#xff0c;全国组织机构统一社会信用代码数据服务中心对国家网信办公示的人工智能领域备案信息进行了详尽的分析&#xff0c;揭示了我国人工智能产业的蓬勃景象。据统计&#xff0c;我国人工智能领域的备案主体遍布各…

MySQL之表的约束

目录 前言 一&#xff1a;空属性 二&#xff1a;默认值 三:列描述 四:zerofill 五:主键 六:自增长 七:唯一键 八&#xff1a;外键 接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 前言 表中一定要有各种约束&#xff0c;通过约束…

零倾覆力矩点(ZMP)

系列文章目录 前言 在机器人学中&#xff0c;零倾力矩点&#xff08;ZMP&#xff09;是一个特征点&#xff0c;主要用于足式运动。在下文的一些假设中&#xff0c;我们将看到&#xff0c;它非正式地代表了一个系统接触反作用力的结果点。例如&#xff0c;下图中的刚体处于静态平…

【深入理解SpringCloud微服务】深入理解nacos配置中心(四)——配置新增或修改源码分析

【深入理解SpringCloud微服务】深入理解nacos配置中心&#xff08;四&#xff09;——配置新增或修改源码分析 原理回顾源码分析ConfigController#publishConfig()ConfigOperationService#publishConfig()nacos事件监听机制ConfigChangePublisher#notifyConfigChange()NotifyCe…

在 FlexSim 中使用 OpenUSD 分析、可视化和优化现实世界的流程

对于制造和工业企业而言&#xff0c;效率和精度至关重要。为了简化运营、降低成本和提高生产力&#xff0c;各公司正在转向数字孪生和离散事件模拟。 离散事件模拟使制造商能够通过试验不同的输入和行为来优化流程&#xff0c;这些输入和行为可以逐步进行建模和测试。 FlexSi…

6. Transforms的使用(一)--ToTensor()

Transforms的使用&#xff08;一&#xff09; 1.使用ToTensor类将数据转化为Tensor形式 导入需要使用的transforms类 from torchvision import transforms创建ToTensor类的实例 totensor transforms.ToTensor()将读取的图片ndarray数据转化为Tensor数据 img cv.imread(img_p…

Java网络编程 TCP通信(Socket 与 ServerSocket)

1.TCP通信原理 TCP通信涉及两个端点&#xff1a;客户端和服务器。服务器端使用 ServerSocket 监听特定端口&#xff0c;等待客户端的连接请求。客户端使用 Socket 连接到服务器的IP地址和端口。一旦连接建立&#xff0c;双方就可以通过输入输出流进行数据交换. ServerSocket是…

视频工具EasyDarwin生成RTMP给WVP拉流列表

效果 运行 登录 http://127.0.0.1:10086/ admin/admin 创建RTMP服务

微型导轨在光学仪器中的应用!

微型导轨在光学仪器中扮演着至关重要的角色&#xff0c;以其高精度、高稳定性的特点&#xff0c;提供稳定的光学路径和精确的光学元件位置。接下来&#xff0c;我们一起来看看微型导轨在光学仪器中的应用实例&#xff01; 1、显微镜&#xff1a;在显微镜中&#xff0c;微型导轨…

鹏哥C语言自定义笔记重点(67-)

67. 68. 69. 70. 71.结构体内容 72.理解结构体的字节数 73. #pragma once //头文件中使用&#xff0c;功能是:防止头文件被多次引用 74.结构体传参 结论:结构体传参时&#xff0c;要传结构体地址。 75.位段 76.static是只能在该文件中看到&#xff0c;其他地方看不到 77.…

【6大设计原则】迪米特法则:解密软件设计中的“最少知识原则”

引言 在软件设计中&#xff0c;设计原则是指导我们构建高质量、可维护系统的基石。迪米特法则&#xff08;Law of Demeter&#xff0c;LoD&#xff09;&#xff0c;也被称为“最少知识原则”&#xff0c;是六大设计原则之一。它强调对象之间的松耦合&#xff0c;确保系统的各个…

8. Transforms的使用(三)-- Resize

Transforms的使用(三) 1. 为什么要使用Resize 在模型的训练过程中往往需要图片数据的维度相同,才能适应深度学习模型中的相关神经网络结构,这时候就需要使用Resize保证所有的图片保持相同的尺寸2. 使用Resize调整图片的尺寸 在pytorch2.3的版本上,Resize()支持对Tensor类…

1405 问题 E: 世界杯

废话 这个题&#xff0c;我估计 22 22 22 年的时候写过一次&#xff0c;当时应该是搞明白了&#xff0c;现在重新写还是不会写&#xff0c;有点无奈 题目 问题 E: 世界杯&#xff1a;现在的 OJ 把题目加到一个活动里面去之后&#xff0c;感觉之后这个链接就访问不了了。题目…

CSS—4

1.定位 1.相对定位 2.绝对定位 3.固定定位 4.粘性定位 5.定位的特殊应用 2.布局-版心 3.布局-常用布局名词 4.布局-重置默认样式

321. 拼接最大数

1. 题目 321. 拼接最大数 2. 解题思路 题目精简一下&#xff1a; 给你两个数组&#xff0c;从每个数组选取N个元素&#xff08;需要保持相对顺序&#xff0c;比如从数组[4,8,2]选取两个元素&#xff0c;选取出来后必须保持顺序&#xff0c;比如选4和2&#xff0c;那么组成新…

对操作系统(OS)管理和进程的理解

文章目录 从冯诺依曼体系入手来了解计算机硬件部分操作系统操作系统的概念设计操作系统&#xff08;OS&#xff09;的目的对下&#xff08;硬件&#xff09;OS的管理对上如何理解系统调用 进程 在计算机系统中&#xff0c;硬件、操作系统和进程是三个至关重要的概念。它们相互协…

C# 反射之动态生成dll/exe

这个可能应该属于反射的高级使用范围了&#xff0c;平常在项目中使用的人估计也不是很多。由于使用反射的话会降低性能&#xff0c;比如之前用到的GetValue、SetValue等之类&#xff0c;但是使用这种方式会大大提高效率&#xff0c;在这里我只想说&#xff0c;都直接写IL指令了…

C++八股文之面向对象篇

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 思维导图链接&#xff1a;面向对象的性质 持续更新中…… &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 …