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.hqwc.cn/news/338528.html

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

相关文章

干洗店小程序:洗衣、洗鞋、工厂系统、上门取送、拍照预约、下单门店管理,一站式解决方案。

干洗店小程序:洗衣、洗鞋、工厂系统、上门取送、拍照预约、下单门店管理,一站式解决方案。 一、核心功能亮点 1. 多种下单模式:支持上门取送、送货到店、寄存网点、智能衣柜,满足您不同需求。 2. 骑手接单:专业骑手快…

【Python】AttributeError: module ‘torch.nn‘ has no attribute ‘HardSigmoid‘

AttributeError: module ‘torch.nn’ has no attribute ‘HardSigmoid’ 这个错误是因为PyTorch的torch.nn模块中并没有HardSigmoid这个函数。是拼写的大小写问题,换成nn.Hardsigmoid()即可。 如下述代码出错。 import torch import torch.nn as nn hard_sigmoid…

Android可换行的RadioGroup

Android可换行的RadioGroup,有时候需要换行显示的单选列表,当然可以有多种实现方式,比如recycleview或者listview实现,本文采用的是RadioGrouprediobutton方式实现。 一、首先自定义view public class WrapRadioGroup extends RadioGroup {pr…

Kubernetes WebHook 入门 -- 入门案例: apiserver 接入 github

博客原文 文章目录 k8s 集群配置介绍Admission WebhookWebHook 入门实践: github 认证接入web 服务器Dockerfile 镜像制作amd64x86_64构造镜像检验镜像 Makefilewebhook 接入 apiserverwebhook.yamlapiserver 挂载 webconfig在 github 中创建认证 token将 token 添加到 kubecon…

重新认识Elasticsearch-一体化矢量搜索引擎

前言 2023 哪个网络词最热?我投“生成式人工智能”一票。过去一年大家都在拥抱大模型,所有的行业都在做自己的大模型。就像冬日里不来件美拉德色系的服饰就会跟不上时代一样。这不前段时间接入JES,用上好久为碰的RestHighLevelClient包。心血…

【sklearn练习】模型评估

一、交叉验证 cross_val_score 的使用 1、不用交叉验证的情况: from __future__ import print_function from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifieriris…

2022-2023 ICPC, Asia Yokohama Regional Contest 2022(题解)

2022-2023 ICPC, Asia Yokohama Regional Contest 2022 文章目录 A. Hasty Santa ClausB. Interactive Number GuessingC. Secure the Top SecretD. Move One CoinE. Incredibly Cute Penguin ChicksF. Make a LoopG. Remodeling the DungeonH. Cake DecorationI. Quiz Contest…

在AWS云上面创建Developers用户组

问题 需要给开发人员创建一个专门的Developers用户组,保证开发人员只能够尽兴相关操作。注意,我这里使用的AWS国际版。 创建Developers用户组 打开用户组页面,点击用户组,创建组,进行用户组创建,如下图&…

2023一建机电工程过关分享

成绩 先说下背景,我是2年拿下一建机电的考试,成绩如下: 学习安排 1)22年学习时,我是严格按照下图中的时间安排来学习的(下图是23年的表格和时间),先公共在实务,公共过关…

Vue.js设计与实现阅读-3

Vue设计与实现阅读-3 1、声明式描述UI2、渲染器3、组件4、模板的工作原理5、Vue.js 是各个模块组成的有机整体 前言 前面一章我们了解了,开发体验是衡量一个框架的重要指标之一。提供友好的警告信息至关重要,但是越详细的警告信息,意味着框架…

C++重新认知:inline关键字

一、为什么要使用inline关键字 在C中.,为了解决频繁调用小函数造成大量消耗栈空间的问题,引进了inline关键字,inline修饰的函数为内敛函数(频繁大量的使用栈空间会造成栈溢出)。 在这段代码中,每次执行for…

用matlab解决简单的数学问题

1 微分和积分 微分和积分是数学计算中常用的手段。微积分最重要的思想就是”微元“与”逐次逼近“,一个整体的事物往往不好研究,但是通过微元分割成一下块一小块的,当做常量处理,最终加起来就能实现运行效果。在matlab中实现函数微…