当前位置: 首页 > 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…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...