当前位置: 首页 > news >正文

ThreejsWebGPU运动残影demo

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

功能点
实例化SkinnedMesh
修改NodeMaterial着色器
节点材质系统 shader 语言 使用uniform和attribute
中合其他几篇博客中的内容
在这里插入图片描述

代码仓库
克隆后需要放到three源码同级别目录下 运行 three源码部分不在git仓库中(太大了)
使用vscode的live-server启动后访问
http://127.0.0.1:5501/demo/webgpu_skinning_instancing/webgpu_skinning_instancing.html

在这里插入图片描述

html部分

<!--* @Author: hongbin* @Date: 2024-07-30 07:48:37* @LastEditors: hongbin* @LastEditTime: 2024-08-12 22:03:13* @Description: 
-->
<!DOCTYPE html>
<html lang="en"><head><title>three.js webgpu - skinning instancing</title><meta charset="utf-8" /><metaname="viewport"content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" /><linktype="text/css"rel="stylesheet"href="../../three.js/examples/main.css" /></head><body><div id="info"><ahref="https://threejs.org"target="_blank"rel="noopener">three.js</a>webgpu - skinning instancing</div><script type="importmap">{"imports": {"three": "./three.webgpu.js","three/tsl": "./three.webgpu.js","three/addons/": "../../three.js/examples/jsm/"}}</script><script type="module">import * as THREE from "three";import {pass,mix,range,color,oscSine,timerLocal,texture,TextureNode,normalLocal,min,max,abs,uniform,floor,float,nodeObject,instanceIndex,buffer,varyingProperty,int,instancedBufferAttribute,instancedDynamicBufferAttribute,vec3,reference,} from "three/tsl";import { GUI } from "three/addons/libs/lil-gui.module.min.js";import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";import { OrbitControls } from "three/addons/controls/OrbitControls.js";import { RectAreaLightHelper } from "three/addons/helpers/RectAreaLightHelper.js";import { RectAreaLightTexturesLib } from "three/addons/lights/RectAreaLightTexturesLib.js";import TWEEN from "three/addons/libs/tween.module.js";let camera, scene, renderer, controls;let postProcessing, gui;let clock, delta;let dir = 1;let mixer, skinningInstanceMatrices;let mixer2, skinningInstanceMatrices2;let mixer3, skinningInstanceMatrices3;const tt = uniform(0, "float");const ttI = uniform(0, "float");class SkinningInstanceMatrices {constructor(mesh, count = 2, delay = 5,useTween = false) {this.mesh = mesh;this.count = count;this.delay = 0.016 * delay;this.time = 0;this.useTween = useTween;// const params = {opacity:1};//     new TWEEN.Tween(params)//         .to({ opacity: 0 }, 1000)//         .onUpdate(function () {//             console.log(new Date().getSeconds(),params.opacity)//         })//         .start();}setStatus(status = 1) {this.isFinished = !status;// this.mesh.setOmitOneOpacity && this.mesh.setOmitOneOpacity(status);const params = { opacity: 1 - status };new TWEEN.Tween(params).to({ opacity: status }, 16 * 10).onUpdate(() => {this.mesh.setOmitOneOpacity && this.mesh.setOmitOneOpacity(params.opacity);}).start();}start() {this.setStatus(1);}isFinished = false;/* 动画播放完 隐藏其他实例 */finished() {this.setStatus(0);}prevAction(delta) {this.time += delta;if (this.time > this.delay && !this.isFinished) {for (let i = this.count; i >= 1; i--) {this.syncOnes(i, i - 1);// if (this.useTween) {//     const params = { opacity: 1 };//     new TWEEN.Tween(params)//         .to({ opacity: 0 }, this.delay * 1000)//         .onUpdate(() => {//             this.mesh.setOpacity && this.mesh.setOpacity(i, params.opacity);//         })//         .start();// }}// this.syncOnes(3, 2);// this.syncOnes(2, 1);// this.syncOnes(1);this.time = 0;// const params = {opacity:1};// new TWEEN.Tween(params)//     .to({ opacity: 0 }, this.delay * 1000)//     .onUpdate(function () {//         // console.log(params.opacity)//         window.setInstanceOpacity && window.setInstanceOpacity(1,params.opacity)//         window.setInstanceOpacity && window.setInstanceOpacity(2,params.opacity)//     })//     .start();}}syncOnes(index, copyIndex = 0) {const length = this.mesh.skeleton.bones.length;const copyIndexLeft = 16 * copyIndex * length;// const end = 16 * (index + 1) * length;const left = 16 * index * length;// for (let index = left, i = 0; index < end; index++, i++) {//     this.mesh.skeleton.boneMatrices[index] = this.mesh.skeleton.boneMatrices[i + copyIndexLeft];// }//使用内置方法 避免遍历 TypedArray.copyWithin(target start end) https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin// this.mesh.skeleton.boneMatrices.copyWithin(copyIndexLeft, 0, length * 16);this.mesh.skeleton.boneMatrices.copyWithin(left, copyIndexLeft, copyIndexLeft + length * 16);}syncIndex(index) {requestAnimationFrame(() => {this.syncIndex(index);});this.syncOnes(index);// const { count } = this.mesh;// const length = this.mesh.skeleton.bones.length;// const end = 16 * (index + 1) * length;// const left = 16 * index * length;// for (let index = left, i = 0; index < end; index++, i++) {//     this.mesh.skeleton.boneMatrices[index] = this.mesh.skeleton.boneMatrices[i];// }}}init();window.offsetCount = 1040;function init() {gui = new GUI();window.stopAnimation = false;gui.add(window, "stopAnimation");THREE.RectAreaLightNode.setLTC(RectAreaLightTexturesLib.init());camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.01, 40);// camera.position.set( 1, 2, 3 );camera.position.set(0, 0, 0);scene = new THREE.Scene();// scene.add(new THREE.AxesHelper(1));camera.lookAt(0, 1, 0);clock = new THREE.Clock();// lights{const centerLight = new THREE.PointLight(0xff9900, 2, 100);centerLight.position.y = 4.5;centerLight.power = 400;// scene.add(centerLight);const cameraLight = new THREE.PointLight(0xffffff, 1, 100);cameraLight.power = 400;cameraLight.position.set(0, 2, 3);// camera.add(cameraLight);// scene.add(camera);// scene.add(cameraLight);const rectLight1 = new THREE.RectAreaLight(0xffffff, 10, 100, 0.5);rectLight1.position.set(0, 2, 0);rectLight1.lookAt(0, -1, 0);scene.add(rectLight1);{const rectLight1 = new THREE.RectAreaLight(0xffffff, 1, 10, 0.5);rectLight1.position.set(0, 2.1, 0);rectLight1.lookAt(0, -1, 0);scene.add(rectLight1);}{const rectLight1 = new THREE.RectAreaLight(0xffffff, 10, 10, 0.1);rectLight1.position.set(0, 0, 2);rectLight1.lookAt(0, 0, 0);scene.add(rectLight1);}scene.add(new RectAreaLightHelper(rectLight1));}const thickness = 10;const geometry = new THREE.BoxGeometry(100, 2, thickness);geometry.translate(0, 0, -thickness / 2);geometry.rotateX(-Math.PI / 2);const floorMesh = new THREE.Mesh(geometry,new THREE.MeshStandardMaterial({color: 0x000000,roughness: 1,metalness: 0.6,}));scene.add(floorMesh);// {//     const floorMesh = new THREE.Mesh(//         new THREE.BoxGeometry(0.1, 0.1, 0.1),//         new THREE.MeshStandardMaterial({//             color: 0xff0000,//             roughness: 0,//             metalness: 0,//         })//     );//     floorMesh.position.set(0, 1, 1);//     scene.add(floorMesh);// }{const geometry = new THREE.BoxGeometry(100, 2.4, 2);const map = new THREE.TextureLoader().load("../../three.js/examples/textures/carbon/Carbon.png");const normalMap = new THREE.TextureLoader().load("../../three.js/examples/textures/carbon/Carbon_Normal.png");map.colorSpace = THREE.SRGBColorSpace;normalMap.wrapS = map.wrapS = THREE.RepeatWrapping;normalMap.wrapT = map.wrapT = THREE.RepeatWrapping;map.repeat.set(60, 1);normalMap.repeat.copy(map.repeat);const box = new THREE.Mesh(geometry,new THREE.MeshStandardMaterial({color: 0xffffff,// color: 0x666666,roughness: 0.3,metalness: 0.7,map,normalMap,}));box.position.z = -2;box.position.y = 1.2;scene.add(box);}const loader = new GLTFLoader();loader.load("../../three.js/examples/models/gltf/Michelle.glb", function (gltf) {const danceGUI = gui.addFolder("跳舞");const object = gltf.scene;mixer = new THREE.AnimationMixer(object);const action = mixer.clipAction(gltf.animations[0]);action.play();const instanceCount = 10;const dummy = new THREE.Object3D();object.traverse(child => {if (child.isMesh) {skinningInstanceMatrices = new SkinningInstanceMatrices(child);const oscNode = abs(oscSine(timerLocal(0.1)));// const oscNode = abs(oscSine(timerLocal(1)));// const oscNode = abs(timerLocal(1).sin());const indexNode = floor(oscNode.div(0.3333334));// const oscNode = oscSine(timerLocal(0.1));const randomColors = range(new THREE.Color(0x000000), new THREE.Color(0xffffff));const randomMetalness = range(0, 1);const prevMap = child.material.map;// 设置 false 不计入 视椎体可见范围计算 避免被隐藏  椎体计算 一般使用object.boundingSpherechild.frustumCulled = false;// 显示卡通边框child.CartoonBorder = true;child.cartoonBorder = uniform(0.2);child.cartoonBorderColor = uniform(new THREE.Color("#ffffff"));child.CartoonBorderLight = uniform(vec3(0, 0, 1), "vec3");// child.CartoonBorderLight = uniform(camera.position,'vec3');danceGUI.add(child.cartoonBorder, "value", 0, 1).name("cartoonBorder");danceGUI.add(skinningInstanceMatrices, "delay", 0, 0.2).name("speed");danceGUI.addColor({ color: "#" + child.cartoonBorderColor.value.getHexString() }, "color").onChange(c => {const newColor = new THREE.Color(c);child.cartoonBorderColor.value.copy(newColor);});child.material = new THREE.MeshStandardNodeMaterial({transparent: true,side: 0,});// child.material.onBeforeCompile = (shader) => {// 	console.log("onBeforeCompile:", shader);// };// roughnessNode是变化的 roughness是固定的// child.material.roughnessNode = oscNode;// child.material.metalnessNode = 0.5 || mix(0.0, randomMetalness, oscNode);// child.material.colorNode = mix(texture(prevMap), randomColors, oscNode);child.material.colorNode = texture(prevMap);child.isInstancedMesh = true;child.instanceMatrix = new THREE.InstancedBufferAttribute(new Float32Array(instanceCount * 16),16);// 透明度const floatOpacity = new Float32Array(instanceCount);const buffer = new THREE.InstancedBufferAttribute(floatOpacity, 1);console.log(buffer);// instancedDynamicBufferAttribute 每次写入buffer// instancedBufferAttribute 手动更新 needsUpdate = truechild.instanceOpacity = instancedBufferAttribute(buffer);window.setInstanceOpacity = (index, opacity) => {floatOpacity[index] = opacity;buffer.needsUpdate = true;};// child.instanceOpacity = new THREE.InstancedBufferAttribute(//     new Float32Array(instanceCount),//     1// );// child.instanceOpacity.setUsage(THREE.DynamicDrawUsage);// 索引 attributeconst floatIndex = new Float32Array(instanceCount);const indexBuffer = new THREE.InstancedBufferAttribute(floatIndex, 1);child.instanceIndex = instancedBufferAttribute(indexBuffer);// 索引// child.instanceIndex = new THREE.InstancedBufferAttribute(//     new Float32Array(instanceCount),//     1// );// 提供uniform// 选中的实例索引// child.selectInstanceIndex = ttI;// child.selectInstanceIndex = indexNode;child.selectInstanceIndex = uniform(-1, "float");// 选中的实例索引的透明度child.selectInstanceIndexOpacity = tt;// child.selectInstanceIndexOpacity = uniform(0.5, "float");// child.selectInstanceIndexOpacity = abs(oscSine(timerLocal(0.33334)));// child.selectInstanceIndexOpacity = oscNodechild.count = instanceCount;//重新设置 实例矩阵长度 为原长度的instanceCount倍child.skeleton.setInstanceCount(instanceCount);// gui.add(//     {//         f: () => {//             mixer.update(delta);//             console.log(child.skeleton.boneMatrices);//         },//     },//     "f"// ).name("mixer.update()");for (let i = 0; i < instanceCount; i++) {// dummy.position.y = Math.floor(i / 5) * -200;dummy.position.x = 70;// dummy.position.x = i * 70;dummy.position.z = i * -0.1;dummy.updateMatrix();dummy.matrix.toArray(child.instanceMatrix.array, i * 16);floatIndex[i] = i;floatOpacity[i] = 1;}const setIndexFadeOut = i => {// child.selectInstanceIndex.value = i;// dir = -1;// tt.value = 1;};// gui.add({ f: () => skinningInstanceMatrices.syncOnes(1) }, "f").name("1 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncOnes(2) }, "f").name("2 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncOnes(3) }, "f").name("3 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncOnes(4) }, "f").name("4 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncOnes(5) }, "f").name("5 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncOnes(6) }, "f").name("6 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncOnes(7) }, "f").name("7 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncOnes(8) }, "f").name("8 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncOnes(9) }, "f").name("9 ONES");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(1) }, "f").name("1 ASYNC");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(2) }, "f").name("2 ASYNC");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(3) }, "f").name("3 ASYNC");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(4) }, "f").name("4 ASYNC");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(5) }, "f").name("5 ASYNC");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(6) }, "f").name("6 ASYNC");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(7) }, "f").name("7 ASYNC");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(8) }, "f").name("8 ASYNC");// gui.add({ f: () => skinningInstanceMatrices.syncIndex(9) }, "f").name("9 ASYNC");}});scene.add(object);});loader.load("./avoid.glb", function (gltf) {const object = gltf.scene;const avoidGUI = gui.addFolder("躲避");mixer2 = new THREE.AnimationMixer(object);const action = mixer2.clipAction(gltf.animations[0]);// 播放一次// action.loop = THREE.LoopOnce;// 播完保持当前姿势action.clampWhenFinished = true;action.play();// mixer2.addEventListener("finished", c => {//     skinningInstanceMatrices2 && skinningInstanceMatrices2.finished();// });const instanceCount = 10;const dummy = new THREE.Object3D();object.traverse(child => {if (child.isMesh) {skinningInstanceMatrices2 = new SkinningInstanceMatrices(child);skinningInstanceMatrices2.start();const oscNode = abs(oscSine(timerLocal(0.1)));const indexNode = floor(oscNode.div(0.3333334));const randomColors = range(new THREE.Color(0x000000), new THREE.Color(0xffffff));const randomMetalness = range(0, 1);const prevMap = child.material.map;// 设置 false 不计入 视椎体可见范围计算 避免被隐藏  椎体计算 一般使用object.boundingSpherechild.frustumCulled = false;// 显示卡通边框child.CartoonBorder = true;child.cartoonBorder = uniform(0.2);child.cartoonBorderColor = uniform(new THREE.Color("#ffffff"));child.CartoonBorderLight = uniform(vec3(0, 0, 1), "vec3");avoidGUI.add(child.cartoonBorder, "value", 0, 1).name("cartoonBorder");avoidGUI.add(skinningInstanceMatrices2, "delay", 0, 0.2).name("speed");avoidGUI.addColor({ color: "#" + child.cartoonBorderColor.value.getHexString() }, "color").onChange(c => {const newColor = new THREE.Color(c);child.cartoonBorderColor.value.copy(newColor);});// 重新播放avoidGUI.add({f: () => {action.reset();skinningInstanceMatrices2.start();},},"f").name("Reset Action");child.material = new THREE.MeshStandardNodeMaterial({transparent: true,side: 0,});child.material.colorNode = texture(prevMap);// child.material.colorNode = mix(texture(prevMap), randomColors, oscNode);child.isInstancedMesh = true;child.instanceMatrix = new THREE.InstancedBufferAttribute(new Float32Array(instanceCount * 16),16);// 透明度const floatOpacity = new Float32Array(instanceCount);const buffer = new THREE.InstancedBufferAttribute(floatOpacity, 1);child.instanceOpacity = instancedBufferAttribute(buffer);child.hideOther = child.setOmitOneOpacity = (op = 0) => {floatOpacity.fill(op);floatOpacity[0] = 1;buffer.needsUpdate = true;};child.showOther = () => {floatOpacity.fill(1);buffer.needsUpdate = true;};const floatIndex = new Float32Array(instanceCount);const indexBuffer = new THREE.InstancedBufferAttribute(floatIndex, 1);child.instanceIndex = instancedBufferAttribute(indexBuffer);child.selectInstanceIndex = uniform(-1, "float");// 选中的实例索引的透明度child.selectInstanceIndexOpacity = tt;child.count = instanceCount;//重新设置 实例矩阵长度 为原长度的instanceCount倍child.skeleton.setInstanceCount(instanceCount);for (let i = 0; i < instanceCount; i++) {// dummy.position.y = Math.floor(i / 5) * -200;dummy.position.x = -70;// dummy.position.x = i * 70;// dummy.position.y = i * -2;dummy.updateMatrix();dummy.matrix.toArray(child.instanceMatrix.array, i * 16);floatIndex[i] = i;floatOpacity[i] = 1;}}});scene.add(object);});loader.load("./AirEvasion.glb", function (gltf) {const object = gltf.scene;const AirEvasionGUI = gui.addFolder("空中躲避");mixer3 = new THREE.AnimationMixer(object);const action = mixer3.clipAction(gltf.animations[0]);// 播放一次action.loop = THREE.LoopOnce;// 播完保持当前姿势action.clampWhenFinished = true;action.play();mixer3.addEventListener("finished", c => {skinningInstanceMatrices3 && skinningInstanceMatrices3.finished();});const instanceCount = 10;const dummy = new THREE.Object3D();object.traverse(child => {if (child.isMesh) {skinningInstanceMatrices3 = new SkinningInstanceMatrices(child, 2, 29, true);skinningInstanceMatrices3.start();const oscNode = abs(oscSine(timerLocal(0.1)));const indexNode = floor(oscNode.div(0.3333334));const randomColors = range(new THREE.Color(0x000000), new THREE.Color(0xffffff));const randomMetalness = range(0, 1);const prevMap = child.material.map;// 设置 false 不计入 视椎体可见范围计算 避免被隐藏  椎体计算 一般使用object.boundingSpherechild.frustumCulled = false;// 显示卡通边框child.CartoonBorder = true;child.cartoonBorder = uniform(0.2);child.cartoonBorderColor = uniform(new THREE.Color("#ffffff"));child.CartoonBorderLight = uniform(vec3(0, 0, 1), "vec3");AirEvasionGUI.add(child.cartoonBorder, "value", 0, 1).name("cartoonBorder");AirEvasionGUI.add(skinningInstanceMatrices3, "delay", 0, 0.5).name("speed");AirEvasionGUI.addColor({ color: "#" + child.cartoonBorderColor.value.getHexString() },"color").onChange(c => {const newColor = new THREE.Color(c);child.cartoonBorderColor.value.copy(newColor);});// 重新播放AirEvasionGUI.add({f: () => {action.reset();skinningInstanceMatrices3.start();},},"f").name("Reset Action");child.material = new THREE.MeshStandardNodeMaterial({transparent: true,side: 0,});child.material.colorNode = texture(prevMap);// child.material.colorNode = mix(texture(prevMap), randomColors, oscNode);child.isInstancedMesh = true;child.instanceMatrix = new THREE.InstancedBufferAttribute(new Float32Array(instanceCount * 16),16);// 透明度const floatOpacity = new Float32Array(instanceCount);const buffer = new THREE.InstancedBufferAttribute(floatOpacity, 1);child.instanceOpacity = instancedBufferAttribute(buffer);child.hideOther = child.setOmitOneOpacity = (op = 0) => {floatOpacity.fill(op);floatOpacity[0] = 1;buffer.needsUpdate = true;};child.setOpacity = (index, op = 0) => {floatOpacity[index] = op;buffer.needsUpdate = true;};child.showOther = () => {floatOpacity.fill(1);buffer.needsUpdate = true;};const floatIndex = new Float32Array(instanceCount);const indexBuffer = new THREE.InstancedBufferAttribute(floatIndex, 1);child.instanceIndex = instancedBufferAttribute(indexBuffer);child.selectInstanceIndex = uniform(-1, "float");// 选中的实例索引的透明度child.selectInstanceIndexOpacity = tt;child.count = instanceCount;//重新设置 实例矩阵长度 为原长度的instanceCount倍child.skeleton.setInstanceCount(instanceCount);for (let i = 0; i < instanceCount; i++) {// dummy.position.y = Math.floor(i / 5) * -200;dummy.position.x = -140;// dummy.position.x = i * 70;// dummy.position.y = i * -2;dummy.position.y = 60;dummy.updateMatrix();dummy.matrix.toArray(child.instanceMatrix.array, i * 16);floatIndex[i] = i;floatOpacity[i] = 1;}}});scene.add(object);});// rendererrenderer = new THREE.WebGPURenderer({ antialias: true });renderer.setPixelRatio(2);renderer.setSize(window.innerWidth, window.innerHeight);renderer.setAnimationLoop(animate);document.body.appendChild(renderer.domElement);controls = new OrbitControls(camera, renderer.domElement);controls.target.set(0, 1, 0);controls.object.position.set(0, 1, 4);// post processingconst scenePass = pass(scene, camera);const scenePassColor = scenePass.getTextureNode();const scenePassDepth = scenePass.getLinearDepthNode().remapClamp(0.15, 0.3);const scenePassColorBlurred = scenePassColor.gaussianBlur();scenePassColorBlurred.directionNode = scenePassDepth;// postProcessing = new THREE.PostProcessing(renderer);// postProcessing.outputNode = scenePassColorBlurred;// eventswindow.addEventListener("resize", onWindowResize);}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}function animate() {delta = clock.getDelta();if (skinningInstanceMatrices) {TWEEN.update();}if (!window.stopAnimation) {skinningInstanceMatrices && skinningInstanceMatrices.prevAction(delta);if (mixer) mixer.update(delta);skinningInstanceMatrices2 && skinningInstanceMatrices2.prevAction(delta);if (mixer2) mixer2.update(delta);skinningInstanceMatrices3 && skinningInstanceMatrices3.prevAction(delta);if (mixer3) mixer3.update(delta);}// tt.value = tt.value + 0.01 * dir;// if (tt.value >= 1 || tt.value <= 0) {//     dir *= -1;// }// ttI.value = Math.floor(tt.value / 0.333334);// postProcessing.render();renderer.render(scene, camera);}</script></body>
</html>

相关文章:

ThreejsWebGPU运动残影demo

功能点 实例化SkinnedMesh 修改NodeMaterial着色器 节点材质系统 shader 语言 使用uniform和attribute 中合其他几篇博客中的内容 代码仓库 克隆后需要放到three源码同级别目录下 运行 three源码部分不在git仓库中(太大了) 使用vscode的live-server启动后访问 http://127.0.0.…...

HttpSession常用方法

1.HttpSession常用方法 是在Java Servlet中用来管理会话状态的重要接口&#xff0c;它提供了一种在多个请求或页面之间存储用户特定信息的方式。以下是一些 HttpSession 常用的方法和用法&#xff1a; 获取会话对象&#xff1a; HttpSession session request.getSession();…...

【JavaEE初阶】文件操作和IO

目录 &#x1f334;认识文件 &#x1f6a9;树型结构组织和目录 &#x1f6a9;文件路径&#xff08;Path&#xff09; &#x1f6a9; 文件分类 &#x1f38d;Java 中操作文件 &#x1f6a9; File 概述&#xff1a; &#x1f4cc;属性 &#x1f4cc;构造方法 &#x1f4c…...

存储器芯片的基本原理

目录 1.存储元 1.1栅极电容 1.2双稳态触发器 2.存储单元 3.存储体 4.存储器 5.容量计算 6.寻址 1.存储元 1.1栅极电容 给MOS管一个阈值电压&#xff08;5v&#xff09;就能够导电&#xff0c;若是不给那么就是一个绝缘体不会导电。 读出二进制原理&#xff1a; 通常…...

前端实习手记(7):立秋快乐

这周相比上周感觉挺好的哈哈哈&#xff0c;可能只有自己感觉蛮好的&#xff0c;旁边师父忙的飞起了要&#xff0c;不仅赶工作还要回答我乱七八糟的问题&#xff08;心疼一秒&#xff09;。这周也是立秋&七夕咯&#xff0c;立秋快乐哇家人们&#xff08;虽然还是很热嘛&…...

感恩放下,笑对人生,在人生的长河中,每一天都是独特的篇章,或顺心如意,或充满挑战

在人生的长河中,每一天都是独特的篇章,或顺心如意,或充满挑战。然而,无论今日的经历如何,我们都应怀着感恩与放下的心态,因为人生的旅程远不止这短暂的一天,明天依然充满希望,等待我们继续努力前行。 生活,犹如一场变幻莫测的舞台剧,顺心之时,我们仿佛置身于温暖的…...

URLSession之初窥门径

NSURLSession 于 2013 年随 iOS 7 的发布一起面世&#xff0c;苹果将其定位为 NSURLConnection 的替代者。我们使用最广泛的第三方框架如 AFNetworking 和 SDWebImage 的最新版也都已经全面切换至 NSURLSession。 NSURLSession 不仅仅指代同名类 NSURLSession&#xff0c;它还…...

ios创建控制器的3种方法实现页面跳转

ios遵守mvc设计模式&#xff0c;下面介绍创建控制器viewcontroller的几种方法&#xff0c;来实现页面的跳转 1.纯代码创建 // // AppDelegate.m // study2024 // // Created by zhifei zhu on 2024/8/7. //#import "AppDelegate.h" #import "MyViewContro…...

Android逆向题解-boomshakalaka-3-难度5

这个app 是一个cocos游戏&#xff0c;没有用脚本实现&#xff0c;纯c实现。 题目描述:play the game, get the highest score 题目要求是玩游戏得到最高分就可以得到flag&#xff0c;是写到配置文件的&#xff0c;初始flag值看着是base编码的。 核心代码在so里面的ControlLay…...

Linux(Ubuntu 22.04)系统中固定串口

Linux&#xff08;Ubuntu 22.04&#xff09;系统中固定串口 文章目录 前言正文查看linux串口信息修改udev固化串口校验是否修改完成 注意 前言 在Linux系统中固定串口&#xff08;通常指的是串行通信接口&#xff0c;如/dev/ttyS0或/dev/ttyUSB0&#xff09;的原因有几个方面&…...

LeetCode - 209 - 长度最小的子数组

力扣209题 题目描述&#xff1a;长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度**。**如果不存在符合条件的子数组&…...

探索空间计算与VR中的手势跟踪新纪元:XHand框架详解

在虚拟现实(VR)和扩展现实(XR)技术日新月异的今天,手势跟踪作为实现沉浸式体验的关键技术之一,正逐步从概念走向成熟。今天,我们将深入探索一个创新的框架——XHand,它以其卓越的性能和先进的技术亮点,为空间计算与VR领域的手势跟踪带来了全新的解决方案。 XHand框架…...

leetcode + 项目复习

上午 Leetcode算法 参考文章——代码随想录 1. KMP 概念 主要应用 字符串匹配 主要思想 根据之前匹配的信息&#xff0c;当发现字符串不匹配时&#xff0c;避免从头开始匹配。 什么是前缀表&#xff08;next数组、prefix&#xff09; 是用来回退的&#xff0c;当文本串和…...

树莓派4/5:设置apt、pip、conda首选清华镜像源

一、教程简介 在中国大陆地区&#xff0c;使用清华镜像源可以显著缩短资源下载时间。 本教程介绍如何将清华镜像源设置为树莓派的apt、pip、conda下载的首选项&#xff08;默认项&#xff09;。其中&#xff0c;apt和pip为树莓派系统自带&#xff0c;conda则需要安装miniforg…...

NoSQL 之Redis集群模式

目录 案例概述 redis工作模式 主从模式 哨兵模式 redis cluster模式 Redis集群介绍 Redis集群的优势 Redis集群的实现方法 Redis-Cluster数据分片 Redis-Cluster的主从复制模型 Redis集群部署 案例部署 安装redis 检查redis的状态 修改配置文件 重启启动redis服…...

oracle rac

1、app连接oracle rac集群 连接到 Oracle RAC&#xff08;Real Application Clusters&#xff09;的多种配置方式 1. 使用 JDBC 连接字符串&#xff1a; 使用 JDBC 连接字符串是连接 Oracle RAC 的常见方式。连接字符串的格式如下&#xff1a; jdbc:oracle:thin:(DESCRIPTION…...

计算机毕业设计Python深度学习房价预测 房价可视化 链家爬虫 房源爬虫 房源可视化 卷积神经网络 大数据毕业设计 机器学习 人工智能 AI

Python深度学习房价预测系统开题报告 一、研究背景与意义 随着城市化进程的加速和房地产市场的不断发展&#xff0c;房价成为影响人们生活质量的重要因素之一。准确预测房价不仅有助于政府制定科学的房地产政策&#xff0c;还能为开发商提供市场参考&#xff0c;同时帮助购房…...

【Linux】学习Linux,需要借助具象化的思维

指令与图形化界面 导读一、命令行与图形化界面二、命令行与图形化界面的发展历程1.2.1 打字机的起源1.2.2 肖尔斯和格利登型打字机1.2.3 鼠标的发明1.2.4 图形化界面&#xff08;GUI&#xff09;的发展 三、命令行与图形化之间的联系3.1 图形化界面的人机交互3.2 命令行界面的人…...

R语言贝叶斯方法在生态环境领域技术教程

原文链接&#xff1a;R语言贝叶斯方法在生态环境领域技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247612056&idx5&snb170122cf5052cc7cb2d858606b9f158&chksmfa82777fcdf5fe69eec092410530e2900c98bcbb84e3d33c823705c948b4db96545bf282747a…...

mojo实现高阶函数(algorithm)

functional 实现高阶函数。 您可以从 algorithm 包导入这些 API。例如: from algorithm import map别名: ​Static1DTileUnitFunc = fn[Int](Int, /) capturing -> None: Signature of a 1d tiled function that performs some work with a static tile size and an off…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...