大白话react第十九章React 与 WebGL 项目的深度拓展和优化

ops/2025/3/15 4:22:06/

大白话react第十九章React 与 WebGL 项目的深度拓展和优化

1. 实现 VR/AR 交互体验

在 3D 网页应用里加入虚拟现实(VR)或者增强现实(AR)功能,能让用户有更沉浸的体验。就好比用户戴上 VR 眼镜,就能感觉自己身处 3D 场景之中;使用 AR 时,能把虚拟物体叠加到现实世界里。我们使用 three.jswebxr 来实现这些功能。

// 引入 React 的 useEffect 和 useRef 钩子
import React, { useEffect, useRef } from'react';
// 引入 three.js 用于创建 3D 场景
import * as THREE from 'three';
// 引入 OrbitControls 用于控制相机视角
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';const VRARComponent = () => {// 创建一个 ref 用于引用存放 3D 场景的 DOM 元素const containerRef = useRef(null);useEffect(() => {// 创建 three.js 的场景const scene = new THREE.Scene();// 创建透视相机,设置视角、宽高比、近裁剪面和远裁剪面const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建 WebGL 渲染器,并开启 XR 支持const renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);renderer.xr.enabled = true; // 将渲染器的 DOM 元素添加到 ref 对应的 DOM 元素中containerRef.current.appendChild(renderer.domElement);// 创建一个立方体几何体const geometry = new THREE.BoxGeometry();// 创建一个基本材质,颜色为蓝色const material = new THREE.MeshBasicMaterial({ color: 0x0000ff });// 创建一个网格对象,将几何体和材质组合在一起const cube = new THREE.Mesh(geometry, material);// 将立方体添加到场景中scene.add(cube);// 设置相机位置camera.position.z = 5;// 创建轨道控制器,方便用户在普通模式下控制相机视角const controls = new OrbitControls(camera, renderer.domElement);// 定义渲染函数const animate = () => {// 请求下一帧动画renderer.setAnimationLoop(() => {// 让立方体绕 x 轴和 y 轴旋转cube.rotation.x += 0.01;cube.rotation.y += 0.01;// 渲染场景renderer.render(scene, camera);});};// 开始动画循环animate();// 创建一个按钮用于进入 VR 模式const vrButton = document.createElement('button');vrButton.textContent = '进入 VR 模式';vrButton.addEventListener('click', async () => {try {await renderer.xr.setSession(await navigator.xr.requestSession('immersive-vr'));} catch (error) {console.error('无法启动 VR 会话:', error);}});containerRef.current.appendChild(vrButton);// 组件卸载时清理资源return () => {containerRef.current.removeChild(renderer.domElement);containerRef.current.removeChild(vrButton);};}, []);return (// 创建一个 div 用于存放 3D 场景<div ref={containerRef} />);
};export default VRARComponent;
2. 进行大规模场景优化

当场景里的物体数量特别多的时候,渲染会变得很慢。我们可以通过分层渲染、遮挡剔除等方法来优化性能,让大规模场景也能流畅显示。这里我们简单模拟一下分层渲染的思路。

// 引入 React 的 useEffect 和 useRef 钩子
import React, { useEffect, useRef } from'react';
// 引入 three.js 用于创建 3D 场景
import * as THREE from 'three';const LargeScaleSceneComponent = () => {// 创建一个 ref 用于引用存放 3D 场景的 DOM 元素const containerRef = useRef(null);useEffect(() => {// 创建 three.js 的场景const scene = new THREE.Scene();// 创建透视相机,设置视角、宽高比、近裁剪面和远裁剪面const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建 WebGL 渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);// 将渲染器的 DOM 元素添加到 ref 对应的 DOM 元素中containerRef.current.appendChild(renderer.domElement);// 创建多个层,用于分层渲染const layer1 = new THREE.Group();const layer2 = new THREE.Group();scene.add(layer1);scene.add(layer2);// 在第一层添加一些立方体for (let i = 0; i < 10; i++) {const geometry = new THREE.BoxGeometry();const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });const cube = new THREE.Mesh(geometry, material);cube.position.x = i * 2;layer1.add(cube);}// 在第二层添加一些球体for (let i = 0; i < 10; i++) {const geometry = new THREE.SphereGeometry(0.5, 32, 32);const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });const sphere = new THREE.Mesh(geometry, material);sphere.position.x = i * 2;layer2.add(sphere);}// 设置相机位置camera.position.z = 15;// 定义渲染函数const animate = () => {// 请求下一帧动画requestAnimationFrame(animate);// 渲染场景renderer.render(scene, camera);};// 开始动画循环animate();// 组件卸载时清理资源return () => {containerRef.current.removeChild(renderer.domElement);};}, []);return (// 创建一个 div 用于存放 3D 场景<div ref={containerRef} />);
};export default LargeScaleSceneComponent;
3. 实现实时阴影与动态光照

让场景里的阴影和光照能随着物体的移动实时变化,这样场景会更真实。我们可以利用 three.js 的光照和阴影功能来实现。

// 引入 React 的 useEffect 和 useRef 钩子
import React, { useEffect, useRef } from'react';
// 引入 three.js 用于创建 3D 场景
import * as THREE from 'three';const RealTimeShadowsComponent = () => {// 创建一个 ref 用于引用存放 3D 场景的 DOM 元素const containerRef = useRef(null);useEffect(() => {// 创建 three.js 的场景const scene = new THREE.Scene();// 创建透视相机,设置视角、宽高比、近裁剪面和远裁剪面const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建 WebGL 渲染器,并开启阴影支持const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMap.enabled = true;// 将渲染器的 DOM 元素添加到 ref 对应的 DOM 元素中containerRef.current.appendChild(renderer.domElement);// 创建一个平面几何体,作为地面const planeGeometry = new THREE.PlaneGeometry(10, 10);// 创建平面的材质const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 });// 创建平面的 3D 模型const plane = new THREE.Mesh(planeGeometry, planeMaterial);plane.rotation.x = -Math.PI / 2;// 设置平面接收阴影plane.receiveShadow = true;scene.add(plane);// 创建一个立方体几何体const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);// 创建立方体的材质const cubeMaterial = new THREE.MeshStandardMaterial({ color: 0x0000ff });// 创建立方体的 3D 模型const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);cube.position.y = 0.5;// 设置立方体投射阴影cube.castShadow = true;scene.add(cube);// 创建一个聚光灯,用于产生阴影和光照const spotLight = new THREE.SpotLight(0xffffff, 1);spotLight.position.set(2, 5, 2);spotLight.castShadow = true;scene.add(spotLight);// 设置相机位置camera.position.z = 5;// 定义渲染函数const animate = () => {// 请求下一帧动画requestAnimationFrame(animate);// 让立方体在 x 轴上移动,模拟动态效果cube.position.x = Math.sin(Date.now() * 0.001) * 2;// 渲染场景renderer.render(scene, camera);};// 开始动画循环animate();// 组件卸载时清理资源return () => {containerRef.current.removeChild(renderer.domElement);};}, []);return (// 创建一个 div 用于存放 3D 场景<div ref={containerRef} />);
};export default RealTimeShadowsComponent;

通过这些功能的实现,你的 React 和 WebGL 项目会变得更加高级和炫酷,给用户带来更好的体验。


http://www.ppmy.cn/ops/165844.html

相关文章

【我的 PWN 学习手札】House of Pig

House Of Pig House of Pig是利用tcache stash unlink与largebin attack攻击IO_FILE共同实现的一种手法&#xff0c;一般来说利用得到的任意地址写能力往hook上写数据&#xff0c;从而完成对程序流的劫持。 一、关键源码分析&#xff1a;_IO_str_overflow const struct _IO_…

前端学习笔记(三)——ant-design vue表单传递数据到父页面

前言 善用AI&#xff0c;快速解决定位 原理 a-form所在的SFC&#xff08;单文件&#xff09;vue中需要将表单数据传递给父页面SFC文件中&#xff0c;使用emit方法 代码 子组件&#xff08;Form.vue&#xff09; <template><a-form submit"handleSubmit&qu…

Redis 设置密码(配置文件、docker容器、命令行3种场景)

现在没有配置密码的 Redis&#xff0c;一般来说&#xff0c;已经被很多安全检测系统视为漏洞和问题了&#xff0c;官方的 Redis 默认是关闭密码的&#xff0c;如果需要设置密码&#xff0c;目前应用场景来说可以分为三种&#xff0c;如下&#xff1a; 1、基于配置文件的 通过…

用 Vue 3.5 TypeScript 做了一个日期选择器(改进版)

上一篇 已经实现了一个日期选择器&#xff0c;只不过是模态窗的形式&#xff0c;这个版本改为文本框弹出&#xff0c;点击空白处可关闭日历 代码也增加了不少 <template><div><!-- 添加文本框 --><div class"date-picker-input-wrapper">&l…

Java 实现 Android ViewPager2 顶部导航:动态配置与高效加载指南

Java 实现&#xff1a;明确使用的编程语言。Android ViewPager2&#xff1a;技术栈和核心组件。顶部导航&#xff1a;功能点。动态配置与高效加载指南&#xff1a;突出动态配置的灵活性和性能优化的重点。 在 Android 中使用 Java 实现 ViewPager2 和 TabLayout 的顶部导航也是…

【前端】如何在HTML中调用CSS和JavaScript(完整指南)

文章目录 前言一、HTML调用CSS1. 内联样式&#xff08;Inline Style&#xff09;2. 内部样式表&#xff08;Internal Stylesheet&#xff09;3. 外部样式表&#xff08;External Stylesheet&#xff09; 二、HTML调用JavaScript1. 内联脚本&#xff08;Inline Script&#xff0…

C语言数据结构:数组

1. 数组&#xff08;Array&#xff09; 1.1 定义 数组是一种线性数据结构&#xff0c;由相同类型的元素组成&#xff0c;这些元素在内存中按顺序存储。数组的大小在声明时确定&#xff0c;且不可动态改变。 1.2 类型细分 根据维度和用途&#xff0c;数组可以分为以下几种类型…

Spring BOOT 启动参数

Spring BOOT 启动参数 在Java Web的开发完成后&#xff0c;以前我们都会打包成war文件&#xff0c;然后放大web容器&#xff0c;比如tomcat、jetty这样的容器。现在基于SpringBoot开发的项目&#xff0c;我们直接打包成jar文件&#xff0c;基于内嵌的tomcat来实现一样的效果。…