【threejs】每天一个小案例讲解:光照

代码仓

GitHub - TiffanyHoo/three_practices: Learning three.js together!

可自行clone,无需安装依赖,直接liver-server运行/直接打开chapter01中的html文件

运行效果图

知识要点

常见光照类型及其特点如下:

1. 环境光(AmbientLight)

• 特点:均匀照亮场景所有物体,不考虑光源位置,营造基础明暗氛围。

• 应用:常用于模拟间接光照(如室内墙壁反射光),需配合其他光源使用,避免场景过平。

• 示例:new THREE.AmbientLight(0x404040, 0.6)(颜色和强度可调整)。

2. 平行光(DirectionalLight)

• 特点:类似太阳光照,光线平行照射,方向固定,不受距离影响。

• 应用:模拟太阳光、大型场景主光源,可通过旋转调整光照方向。

• 示例:new THREE.DirectionalLight(0xffffff, 0.8),需设置direction属性(如指向地面)。

3. 点光源(PointLight)

• 特点:从单一位置向四周发散光线,光照强度随距离衰减。

• 应用:模拟灯泡、蜡烛等点光源效果,可通过distance和decay控制衰减范围。

• 示例:new THREE.PointLight(0xff0000, 1, 100)(红色光,强度1,有效距离100)。

4. 聚光灯(SpotLight)

• 特点:光线呈锥形发散,可控制照射角度、边缘柔和度等,类似手电筒。

• 应用:舞台灯光、局部重点照明,可通过angle(锥角)和penumbra(边缘模糊)调整效果。

• 示例:new THREE.SpotLight(0xffffff, 1, 100, Math.PI/4)(白光,强度1,锥角45度)。

5. 半球光(HemisphereLight)

• 特点:模拟天空和地面的光照,顶部为天空色,底部为地面色,光线柔和。

• 应用:户外场景自然光照(如蓝天与地面反射),参数包括天空色、地面色和强度。

• 示例:new THREE.HemisphereLight(0xaaaaaa, 0x444444, 1)(天空浅灰,地面深灰)。

关键参数对比

• 位置影响:平行光(方向)、点/聚光灯(位置),环境光/半球光无位置概念。

• 衰减特性:点/聚光灯支持距离衰减,平行光/环境光无衰减。

• 阴影支持:平行光和聚光灯可投射阴影(需开启castShadow),其他光源通常不支持。

通过组合不同光照类型,可实现复杂场景的光影效果,例如“平行光(主光源)+ 环境光(基础照明)+ 点光源(局部补光)”的搭配。

核心运行代码

<!DOCTYPE html><html><head><title>Example 03.02 - point Light</title><script type="text/javascript" src="../libs/three.js"></script><script type="text/javascript" src="../libs/stats.js"></script><script type="text/javascript" src="../libs/dat.gui.js"></script><style>body {/* set margin to 0 and overflow to hidden, to go fullscreen */margin: 0;overflow: hidden;}</style>
</head><body><div id="Stats-output"></div><!-- Div which will hold the Output --><div id="WebGL-output"></div><!-- Javascript code that runs our Three.js examples --><script type="text/javascript">// once everything is loaded, we run our Three.js stuff.function init() {// create a scene, that will hold all our elements such as objects, cameras and lights.var scene = new THREE.Scene();// create a camera, which defines where we're looking at.var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);// create a render and set the sizevar renderer = new THREE.WebGLRenderer();// var renderer = new THREE.WebGLRenderer({alpha: true});/*** alpha: true 启用透明度支持* !!!透明度没有生效* 1.因为没有启用渲染器透明度支持* 2.没有正确使用setClearColor方法两个参数*   renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));*   透明度 (0-1) 0 完全透明 1完全不透明**/renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));renderer.setSize(window.innerWidth, window.innerHeight);// renderer.shadowMapEnabled = true;// 启用阴影贴图:用于在3D场景中生成和渲染物体的阴影// create the ground planevar planeGeometry = new THREE.PlaneGeometry(60, 20, 20, 20);var planeMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff });var plane = new THREE.Mesh(planeGeometry, planeMaterial);plane.receiveShadow = true; // 接收阴影// rotate and position the planeplane.rotation.x = -0.5 * Math.PI;plane.position.x = 15;plane.position.y = 0;plane.position.z = 0;// add the plane to the scenescene.add(plane);// create a cubevar cubeGeometry = new THREE.BoxGeometry(4, 4, 4);var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff7777 });// MeshLambertMaterial 基于Lambert反射模型的材质,适用于不发光且没有高光的物体(表面粗糙、没有明显反光)。它支持颜色、贴图、透明度等属性。var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);cube.castShadow = true; // 投射阴影// position the cubecube.position.x = -4;cube.position.y = 3;cube.position.z = 0;// add the cube to the scenescene.add(cube);var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x7777ff });var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);// position the spheresphere.position.x = 20;sphere.position.y = 0;sphere.position.z = 2;sphere.castShadow = true;// add the sphere to the scenescene.add(sphere);// position and point the camera to the center of the scenecamera.position.x = -25;camera.position.y = 30;camera.position.z = 25;camera.lookAt(new THREE.Vector3(10, 0, 0));// 添加光源// add subtle ambient lightingvar ambiColor = "#0c0c0c";var ambientLight = new THREE.AmbientLight(ambiColor);scene.add(ambientLight);// add spotlight for the shadowsvar spotLight = new THREE.SpotLight(0xffffff);console.log(spotLight.position);spotLight.position.set(-40, 60, -10);spotLight.castShadow = true;console.log(spotLight);console.log(spotLight.target); // 默认(0,0,0)console.log(spotLight.shadow); // undefined shadow属性是在r128之后引入的// scene.add( spotLight );var pointColor = "#ccffcc";var pointLight = new THREE.PointLight(pointColor); // 无阴影pointLight.distance = 100; // 0 无限远 光线强度不随距离增加而减弱scene.add(pointLight);// add a small sphere simulating the pointlightvar sphereLight = new THREE.SphereGeometry(0.2);var sphereLightMaterial = new THREE.MeshBasicMaterial({ color: 0xac6c25 });var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);sphereLightMesh.castShadow = true;sphereLightMesh.position = new THREE.Vector3(3, 0, 3);scene.add(sphereLightMesh);// const directionalLight = new THREE.DirectionalLight(0xffffff, 1);// directionalLight.position.set(-40, 60, -10);// directionalLight.castShadow = true;// scene.add(directionalLight);// add the output of the renderer to the html elementdocument.getElementById("WebGL-output").appendChild(renderer.domElement);// call the render functionvar step = 0;// used to determine the switch point for the light animationvar invert = 1;var phase = 0;var controls = new function () {this.rotationSpeed = 0.03;this.bouncingSpeed = 0.03;this.ambientColor = ambiColor;this.pointColor = pointColor;this.intensity = 1;this.distance = 100;};var gui = new dat.GUI();gui.addColor(controls, 'ambientColor').onChange(function (e) {ambientLight.color = new THREE.Color(e);});gui.addColor(controls, 'pointColor').onChange(function (e) {pointLight.color = new THREE.Color(e);});gui.add(controls, 'intensity', 0, 3).onChange(function (e) {pointLight.intensity = e;});gui.add(controls, 'distance', 0, 100).onChange(function (e) {pointLight.distance = e;});var stats = initStats();render();function render() {stats.update();// rotate the cube around its axescube.rotation.x += controls.rotationSpeed;cube.rotation.y += controls.rotationSpeed;cube.rotation.z += controls.rotationSpeed;// bounce the sphere up and downstep += controls.bouncingSpeed;sphere.position.x = 20 + (10 * (Math.cos(step)));sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));// move the light simulationif (phase > 2 * Math.PI) {invert = invert * -1;phase -= 2 * Math.PI;} else {phase += controls.rotationSpeed;}sphereLightMesh.position.z = +(7 * (Math.sin(phase)));sphereLightMesh.position.x = +(14 * (Math.cos(phase)));sphereLightMesh.position.y = 5;if (invert < 0) {var pivot = 14;sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot)) + pivot;}pointLight.position.copy(sphereLightMesh.position);// render using requestAnimationFramerequestAnimationFrame(render);renderer.render(scene, camera);}function initStats() {var stats = new Stats();stats.setMode(0); // 0: fps, 1: ms// Align top-leftstats.domElement.style.position = 'absolute';stats.domElement.style.left = '0px';stats.domElement.style.top = '0px';document.getElementById("Stats-output").appendChild(stats.domElement);return stats;}}window.onload = init</script>
</body></html>

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

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

相关文章

大模型在输尿管下段积水预测及临床应用的研究

目录 一、引言 1.1 研究背景与意义 1.2 研究目的 1.3 研究范围与限制 1.4 文献综述 1.5 研究方法和框架 二、相关理论与概念 2.1 大模型技术原理 2.2 输尿管下段积水病理机制 2.3 大模型在医学预测领域的应用 三、大模型预测输尿管下段积水的方法 3.1 数据收集 3.…

gitlab相关操作

2025.06.11今天我学习了如何在终端使用git相关操作&#xff1a; 一、需要修改新的仓库git地址的时候&#xff1a; &#xff08;1&#xff09;检查当前远程仓库 git remote -v 输出示例&#xff1a; origin https://github.com/old-repo.git (fetch) origin https://github.c…

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…

通过共享内存在多程序之间实现数据通信

注&#xff1a;以下内容为与 GPT-4O 共同创作完成 以共享内存的方式实现多程序之间的数据通信&#xff0c;尤其适合在一台机器上的多程序之间进行高频数据交换。 以下示例展示了 sender.py 向 receiver.py 发送数据并接收经 receiver.py 处理后的数据&#xff0c;以及如何通过…

[论文阅读] 人工智能+软件工程 | 理解GitGoodBench:评估AI代理在Git中表现的新基准

理解GitGoodBench&#xff1a;评估AI代理在Git中表现的新基准 论文信息 GitGoodBench: A Novel Benchmark For Evaluating Agentic Performance On Git Tobias Lindenbauer, Egor Bogomolov, Yaroslav Zharov Cite as: arXiv:2505.22583 [cs.SE] 研究背景&#xff1a;当AI走进…

开源 java android app 开发(十二)封库.aar

文章的目的为了记录使用java 进行android app 开发学习的经历。本职为嵌入式软件开发&#xff0c;公司安排开发app&#xff0c;临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 java an…

ubuntu + nginx 1.26 + php7.4 + mysql8.0 调优

服务器配置 8核 16G 查看内存 free -h nginx配置 worker_processes auto; # 自动检测CPU核心数 worker_rlimit_nofile 65535; # 提高文件描述符限制 ​ events {worker_connections 8192; # 每个worker的最大连接数multi_accept on; # 一次性接受…

[未验证]abaqus2022 更改内置python

如何在 Abaqus 2022 中更改内置 Python 在 Abaqus 中&#xff0c;Python 是常用的脚本语言&#xff0c;它使得用户能够自动化模型的创建、分析和后处理。可能有时候你需要更改默认的 Python 版本&#xff0c;比如使用特定库或者功能。本文将为您详细说明如何在 Abaqus 2022 中更…

RAG文档解析难点2:excel数据“大海捞针”,超大Excel解析与精准行列查询指南

写在前面 在构建检索增强生成(RAG)应用时,Excel文件是不可或缺的数据源。它们通常包含了企业运营、市场分析、科学研究等各个领域的宝贵数据。然而,当这些Excel文件变得“超大”——可能包含数十万甚至数百万行数据时,传统的解析方法和RAG数据处理流程将面临严峻的内存、…

深度掌控,智启未来 —— 基于 STM32F103RBT6 的控制板

在科技浪潮奔涌向前的时代&#xff0c;电子领域的创新发展从未停歇。对于电子工程师、科研工作者以及电子技术爱好者&#xff0c;在校电子专业学生而言&#xff0c;一款性能卓越、功能全面且稳定可靠的开发板&#xff0c;是探索电子世界奥秘、实现创意构想的关键基石。今天&…

什么样的登录方式才是最安全的?

目录 一、基础协议&#xff1a;HTTP与HTTPS HTTP协议 HTTPS协议 二、常见Web攻击与防御 2.1 XSS 常见攻击手段 针对XSS 攻击窃取 Cookie 2.2 CSRF CSRF攻击的核心特点 与XSS的区别 常见防御措施 三、疑问解答 四、登录方式演变 4.1 方案一&#x1f436;狗都不用 …

android studio底部导航栏

实现底部导航栏切换 将java文件return的xml文件赋值给页面FrameLayout控件 java文件BottomNavigationView&#xff0c;监听器setOnNavigationItemSelectedListener MainActivity.java代码 package com.example.myapplication;import android.os.Bundle;import androidx.appc…

vue-router相关理解

一、前言 随着 Vue.js 在前端开发中的广泛应用&#xff0c;Vue Router 成为了 Vue 官方推荐的路由管理器。它不仅支持单页面应用&#xff08;SPA&#xff09;中常见的路由跳转、嵌套路由、懒加载等功能&#xff0c;还提供了导航守卫、动态路由等高级特性。 本文将带你深入了解…

uni-app 自定义路由封装模块详解(附源码逐行解读)

&#x1f680;uni-app 自定义路由封装模块详解&#xff08;附源码逐行解读&#xff09; &#x1f4cc; 请收藏 点赞 关注&#xff0c;获取更多 uni-app 项目实用技巧&#xff01; 在实际 uni-app 项目中&#xff0c;我们常常需要对 uni.navigateTo、uni.switchTab 等 API 做…

QML显示图片问题解决办法

以前用qtwediget的时候&#xff0c;好像是放在qlabel或者什么组件上面&#xff0c;把图片的路径放上去就可以直接加载&#xff0c;但我用QML创建界面的时候就遇到了问题&#xff0c;哦对&#xff0c;qtwedget用qpixmap组件显示图片&#xff0c;也有image。话说回来&#xff0c;…

Vue中使用jsx

1. jsx的babel配置 1.1 在项目中使用jsx&#xff0c;需要添加对jsx的支持&#xff1a; jsx通常会通过Babel来进行转换(React编写的jsx就是通过babel转换的)Vue中&#xff0c;只需要在Babel中配置对应的插件即可以下列举需要支持转换的案例&#xff1a; template -> vue-l…

Spring Cache+Redis缓存方案 vs 传统redis缓存直接使用RedisTemplate 方案对比

结合 Spring Cache 和 Redis 的缓存方案&#xff08;即 Spring Cache Redis&#xff09;相较于普通的 Redis 缓存使用&#xff08;如直接通过 RedisTemplate 操作&#xff09;&#xff0c;具有以下显著优势&#xff1a; 具体实现方案请参考&#xff1a;Spring CacheRedis缓存…

Web应用安全漏洞扫描:原理、常用方法及潜在风险解析?

Web应用安全的关键环节在于进行漏洞扫描&#xff0c;这种扫描通过自动化或半自动化的方式&#xff0c;对应用进行安全测试。它能揭示出配置错误、代码缺陷等众多安全风险。接下来&#xff0c;我将详细阐述这些情况。 扫描原理 它主要模拟攻击者的行为&#xff0c;以探测和攻击…

Spring中@Value注解:原理、加载顺序与实战指南

文章目录 前言一、Value注解的核心原理1.1 容器启动阶段&#xff1a;环境准备1.2 Bean实例化阶段&#xff1a;后置处理器介入1.3 值解析阶段&#xff1a;双引擎处理1. 占位符解析&#xff08;${...}&#xff09;2. SpEL表达式解析&#xff08;#{...}&#xff09; 1.4 类型转换与…

MySQL 8配置文件详解

MySQL 8 配置文件详解 MySQL 8 的配置文件(my.cnf或my.ini)是MySQL服务器启动时读取的主要配置文件&#xff0c;它包含了服务器运行所需的各种参数设置。以下是MySQL 8配置文件的详细解析&#xff1a; 配置文件位置 MySQL 8 会按照以下顺序查找配置文件&#xff1a; /etc/m…