Three.js环境光,平行光,点光源,聚光灯的创建和灯光辅助线的使用

news2024/11/19 3:45:50

Three.js中的灯光API使用

1.环境光(AmbientLight)2.平行光(directionalLight)3.PointLight(点光源) 4.聚光灯(SpotLight)5.材质平面(PlaneGeometry)用于接收(平行光和聚光灯的光源)

首页在上一篇 Three.js加载外部glb,fbx,gltf,obj 模型文件 的文章基础上新加入一个创建 灯光的函数 createLight 方法

	// 创建光源
	createLight() {
		// 创建环境光
		this.ambientLight = new THREE.AmbientLight('#fff', .8)
		this.scene.add(this.ambientLight)

		// 创建平行光
		this.directionalLight = new THREE.DirectionalLight('#1E90FF', 1)
		this.directionalLight.position.set(-1.44, 2.2, 1)
		this.directionalLight.castShadow = true
		this.directionalLight.visible = false
		this.scene.add(this.directionalLight)
		// 创建平行光辅助线
		this.directionalLightHelper = new THREE.DirectionalLightHelper(this.directionalLight, .5)
		this.directionalLightHelper.visible = false
		this.scene.add(this.directionalLightHelper)

		// 创建点光源
		this.pointLight = new THREE.PointLight(0xff0000, 1, 100)
		this.pointLight.visible = false
		this.scene.add(this.pointLight)
		// 创建点光源辅助线
		this.pointLightHelper = new THREE.PointLightHelper(this.pointLight, .5)
		this.pointLightHelper.visible = false
		this.scene.add(this.pointLightHelper)

		//  创建聚光灯
		this.spotLight = new THREE.SpotLight('#323636', 440);
		this.spotLight.visible = false
		this.spotLight.map = new THREE.TextureLoader().load(require('@/assets/image/model-bg-1.jpg'));
		this.spotLight.decay = 2;
		this.spotLight.shadow.mapSize.width = 1920;
		this.spotLight.shadow.mapSize.height = 1080;
		this.spotLight.shadow.camera.near = 1;
		this.spotLight.shadow.camera.far = 10;
		this.scene.add(this.spotLight);
		//创建聚光灯辅助线
		this.spotLightHelper = new THREE.SpotLightHelper(this.spotLight);
		this.spotLightHelper.visible = false
		this.scene.add(this.spotLightHelper)

		// 模型平面
		const geometry = new THREE.PlaneGeometry(4, 4);
		var groundMaterial = new THREE.MeshStandardMaterial({ color: '#939393' });
		this.planeGeometry = new THREE.Mesh(geometry, groundMaterial);
		this.planeGeometry.rotation.x = -Math.PI / 2
		this.planeGeometry.position.set(0, -.59, 0)
		// 让地面接收阴影
		this.planeGeometry.receiveShadow = true;
		this.planeGeometry.visible = false
		this.scene.add(this.planeGeometry);
	}

完整的代码

import * as THREE from 'three' //导入整个 three.js核心库
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' 
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
// 定义一个 class类
class renderModel {
    	constructor(selector) {
    	    this.container = document.querySelector(selector)
		    // 相机
	    	this.camera
		    // 场景
		    this.scene
		    //渲染器
		    this.renderer
		    // 控制器
		    this.controls
		    // 模型
		    this.model    
		     //文件加载器类型
		    this.fileLoaderMap = {
			'glb': new GLTFLoader(),
			'fbx': new FBXLoader(),
			'gltf': new GLTFLoader(),
			'obj': new OBJLoader(),
		   }
		   	// 环境光
		   this.ambientLight
	     	//平行光
		   this.directionalLight
		    // 平行光辅助线
		   this.directionalLightHelper
		     // 点光源
		   this.pointLight
		    //点光源辅助线
		   this.pointLightHelper
		    //聚光灯
		   this.spotLight
		    //聚光灯辅助线
		   this.spotLightHelper
		    //模型平面
		   this.planeGeometry
        }
         // 初始化加载模型方法
        init(){
         	return new Promise(async (reslove, reject) => {
			//初始化场景
			this.initScene()
			//初始化相机
			this.initCamera()
			//初始化渲染器
			this.initRender()
			 // 创建灯光
			this.createLight()
			// 添加物体模型 TODO:初始化时需要默认一个  filePath:'threeFile/glb/glb-3.glb' 放在 vue项目中的public/threeFile文件下
			const load = await this.setModel({ filePath: 'threeFile/glb/glb-3.glb', fileType: 'glb',scale:0.5})
			//监听场景大小改变,跳转渲染尺寸
			window.addEventListener("resize", this.onWindowResize.bind(this))
			//场景渲染
			this.sceneAnimation()
			reslove(load)
	   	  })
        }
        //创建场景
	initScene() {
		this.scene = new THREE.Scene()
		//创建一个球体 用于映射全景图
		const sphereBufferGeometry = new THREE.SphereGeometry(40, 32, 16);
		sphereBufferGeometry.scale(-1, -1, -1);
		const material = new THREE.MeshBasicMaterial({
			map: new THREE.TextureLoader().load(require('@/assets/image/view-1.png'))
		});
		//设置场景全景图
		this.viewMesh = new THREE.Mesh(sphereBufferGeometry, material);
	     //添加场景
		this.scene.add(this.viewMesh);
	}
		// 创建相机
	initCamera() {
		const { clientHeight, clientWidth } = this.container
		this.camera = new THREE.PerspectiveCamera(45, clientWidth / clientHeight, 0.25, 100)
	}
	 // 创建渲染器
	initRender() {
		this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) //设置抗锯齿
		//设置屏幕像素比
		this.renderer.setPixelRatio(window.devicePixelRatio)
		//渲染的尺寸大小
		const { clientHeight, clientWidth } = this.container
		this.renderer.setSize(clientWidth, clientHeight)
		//色调映射
		this.renderer.toneMapping = THREE.ACESFilmicToneMapping
		//曝光
		this.renderer.toneMappingExposure = 3
		this.renderer.shadowMap.enabled = true
		this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
		this.container.appendChild(this.renderer.domElement)
	}
	// 使用动画器不断更新场景
	 sceneAnimation() {
		this.renderer.setAnimationLoop(this.render.bind(this))
	 }
     //渲染场景
	render(){
	  this.renderer.render(this.scene, this.camera)
	}
	//加载模型
	setModel({ filePath, fileType, scale,  position }) {
		return new Promise((resolve, reject) => {
			const loader = this.fileLoaderMap[fileType]
			loader.load(filePath, (result) => {
			  //加载不同类型的文件
				switch (fileType) {
					case 'glb':
						this.model = result.scene		
						break;
					case 'fbx':
						this.model = result
						break;
					case 'gltf':
						this.model = result.scene
						break;
					case 'obj':
						this.model = result
						break;
					default:
						break;
				}
				// 设置模型大小
				if (scale) {
					this.model.scale.set(scale, scale, scale);
				}
				// 设置模型位置 
				if (position) {
					const { x, y, z } = position
					this.model.position.set(x, y, z)
				}
				// 设置相机位置
				this.camera.position.set(0, 2, 6)
				// 设置相机坐标系
				this.camera.lookAt(0, 0, 0)
	             // 将模型添加到场景中去   
				this.scene.add(this.model)
				resolve(true)
			}, () => {

			}, (err) => {
				console.log(err)
				reject()
			})
		})
	}
		// 创建光源
	createLight() {
		// 创建环境光
		this.ambientLight = new THREE.AmbientLight('#fff', .8)
		this.scene.add(this.ambientLight)

		// 创建平行光
		this.directionalLight = new THREE.DirectionalLight('#1E90FF', 1)
		this.directionalLight.position.set(-1.44, 2.2, 1)
		this.directionalLight.castShadow = true
		this.directionalLight.visible = false
		this.scene.add(this.directionalLight)
		// 创建平行光辅助线
		this.directionalLightHelper = new THREE.DirectionalLightHelper(this.directionalLight, .5)
		this.directionalLightHelper.visible = false
		this.scene.add(this.directionalLightHelper)

		// 创建点光源
		this.pointLight = new THREE.PointLight(0xff0000, 1, 100)
		this.pointLight.visible = false
		this.scene.add(this.pointLight)
		// 创建点光源辅助线
		this.pointLightHelper = new THREE.PointLightHelper(this.pointLight, .5)
		this.pointLightHelper.visible = false
		this.scene.add(this.pointLightHelper)

		//  创建聚光灯
		this.spotLight = new THREE.SpotLight('#323636', 440);
		this.spotLight.visible = false
		this.spotLight.map = new THREE.TextureLoader().load(require('@/assets/image/model-bg-1.jpg'));
		this.spotLight.decay = 2;
		this.spotLight.shadow.mapSize.width = 1920;
		this.spotLight.shadow.mapSize.height = 1080;
		this.spotLight.shadow.camera.near = 1;
		this.spotLight.shadow.camera.far = 10;
		this.scene.add(this.spotLight);
		//创建聚光灯辅助线
		this.spotLightHelper = new THREE.SpotLightHelper(this.spotLight);
		this.spotLightHelper.visible = false
		this.scene.add(this.spotLightHelper)

		// 模型平面
		const geometry = new THREE.PlaneGeometry(4, 4);
		let  groundMaterial = new THREE.MeshStandardMaterial({ color: '#939393' });
		this.planeGeometry = new THREE.Mesh(geometry, groundMaterial);
		this.planeGeometry.rotation.x = -Math.PI / 2
		this.planeGeometry.position.set(0, -.59, 0)
		// 让地面接收阴影
		this.planeGeometry.receiveShadow = true;
		this.planeGeometry.visible = false
		this.scene.add(this.planeGeometry);
	}
}

完整的代码可参考:https://gitee.com/ZHANG_6666/Three.js3D

界面效果:
在这里插入图片描述

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

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

相关文章

【边缘计算】【第一章 什么是边缘计算】

边缘计算 序第一章 什么是边缘计算概念章鱼说应用场景数据单位转换边缘计算的前世今生CDN(Content Delivery Network)内容分发网络微云(Cloudlet)雾计算——雾是接近地面的云MEC边缘计算大事记 边缘计算核心技术概述1 网络技术2 隔…

explain 是干嘛的

explain 是干嘛的 1.explain的作用 在MySQL中,EXPLAIN是一个用于查询优化的关键字。它可以用于分析查询语句的执行计划,帮助开发人员和数据库管理员理解查询的执行方式、查询涉及的表和索引、连接类型、查询优化器的决策等信息。 通过使用EXPLAIN关键…

智慧团建登录或忘记密码刷不出验证码

问题如下: 忘记密码和登录时没有验证码 原因:智慧团建的服务器端只放行不带“www.”的域名,一般zf或者其他jg系统都会限制万维网的进入 解决办法: 删掉“www.”,然后重新回车访问或者直接点我下边的链接:…

PyTorch翻译官网教程6-AUTOMATIC DIFFERENTIATION WITH TORCH.AUTOGRAD

官网链接 Automatic Differentiation with torch.autograd — PyTorch Tutorials 2.0.1cu117 documentation 使用TORCH.AUTOGRAD 自动微分 当训练神经网络时,最常用的算法是方向传播算法。在该算法中,根据损失函数与给定参数的梯度来调整模型参数&…

机器学习---定义、用途、算法的分类、假设空间与归纳偏好、奥卡姆剃刀原则

1. 机器学习的定义 基于历史经验的,描述和预测的理论、方法和算法。 从历史数据中,发现某些模式或规律(描述),利用发现的模式和规律进行预测。 2. 机器学习能做什么 机器学习已经有了十分广泛的应用,例…

pdf文件大小如何压缩?pdf文件怎么压缩得更小?

日常生活和工作中,经常用到图片,但是有时候需要将图片压缩指定大小来符合各种规定,比如图片压缩到200kb,那么有没有简单方便的图片压缩( https://www.yasuotu.com/imagesize)的方法呢?下面就拿压…

【测试开发】案例分析

目录 一. 模拟弱网 二. 接口测试 三. 对冒泡排序进行测试 四. 对于 Linux 命令进行测试 五. 微信发送朋友圈设计测试用例 六. 补充 一. 模拟弱网 模拟弱网环境可以借助 Fiddler 来进行; 1. 先要打开 Simulate Modem Speeds 选项; 2. 打开 Customize R…

一起学SF框架系列5.8-模块Beans-注解bean解析1-解析入口

前面跟踪了Spring框架如何解析xml模式配置的bean解析(参见“一起学SF框架系列5.7-模块Beans-BeanDefinition解析”),本文主要解析注解bean(详见“一起学SF框架系列5.2-模块Beans-bean的元数据配置”)是如何被Spring框架…

scripy其他

持久化 # 爬回来,解析完了,想存储,有两种方案 ## 方案一:一般不用 parse必须有return值,必须是列表套字典形式--->使用命令,可以保存到json格式中,csv中scrapy crawl cnblogs -o cnbogs.j…

IEEE WCCI-2020电动汽车路由问题进化计算竞赛的基准集

引言 交通一直是二氧化碳排放的主要贡献者。由于全球变暖、污染和气候变化,联邦快递、UPS、DHL和TNT等物流公司对环境变得更加敏感,他们正在投资于减少作为其日常运作的一部分而产生的二氧化碳排放的方法。毫无疑问,使用电动汽车(…

JavaWeb——Linux的常用命令

目录 一、Linux优点 二、Linux常用命令 1、ls (1)、语法 (2)、功能 (3)、常用选项 例: 2、pwd (1)、语法 (2)、功能 例: 3、cd (1&am…

Doc as Code (1):起源

作为技术传播从业者,你一定听说过Doc as Code,中文大家叫做文档代码化。 近年来,这个词在技术传播行业传开了。也许是在某个大会上,也许是在某篇文章中,再或者是在与同行的讨论群里,不管是从哪里&#xff…

DAY47:动态规划(九)完全背包理论基础

文章目录 完全背包示例与01背包的区别:遍历顺序常规遍历写法DP状态图-为什么背包正序就能放进来重复物品 for循环的嵌套,外层物品内层背包能否颠倒?for嵌套顺序颠倒的遍历写法 测试示例面试题目总结 课程链接: 代码随想录 (progr…

自动生成spring-configuration-metadata.json文件

在开发过程中为避免重复修改代码,往往将代码中容易发生变更的值提取出来放到配置文件中。例如数据库连接信息,使用Http调用第三方应用的网关地址等信息。 使用Sprin Boot的ConfigurationPropertie 从配置文件中读取属性值方法多样,这里介绍…

【反向代理】反向代理及其作用

反向代理及其作用 一、什么是正向代理 在介绍反向代理之前我们先介绍什么是正向代理 首先要明确的是,在http协议中正向代理一般被称为代理,在web服务中我们可以通过主动配置代理服务器的方式来发送请求,并通过代理服务器接收服务器的响应。…

自学网络安全(成为黑客)

一、前言 黑客这个名字一直是伴随着互联网发展而来,给大家的第一印象就是很酷,而且技术精湛,在网络世界里无所不能。目前几乎所有的公司企业甚至国家相关部门都会争相高薪聘请技术精湛的黑客作为互联网机构的安全卫士,所以黑客也…

umi框架的使用

umi框架的使用 安装npm i -g yrm 查看yarn镜像源yrm ls 切换源 yrm use taobao 创建项目 yarn create umijs/umi-app 安装依赖yarn 启动项目yarn start 路由组件还可以进行children进行子路由渲染 打个比方,现在有头部导航跟侧边是一致的我们只希望修改每个应…

Mybatis-Plus详解

目录 一、Mybatis-Plus简介 (一)什么是Mybatis-Plus (二)Mybatis-Plus的优势 (三)Mybatis-Plus的框架结构 二、SpringBoot整合Mybatis-Plus入门 (一)创建maven工程,…

爬虫+Flask+Echarts搭建《深度学习》书评显示大屏

爬虫FlaskEcharts搭建《深度学习》书评显示大屏 1、前言2、实现2.1 挑选想要采集的书籍2.2 构建爬虫2.2.1 采集书籍信息2.2.2 采集书评 2.3 数据清洗2.3.1 清洗书籍信息2.3.2 清洗书评信息 2.4 统计分析,结果持久化存储2.5 搭建flask框架2.6 数据传值2.7 完整代码&a…

什么是Nginx的反向代理与正向代理详解

文章目录 1、什么是正向代理2、什么是反向代理3、反向代理的作用 1、什么是正向代理 正向代理,“它代理的是客户端”,是一个位于客户端和目标服务器之间的服务器,为了从目标服务器取得内容,客户端向代理服务器发送一个请求并指定…