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

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

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

猜你喜欢

转载自blog.csdn.net/weixin_43835425/article/details/131739263