three.js之光源

news2024/11/19 11:18:28

文章目录

  • 简介
  • 分类
    • 环境光
    • 点光源
    • 平行光
    • 聚光灯
  • 光源辅助对象
  • 相关计算
    • 颜色计算
  • 阴影
    • 相关属性
      • castShadow
      • receiveShadow
      • shadow
        • LightShadow
  • 基类

专栏目录请点击

简介

光源是对于自然界光照的模拟,往往为了更好的渲染场景,需要设置不同的光源,设置不同的光照强度

分类

一般光源可以分成以下类别

  1. 环境光(AmbientLight)
  2. 平行光(DirectionalLight)
  3. 点光源(PointLight)
  4. 聚光灯光源(SpotLight)

环境光

环境光是没有特定方向的光源,主要是均匀改变物体明暗的效果,如果没有设置环境光,那么物体会是一个全黑的对象

  • 没有环境光

在这里插入图片描述

  • 有环境光
//环境光:环境光颜色RGB成分分别和物体材质颜色RGB成分分别相乘
var ambient = new THREE.AmbientLight(0x888888);
scene.add(ambient);//环境光对象添加到scene场景中

当环境光打上之后,物体立马改变了颜色

在这里插入图片描述

点光源

  1. 点光源就像我们生活中的灯泡,当设置点光源的时候,必须设置光源的位置属性position
  2. 他会呈现出阴暗面,我们可以设置光源的位置来感受点光源的特点
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300);
scene.add(point);

在这里插入图片描述
3. 我们修改点光源的位置,看一下他的渲染效果

point.position.set(-400, -200, -300);

在这里插入图片描述
我们拖动一下物体就会发现,亮面在另一面

平行光

  1. 平行光的光线是平行的,也就是说物体的每一个区域接收到的入射角是相同的
  2. 在设置的时候,使用positiontarget两个属性来一起确定平行光的方向
    • target的属性值可以是threejs场景中任何一个三维模型
// 平行光设置
var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 两点确定一条直线,我们要找两个点,一个是我们设置的点(position),一个是物体(target)
directionalLight.position.set(80, 100, 50);
directionalLight.target = mesh;
scene.add(directionalLight);

在这里插入图片描述
平行光如果不设置position和target属性,那么光线默认从上往下照射,也就可以认为是从(0,1,0)(0,0,0)两个点确定的直线

聚光灯

  • 聚光灯是一个会沿着特定方向逐渐发散的光源,在一个立体空间会构成一个圆锥体
  • 通过属性angle可以设置聚光灯发散的角度,照射位置和平行光相同是由positiontarget两个属性实现的
// 聚光灯设置
var spotLight = new THREE.SpotLight(0xffffff);
// 两点确定一条直线,我们要找两个点,一个是我们设置的点(position),一个是物体(target)
spotLight.position.set(200, 200, 200);
spotLight.target = mesh;
// 设置发散的角度
spotLight.angle = Math.PI / 100

scene.add(spotLight);

在这里插入图片描述

光源辅助对象

光源辅助对象,就像AxesHelper一样可以可视化显示坐标,他可以大致显示光照的方向

辅助对象构造函数名
聚光源辅助对象SpotLightHelper
点光源辅助对象PointLightHelper
平行光光源辅助对象DirectionalLightHelper
// 光源对象设置
const sphereSize = 2;
const pointLightHelper = new THREE.PointLightHelper( point, sphereSize,"#000" );
scene.add( pointLightHelper );

在这里插入图片描述

相关计算

颜色计算

  1. 当不同颜色的光源照射到有颜色的材质上面去的时候,当光源的颜色和网格模型材质的颜色值mesh.material.color和光源的颜色值light.color会进行简单的相乘,也就是RGB三个分量分别进行相乘
  2. 平行光漫反射的数学模型:漫反射光的颜色 = 网格模型材质颜色值 x 光线颜色 x 光线入射角余弦值
  3. 漫反射数学模型RGB分量表示:(R2,G2,B2) = (R1,G1,B1) x (R0,G0,B0) x cosθ
R2 = R1 * R0 * cosθ
G2 = G1 * G0 * cosθ
B2 = B1 * B0 * cosθ

阴影

有方向的光源的作用下,物体都会形成隐形,想要产生阴影,需要有三个要素

  1. 首先要有光源
  2. 要有投影的模型
  3. 要有接收投影的模型
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <style>
    body {
      margin: 0;
      overflow: hidden;
      /* 隐藏body窗口区域滚动条 */
    }
  </style>
  <!--引入three.js三维引擎-->
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
  <!-- 引入threejs扩展控件OrbitControls.js -->
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>
</head>

<body>
  <script>
    /**
     * 创建场景对象Scene
     */
    var scene = new THREE.Scene();
    /**
     * 创建网格模型
     */
    var geometry = new THREE.BoxGeometry(40, 100, 40); //创建一个立方体几何对象Geometry
    var material = new THREE.MeshLambertMaterial({
      color: 0x0000ff
    }); //材质对象Material
    var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
    scene.add(mesh); //网格模型添加到场景中
    // 设置产生投影的网格模型
    mesh.castShadow = true;
    // mesh.position.set(0,0,0)

    //创建一个平面几何体作为投影面
    var planeGeometry = new THREE.PlaneGeometry(300, 200);
    var planeMaterial = new THREE.MeshLambertMaterial({
      color: 0x999999
    }); //材质对象Material

    // 平面网格模型作为投影面
    var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); //网格模型对象Mesh
    scene.add(planeMesh); //网格模型添加到场景中
    planeMesh.rotateX(-Math.PI / 2); //旋转网格模型
    planeMesh.position.y = -50; //设置网格模型y坐标
    // 设置接收阴影的投影面
    planeMesh.receiveShadow = true;
    /**
     * 光源设置
     */
    //环境光   环境光颜色RGB成分分别和物体材质颜色RGB成分分别相乘
    var ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient); //环境光对象添加到scene场景中

    // 方向光
    var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
    // 设置光源位置
    directionalLight.position.set(60, 100, 40);
    scene.add(directionalLight);
    // 设置用于计算阴影的光源对象
    directionalLight.castShadow = true;
    // 设置计算阴影的区域,最好刚好紧密包围在对象周围
    // 计算阴影的区域过大:模糊  过小:看不到或显示不完整
    directionalLight.shadow.camera.near = 0.5;
    directionalLight.shadow.camera.far = 300;
    directionalLight.shadow.camera.left = -50;
    directionalLight.shadow.camera.right = 50;
    directionalLight.shadow.camera.top = 200;
    directionalLight.shadow.camera.bottom = -100;
    // 设置mapSize属性可以使阴影更清晰,不那么模糊
    // directionalLight.shadow.mapSize.set(1024,1024)
    console.log(directionalLight.shadow.camera);
    /**
     * 相机设置
     */
    var width = window.innerWidth; //窗口宽度
    var height = window.innerHeight; //窗口高度
    var k = width / height; //窗口宽高比
    var s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
    //创建相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.set(200, 300, 200); //设置相机位置
    camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
    /**
     * 创建渲染器对象
     */
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height); //设置渲染区域尺寸
    renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
    // 设置渲染器,允许场景中使用阴影贴图
    renderer.shadowMap.enabled = true;
    // 渲染函数
    function render() {
      renderer.render(scene, camera); //执行渲染操作
    }
    render();
    //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
    var controls = new THREE.OrbitControls(camera, renderer.domElement);
    //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
    controls.addEventListener('change', render);
  </script>
</body>

</html>

我们可以将上面的代码进行复制,渲染出来的效果如下
在这里插入图片描述

  1. 在这里,我们设置了投影面,并让投影面接收阴影
// 平面网格模型作为投影面
var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); //网格模型对象Mesh
scene.add(planeMesh); //网格模型添加到场景中
planeMesh.rotateX(-Math.PI / 2); //旋转网格模型
planeMesh.position.y = -50; //设置网格模型y坐标
// 设置接收阴影的投影面
planeMesh.receiveShadow = true;
  1. 然后设置了阴影的计算区域
// 设置用于计算阴影的光源对象
directionalLight.castShadow = true;
// 设置计算阴影的区域,最好刚好紧密包围在对象周围
// 计算阴影的区域过大:模糊  过小:看不到或显示不完整
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 300;
directionalLight.shadow.camera.left = -50;
directionalLight.shadow.camera.right = 50;
directionalLight.shadow.camera.top = 200;
directionalLight.shadow.camera.bottom = -100;
// 设置mapSize属性可以使阴影更清晰,不那么模糊
// directionalLight.shadow.mapSize.set(1024,1024)

相关属性

castShadow

  • 模型和光源都有这个属性,且都是布尔值
  • 如果是模型的castShadow,它主要用来设置模型对象在光源下是否产生阴影
  • 如果是光源的castShadow,那么光源将会设置动态的阴影,这需要消耗很多动态资源,使投影看起正确

receiveShadow

  • 他也是一个布尔值,用于设置一个模型对象是否在光照下接受其他模型的投影

shadow

  • 光源的shadow属性是一个对象,不同光源的属性值,他们的光阴影对象也是不同的
种类对象阴影对象
平行光DirectionalLightDirectionalLightShadow
聚光源SpotLightSpotLightShadow

LightShadow

LightShadow是所有阴影对象的基类,他有一个属性叫做camera

  • 这个是观察光源的相机对象。这里可以看官网的解释 点击,他用于生成场景的深度图

基类

  • 光源都有一个共同的基类,那就是Light
  • 而Light也有一个基类叫做Object3D
  • 在基类中,光源有两个常用的属性
    • color:他的默认值是0xffffff
    • intensity:他的默认值是1.0
    • 光照计算的时候会把两个属性值进行相乘

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

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

相关文章

如何利用Python中的scipy做卡方检验?

1.简单介绍 卡方检验是一种用途很广的计数资料的假设检验方法。它属于非参数检验的范畴&#xff0c;主要是比较两个及两个以上样本率&#xff08;构成比&#xff09;以及两个分类变量的关联性分析。其根本思想就是在于比较理论频数和实际频数的吻合程度或拟合优度问题。 应用场…

【数据架构】如何通俗易懂的介绍数据模型

一直以来&#xff0c;如何和业务领导讲明白什么是数据模型&#xff0c;是沟通的一大难题&#xff0c;下面演示一个示例&#xff0c;仅供参考。 介绍抽象世界 先从大佬胡本立的《以人为中心的数据观》说起。这个世界可以划分为3个世界&#xff0c;一个是客观存在的客观世界&am…

Lecture3:神经网络与反向传播

目录 1.计算图 2.反向传播与计算图 2.1 第一个例子 2.2 第二个例子--sigmoid 2.3 第三个例子--MAX门 2.4 第四和例子--对于向量的梯度 3.神经网络 4.常见矩阵求导公式 4.1 标量对向量求导 4.2 二次型对向量求导 1.计算图 在实践中我们想要推导和使用解析梯度&…

SOLIDWORKS PDM 2023新功能 SOLIDWORKS本地数据管理优化升级

SOLIDWORKS 2023新版本已经与大家见面&#xff0c;今天众联亿诚与大家分享SOLIDWORKS PDM 2023新功能&#xff0c;让我们先一起来看看视频—— 点击观看SOLIDWORKS PDM 2023新功能 长期以来&#xff0c;SOLIDWORKS PDM Professional一直为SOLIDWORKS的本地数据管理制定标准。随…

centos8 离线安装redis的艰苦历程(gcc、make、redis)

目录 背景环境 一、安装gcc 二、安装make 三、安装redis 背景环境 服务器centos8&#xff0c;内网不能联网 本机Windows&#xff0c;能联网 一、安装gcc 1、下载rpm文件 比较恶心的是需要手动的搜索一个一个的下载。不要问我为什么知道的&#xff01;&#xff01;&…

C++11特性-模板的改进

1.模板的右尖括号>> C11模板的多个右尖括号需要一个空格符fun<A<> >,之前连在一起是右移操作符 C11特性优化了这个fun<A<>> 2.模板的默认参数 函数模板能添加模板参数 template <typename T int> 类模板参数多个时&#xff0c;必…

opencv c++ 光流法、稀疏光流法、稠密光流法、均值迁移追踪(meanshift、camshift)

1、概念 参考&#xff1a; (70条消息) 什么是光流法_张年糕慢慢走的博客-CSDN博客_光流法 (70条消息) 计算机视觉--光流法(optical flow)简介_T-Jhon的博客-CSDN博客_光流法 此外&#xff0c;还有基于均值迁移的目标追踪方法&#xff1a; camshift&#xff1a; (75条消息)…

【VC7升级VC8】将vCenter Server 7.X 升级为 vCenter Server 8 (上)—— VC 8系统要求与升级前的说明

目录1. 新 vCenter Server Appliance 8的系统要求1.1 确认升级路径1.2 硬件要求1.3 存储要求1.4 软件要求1.5 vSphere Client 软件要求2. 升级说明2.1 升级阶段介绍2.2 旧VC7虚拟机的信息2.3 打开升级用安装程序&#xff08;1&#xff09;进入vcsa镜像目录&#xff08;2&#x…

leetcode(力扣)算法刷题-160. 相交链表

描述&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据保证整个链式结构中不存在环。 注意&#xff0c…

Java基础入门第三版黑马课后习题(编程部分)

第 1 章 Java 开发入门 第 2 章 Java 编程基础 1. 编写程序,计算13…99的值,要求如下&#xff1a; (1)使用循环语句实现1~99的遍历 (2)在遍历过程中,通过条件判断当前的数是否为奇数,如果是就累加,否则不加。 public class getSum { 2 public static void main(String[] ar…

vue elementui 多选级联组件 全选功能

Vue 封装 多选级联组件 支持全选功能 使用方式和elm官方一致&#xff0c;原参数一致主要参数&#xff1a; options&#xff1a;级联数菜单。多维数组mulSelectedVal&#xff1a;绑定值。id集合。且取值最后一层idcollapseTags&#xff1a;是否tag展示fieldNames&#xff1a;自…

酵母葡聚糖硫酸酯(SPS)|葡聚糖修饰异黄酮|右旋糖酐修饰Savinase蛋白酶

酵母葡聚糖硫酸酯(SPS)|葡聚糖修饰异黄酮|右旋糖酐修饰Savinase蛋白酶 酵母葡聚糖硫酸酯(SPS) 中文名称&#xff1a;酵母葡聚糖硫酸酯(SPS) 纯度&#xff1a;95% 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 外观:固体或粘性液体 包装&#xff1a;瓶装/袋…

C++ 函数重载的细节

前言&#xff1a;如果不想看论证&#xff0c;可以直接点击总结&#xff0c;跳转到最后 目录 总结 1、使用重载函数时&#xff0c;如果数据类型不匹配&#xff0c;C尝试使用类型转换与形参进行匹配&#xff0c;如果转换后有多个函数能匹配上&#xff0c;编译器将报错&#xff1…

【重识云原生】第六章容器基础6.4.12节——IPv4与IPv6双协议栈配置

1 IPv4/IPv6 双协议栈特性 Kubernetes v1.23 [stable] IPv4/IPv6 双协议栈网络能够将 IPv4 和 IPv6 地址分配给 Pod 和 Service。 从 1.21 版本开始&#xff0c;Kubernetes 集群默认启用 IPv4/IPv6 双协议栈网络&#xff0c; 以支持同时分配 IPv4 和 IPv6 地址。 1.1 支持的…

6 张配图通俗易懂说透 K8S 请求和限制

6 张配图通俗易懂说透 K8S 请求和限制 在 Kubernetes 中使用容器时&#xff0c;了解涉及的资源是什么以及为何需要它们很重要。有些进程比其他进程需要更多的 CPU 或内存。这很关键&#xff0c;永远不应该让进程挨饿。知道了这一点&#xff0c;我们应该正确配置容器和 Pod&…

ICV:L2级乘用车渗透率预计将在2025年超过50%

全球前沿科技咨询机构ICV近期发布了全球乘用车市场的分析报告。ICV在报告中指出&#xff0c;作为汽车消费大国之一的中国在2022年仍是乘用车销量第一的国家。目前L0和L1级别的自动驾驶乘用车仍占市场主导地位&#xff0c;但随着供应端在技术方面的不断突破以及需求端在认可度方…

让你的Python程序像C语言一样快

让你的Python程序像C语言也一样快 在《Python性能优化指南–让你的Python代码快x3倍的秘诀》中有提到很多加速Python程序的方法&#xff0c;在随后的系列文章中我也为大家专门介绍了用PyPy加速Python 和 用Numba&#xff1a;一行代码将Python程序运行速度提升100倍。但在所有方…

VM系列振弦读数模块通讯协议

通讯协议是上位机通过 VMXXX 模块支持的数字接口完成信息交互的数据格式、传输步骤、 通讯速率等的一系列预先约定。上位机必须按照本章描述的通讯协议规则来完成与 VMXXX 的数据交互工作。 寄存器机制 VMXXX 内部维护有若干寄存器&#xff0c;模块在寄存器参数值的控制下…

【LeetCode_字符串_逻辑分析】13. 罗马数字转整数

目录考察点第一次&#xff1a;2022年12月8日15:24:16解题思路代码展示优秀的解题思路1. 总结规律2. 字符串替换题目描述13. 罗马数字转整数 考察点 逻辑分析能力 第一次&#xff1a;2022年12月8日15:24:16 解题思路 分析能力有待提高 代码展示 class Solution {public i…

【HTML5期末作业】用HTML+CSS一个兰州交通大学官网网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…