WEB 3D技术 three.js 光照与阴影

本文 我们来说 灯光与阴影

之前 我们有接触到光照类的知识 但是阴影应该都是第一次接触
那么 我们先来看光
首先是 AmbientLight 环境光 你在官网中搜索 AmbientLight 官方是就写明了 环境光是不会产生阴影的
因为 它没有反向
在这里插入图片描述
然后是 DirectionalLight 平行光 它是可以投射阴影的
因为它是类似于太阳 那 太阳照下来 自然是有阴影的
在这里插入图片描述
还有就是 PointLight 点光源
点光源也是可以产生阴影 但 它是自身为中心 四处发光的
就好像一颗光球 会照向四周
在这里插入图片描述
SpotLight 聚光灯
在这里插入图片描述
这个就像舞台聚关灯的一个效果 中心点光很聚集 照向一个放心 越远光越分散 范围越大
在这里插入图片描述
RectAreaLight 平面光源
比较像 从窗户外面照进来的光
但官网也说明白了 平面光是不支持阴影的
在这里插入图片描述
大体可以总结为 环境光和平面光是无法产生阴影的
那么 还有一些材质 也是不支持阴影的

首当其冲的就是 MeshBasicMaterial 基础网格材质
官网会告诉你 它有没有光照都是一样的 自然不会有阴影类的反应
在这里插入图片描述
MeshStandardMaterial 标准网格材质
这种就是 使用Metallic-Roughness工作流程
和光照息息相关的 它就可以产生出阴影
在这里插入图片描述
MeshLambertMaterial 的话 也有光的效果 但是 这种比较粗糙 不光滑
比较适合做木材等表面粗糙的物体的反射效果
在这里插入图片描述
MeshPhongMaterial 则相反 它适合做一些表面光滑的物体
在这里插入图片描述
MeshLambertMaterial 和 MeshPhongMaterial,都是以性能好作为优势的 相对逼真的程度会弱一些

通常情况下 选择 MeshStandardMaterial 标准网格材质 就够了
那么 还有 MeshPhysicalMaterial 物理网格材质
它内部是更高级的渲染引擎 效果会比基础网格材质更加逼真
但是 会消耗更多的性能
他也是能够更光照发生作用的
在这里插入图片描述
OK 那 我们想在就代码搞起喽

我们先把代码搞成这样

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();//c创建一个canvas容器  并追加到 body上
const renderer = new THREE.WebGLRenderer(0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);//设置相机位置   这里 我们设置Z轴  大家可以试试  S Y 和 Z  都是可以的
camera.position.z = 5;
//设置相机默认看向哪里   三个 0  代表 默认看向原点
camera.lookAt(0, 0, 0);
//将内容渲染到元素上
renderer.render(scene, camera);
const controls = new OrbitControls(camera, renderer.domElement);function animate() {controls.update();requestAnimationFrame(animate);/*cube.rotation.x += 0.01;cube.rotation.y += 0.01;*/renderer.render(scene, camera);
}
animate();

运行起来 就是 一片黑 暂时什么都没有
在这里插入图片描述
我们加入如下代码

// 环境光
const light = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(light);
//直线光源
const directionallight = new THREE.DirectionalLight(0xffffff, 0.5);
directionallight.position.set(10, 10, 10);
scene.add(directionallight);
//创建球形几何体
const sphere1 = new THREE .Mesh(
new THREE.SphereGeometry(0.7, 32, 32),
new THREE.MeshStandardMaterial({
}))
scene.add(sphere1);

这里 我们设置了 环境光 然后创建了一个球形的几何体
球体材质是 普通的 MeshStandardMaterial
在这里插入图片描述
我们拖动一下 会发现 这个球还是有一个反光的效果
我们在他下面加一个平面

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

也是最普通的材质 然后 position y下移 到 负1的位置 然后 旋转rotation 负90度
在这里插入图片描述
我们转动一下平面
在这里插入图片描述
这里 虽然我们有灯光反射的一个效果 但是 显然没有出现阴影的效果

那么 想要有阴影 首先 你要有能达到阴影要求的光照
然后 我们渲染器 要开启这个渲染的计算

我们官网搜索 WebGLRenderer
下面就有一个 shadowMap 阴影贴图效果
这个属性 默认是false 不使用的
在这里插入图片描述
我们找到 渲染器所在位置 将他的 shadowMap字段下的 enabled 设置为true
在这里插入图片描述
开启了之后 我们要设置光照 投射我们的阴影

我们官网 进入平行直线光
在这里插入图片描述
找到属性中的 castShadow 投射阴影
在这里插入图片描述
他默认 为了避免性能消耗 是关闭的
我们直接在平行光这里 给他 castShadow 设为true即可开启
在这里插入图片描述
然后 物体 我们也要设置 让它能够投射我们的阴影
我们 官网进入 Object3D
它的这个属性也叫 castShadow
是否投射阴影
在这里插入图片描述
我们代码中 将球形几何体的 castShadow 给个true 把它打开
在这里插入图片描述
然后 这个阴影是要映射到我们平面上的
那么 这里 我们平面 要去接受这个阴影效果
Object3D 下的 receiveShadow 属性
在这里插入图片描述
平面这里 我们将 receiveShadow 属性设为true
在这里插入图片描述
这培 我们运行代码
在这里插入图片描述
阴影的效果 就出来啦
在这里插入图片描述
所有的步骤 一个不能少 否则就出不来

好 我们最后的代码就是这样的

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 directionallight = new THREE.DirectionalLight(0xffffff, 0.5);
directionallight.position.set(10, 10, 10);
directionallight.castShadow = true;
scene.add(directionallight);
//创建球形几何体
const sphere1 = new THREE .Mesh(new THREE.SphereGeometry(0.7, 32, 32),new THREE.MeshStandardMaterial({})
)
sphere1.castShadow = true;
scene.add(sphere1);
//添加平面
const plane = new THREE.Mesh(new THREE.PlaneGeometry(3, 3),new THREE.MeshStandardMaterial({})
);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add(plane);//c创建一个canvas容器  并追加到 body上
const renderer = new THREE.WebGLRenderer(0);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);//设置相机位置   这里 我们设置Z轴  大家可以试试  S Y 和 Z  都是可以的
camera.position.z = 5;
//设置相机默认看向哪里   三个 0  代表 默认看向原点
camera.lookAt(0, 0, 0);
//将内容渲染到元素上
renderer.render(scene, camera);
const controls = new OrbitControls(camera, renderer.domElement);function animate() {controls.update();requestAnimationFrame(animate);/*cube.rotation.x += 0.01;cube.rotation.y += 0.01;*/renderer.render(scene, camera);
}
animate();

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenAI ChatGPT-4开发笔记2024-04:Chat之Tool之2:multiple functions

从程序员到ai Expert 1 定义参数和函数2 第一轮chatgpt3 第一轮结果和function定义全部加入prompt再喂给chatgpt4 大结局7 参考资料 上一篇解决了调用一个函数的问题。这一篇扩展为调用3个。n个自行脑补。 1 定义参数和函数 #1.设定目标 import json import openai#1.定义para…

Python 快速合并PDF表格转换输出CSV文件

单位的刷脸考勤机后台系统做得比较差,只能导出每个部门的出勤统计表pdf,格式如下: 近期领导要看所有部门的考勤数据,于是动手快速写了个合并pdf并输出csv文件的脚本。 安装模块 pypdf2,pdfplumber,前者用…

docker打包介绍

最近在做一个开源项目,遇到开发者问各种问题,发现都是系统和软件版本的差异引起的。于是了解了一下docker的使用,发现docker真是个好东东,基本解决了各种版本差异的问题,真正做到了一键部署使用。 先熟悉一下docker里…

使用Django框架自带的Form表单完成简单的用户登录注册

如果不知道怎么配置Django环境以及如何连接数据库请点击我的上一篇博客: 使用pycharm初始化Django框架并连接Sql Server 文章目录 1.Django默认生成的数据表2.用户登录2.1创建登录页面2.2视图处理登录请求2.3配置访问路径 3.用户注册3.1创建用户表单3.2创建注册模版…

Java中的网络编程

文章目录 网络基础知识IP 地址端口协议 Java 中网络编程InetAddress(静态类)UDP 通信原理UDP 发送数据步骤UDP 接收数据步骤UDP 发送接收案例 TCP 通信原理TCP 发送数据步骤TCP 接收数据步骤TCP 发送接收案例 网络基础知识 概述:在网络通信协…

限流式保护器在户外汽车充装的应用

摘 要:国家标准GB51348-2019中规定储备仓库、电动车充电等场所的末端回路应设置限流式电气防火保护器。电气防火限流式保护器可以有效克服传统断路器、空气开关和监控设备存在的短路电流大、切断短路电流时间长、短路时产生的电弧火花大,以及使用寿命短等…

鱼哥赠书活动第⑥期:《内网渗透实战攻略》看完这本书教你玩转内网渗透测试成为实战高手!!!!

鱼哥赠书活动第⑥期:《内网渗透实战攻略》 如何阅读本书:本书章节介绍:本书大致目录:适合阅读对象:赠书抽奖规则:往期赠书福利: 当今,网络系统面临着越来越严峻的安全挑战。在众多的安全挑战中&…

14:00面试,14:07就出来了,问的问题有点变态。。。

前言 刚从小厂出来,没想到在另一家公司我又寄了。 在这家公司上班,每天都要加班,但看在钱给的比较多的份上,也就不太计较了。但万万没想到一纸通知,所有人不准加班了,不仅加班费没有了,薪资还…

EndNote20 下载与安装详细教程

扫描文末二维码,关注微信公众号:ThsPool 后台回复 a004 ,免费领取 EndNote20下载安装包 EndNote是一款备受欢迎的文献管理软件,被数百万研究人员、学生和图书管理员广泛使用。它提供便捷的方式来扩展各种语言的参考书目&#xff0…

并发程序设计--D11D12进程间通信

概念:就是进程和进程之间交换信息。 常用通信方式 无名管道(pipe) 有名管道 (fifo) 信号(signal) 共享内存映射(mmap) 套接字(socket) 过时的IPC通信方式 System…

ChatGPT扩展系列之网易数帆ChatBI

在当今数字化快速发展的时代,数据已经成为业务经营与管理决策的核心驱要素。无论是跨国大企业还是新兴创业公司,正确、迅速地洞察数据已经变得至关重要。然而,传统的BI工具往往对用户有一定的技术门槛,需要熟练的操作技能和复杂的查询语句,这使得大部分的企业员工难以深入…

【Flutter 开发实战】Dart 基础篇:从了解背景开始

想要学会用 Flutter 开发 App,就不可避免的要学习另一门很有意思的编程语言 —— Dart。很多小伙伴可能在学习 Flutter 之前可能都没听说过这门编程语言,我也是一样,还以为 Dart 是为了 Flutter 而诞生的;然而,当我们去…

计算机网络(2)

计算机网络(2) 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 计算机网络和因特网(2)分组交换网中的时延、丢包和吞吐量时延丢包吞吐量总结 协议层次及其服务模型模型类型OSI模型分析TCP/IP模型分析 追溯历史 小程一言 我…

2024年 快速搭建自己AI Gemini API 搭建完整

先看下效果 体验效果 Gemini 前言 12月7日消息,谷歌12月6日宣布推出其认为规模最大、功能最强大的人工智能模型Gemini。Gemini将包括三种不同的套件:Gemini Ultra,Gemini Pro和Gemini Nano。 谷歌表示,该公司备受期待的人工智能…

YB2412L 18V 2A 500KHz 同步降压稳压器

YB2412L 18V 2A 500KHz 同步降压稳压器 概述: YB2412L是一种高频、同步、整流、降压、开关模式转换器 移动组。它提供了一个非常紧凑的解决方案,以实现一个2A连续输出电流在一个广泛的输入供应 范围,具有良好的负荷和线路调节。 YB2412L需…

【FPGA/verilog -入门学习17】vivado 实现串口自发自收程序

1,需求 PC使用串口助手给FPGA板发送9600 波特率的数据,FPGA板接收到数据后,回复同样的数据给PC 2,需求分析 按模块可以划分为: rx接收模块,将输入的8位并行rx 数据转换成[7:0]rx_data 信号,当…

设计模式之外观模式【结构型模式】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档> 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某…

小游戏实战丨基于Tkinter的五子棋小游戏

文章目录 写在前面Tkinter五子棋系列文章写在后面 写在前面 本期内容:基于tkinter的五子棋小游戏 下载地址:https://download.csdn.net/download/m0_68111267/88700190 实验环境 python3.11及以上pycharmtkinter Tkinter Tkinter是Python的一个标准…

C#,归并排序算法(Merge Sort Algorithm)的源代码及数据可视化

归并排序 归并算法采用非常经典的分治策略,每次把序列分成n/2的长度,将问题分解成小问题,由复杂变简单。 因为使用了递归算法,不能用于大数据的排序。 核心代码: using System; using System.Text; using System.Co…

phpstudy面板Table ‘mysql.proc‘ doesn‘t exist解决办法

原因分析:误删了mysql数据库 解决办法如下: 1、停止服务 2、先把mysql文件夹下的data文件夹备份,因为data文件里存有数据库文件。然后再删除data文件。 3、cmd管理员命令进入到mysql中的bin目录下 ,执行mysqld --initialize-…