第十二節:粒子系統:海量點渲染

第十二節:粒子系統:海量點渲染

引言

粒子系統是創造動態視覺效果的神器,從漫天繁星到熊熊火焰,從魔法特效到數據可視化,都離不開粒子技術。Three.js提供了強大的粒子渲染能力,可輕松處理百萬級粒子。本文將深入解析粒子系統核心原理,并通過Vue3實現交互式粒子編輯器,帶你掌握微觀世界的創造藝術。


在這里插入圖片描述

1. 粒子系統基礎
1.1 核心組件
粒子系統
Points
PointsMaterial
BufferGeometry
粒子容器
粒子外觀
粒子數據
1.2 創建流程
// 1. 創建幾何體(存儲粒子位置)
const geometry = new THREE.BufferGeometry();// 2. 設置頂點數據
const positions = new Float32Array(1000 * 3); // 1000個粒子
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));// 3. 創建材質
const material = new THREE.PointsMaterial({color: 0xffffff,size: 0.1,
});// 4. 創建粒子系統
const particles = new THREE.Points(geometry, material);
scene.add(particles);

2. 基礎粒子效果
2.1 靜態星空
<script setup>
import { onMounted } from 'vue';
import * as THREE from 'three';function createStars() {const starCount = 10000;const geometry = new THREE.BufferGeometry();// 生成隨機位置const positions = new Float32Array(starCount * 3);for (let i = 0; i < starCount * 3; i += 3) {positions[i] = (Math.random() - 0.5) * 2000; // xpositions[i+1] = (Math.random() - 0.5) * 2000; // ypositions[i+2] = (Math.random() - 0.5) * 2000; // z}geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));// 創建材質const material = new THREE.PointsMaterial({color: 0xffffff,size: 0.7,sizeAttenuation: true, // 透視衰減});return new THREE.Points(geometry, material);
}onMounted(() => {const stars = createStars();scene.add(stars);
});
</script>
2.2 動態雨雪
<script setup>
import { ref, onMounted } from 'vue';
import * as THREE from 'three';const rainGeometry = ref(null);
const rainMaterial = ref(null);
const rainSystem = ref(null);// 初始化雨滴
onMounted(() => {const rainCount = 5000;rainGeometry.value = new THREE.BufferGeometry();// 初始位置(頂部隨機分布)const positions = new Float32Array(rainCount * 3);for (let i = 0; i < rainCount * 3; i += 3) {positions[i] = Math.random() * 100 - 50; // xpositions[i+1] = Math.random() * 50 + 50; // ypositions[i+2] = Math.random() * 100 - 50; // z}rainGeometry.value.setAttribute('position', new THREE.BufferAttribute(positions, 3));// 創建雨滴材質rainMaterial.value = new THREE.PointsMaterial({color: 0xaaaaaa,size: 0.1,transparent: true,opacity: 0.8,});rainSystem.value = new THREE.Points(rainGeometry.value, rainMaterial.value);scene.add(rainSystem.value);
});// 更新動畫
function animateRain() {const positions = rainGeometry.value.attributes.position.array;for (let i = 1; i < positions.length; i += 3) {positions[i] -= 0.5; // Y軸下落// 重置位置(到達地面后回到頂部)if (positions[i] < -50) {positions[i] = Math.random() * 50 + 50;positions[i-2] = Math.random() * 100 - 50; // 重置Xpositions[i+1] = Math.random() * 100 - 50; // 重置Z}}// 標記更新rainGeometry.value.attributes.position.needsUpdate = true;
}
</script>

3. 高級粒子技術
3.1 粒子紋理
// 加載粒子貼圖
const textureLoader = new THREE.TextureLoader();
const particleTexture = textureLoader.load('textures/particle.png');const material = new THREE.PointsMaterial({map: particleTexture,alphaTest: 0.5, // 透明度閾值blending: THREE.AdditiveBlending, // 疊加混合depthWrite: false, // 禁用深度寫入
});// 圓形粒子
const discTexture = new THREE.CanvasTexture(createDiscCanvas(64));
function createDiscCanvas(size) {const canvas = document.createElement('canvas');canvas.width = canvas.height = size;const ctx = canvas.getContext('2d');const center = size / 2;const gradient = ctx.createRadialGradient(center, center, 0,center, center, center);gradient.addColorStop(0, 'rgba(255,255,255,1)');gradient.addColorStop(1, 'rgba(255,255,255,0)');ctx.fillStyle = gradient;ctx.beginPath();ctx.arc(center, center, center, 0, Math.PI * 2);ctx.fill();return canvas;
}
3.2 粒子物理
// 添加重力
const gravity = -0.01;
const velocities = new Float32Array(particleCount * 3);function initPhysics() {for (let i = 0; i < particleCount; i++) {velocities[i * 3] = (Math.random() - 0.5) * 0.1; // vxvelocities[i * 3 + 1] = Math.random() * 0.5 + 0.1; // vyvelocities[i * 3 + 2] = (Math.random() - 0.5) * 0.1; // vz}
}function updatePhysics() {const positions = geometry.attributes.position.array;for (let i = 0; i < particleCount; i++) {const idx = i * 3;// 更新速度velocities[idx + 1] += gravity;// 更新位置positions[idx] += velocities[idx];positions[idx + 1] += velocities[idx + 1];positions[idx + 2] += velocities[idx + 2];// 地面碰撞檢測if (positions[idx + 1] < 0) {positions[idx + 1] = 0;velocities[idx + 1] = -velocities[idx + 1] * 0.8; // 反彈}}geometry.attributes.position.needsUpdate = true;
}
3.3 粒子交互
// 鼠標交互影響粒子
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();function onMouseMove(event) {// 計算鼠標位置mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;// 更新射線raycaster.setFromCamera(mouse, camera);// 計算鼠標在空間中的位置const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);const intersectPoint = new THREE.Vector3();raycaster.ray.intersectPlane(plane, intersectPoint);// 影響粒子const positions = geometry.attributes.position.array;const center = new THREE.Vector3(intersectPoint.x,intersectPoint.y,intersectPoint.z);for (let i = 0; i < particleCount; i++) {const idx = i * 3;const particlePos = new THREE.Vector3(positions[idx],positions[idx+1],positions[idx+2]);const distance = particlePos.distanceTo(center);if (distance < 5) {const direction = particlePos.clone().sub(center).normalize();const force = (5 - distance) * 0.01;positions[idx] += direction.x * force;positions[idx+1] += direction.y * force;positions[idx+2] += direction.z * force;}}geometry.attributes.position.needsUpdate = true;
}

4. GPU加速粒子
4.1 ShaderMaterial定制
<script setup>
import { ref, onMounted } from 'vue';
import * as THREE from 'three';// 頂點著色器
const vertexShader = `attribute float size;attribute vec3 customColor;varying vec3 vColor;void main() {vColor = customColor;vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);gl_PointSize = size * (300.0 / -mvPosition.z); // 透視縮放gl_Position = projectionMatrix * mvPosition;}
`;// 片元著色器
const fragmentShader = `varying vec3 vColor;uniform sampler2D pointTexture;void main() {gl_FragColor = vec4(vColor, 1.0);gl_FragColor = gl_FragColor * texture2D(pointTexture, gl_PointCoord);// 圓形粒子if (length(gl_PointCoord - vec2(0.5)) > 0.5) {discard;}}
`;// 創建自定義粒子材質
const particleMaterial = ref(null);onMounted(() => {particleMaterial.value = new THREE.ShaderMaterial({uniforms: {pointTexture: { value: new THREE.TextureLoader().load('particle.png') }},vertexShader,fragmentShader,blending: THREE.AdditiveBlending,depthTest: false,transparent: true});
});
</script>
4.2 計算著色器(WebGPU)
// 使用WebGPU計算著色器
import { GPUComputationRenderer } from 'three/addons/misc/GPUComputationRenderer.js';const gpuCompute = new GPUComputationRenderer(1024, 1024, renderer);// 創建位置紋理
const positionTexture = gpuCompute.createTexture();
initPositionTexture(positionTexture);// 創建速度紋理
const velocityTexture = gpuCompute.createTexture();
initVelocityTexture(velocityTexture);// 創建計算著色器
const positionShader = `uniform float time;uniform sampler2D velocityTexture;void main() {vec2 uv = gl_FragCoord.xy / resolution.xy;vec4 velocity = texture2D(velocityTexture, uv);// 更新位置vec4 position = texture2D(positionTexture, uv);position.xyz += velocity.xyz * 0.05;// 邊界約束if (position.x > 50.0) position.x = -50.0;// 其他邊界...gl_FragColor = position;}
`;const positionVariable = gpuCompute.addVariable('positionTexture', positionShader, positionTexture
);// 類似創建速度著色器...// 初始化計算
gpuCompute.setVariableDependencies(positionVariable, [positionVariable, velocityVariable]);
gpuCompute.init();
4.3 Instanced Particles
// 使用實例化粒子
const particleGeometry = new THREE.InstancedBufferGeometry();
particleGeometry.instanceCount = 100000;// 基礎幾何(一個點)
particleGeometry.setAttribute('position',new THREE.BufferAttribute(new Float32Array([0, 0, 0]), 3)
);// 實例化屬性
const offsets = new Float32Array(100000 * 3);
const colors = new Float32Array(100000 * 3);
const sizes = new Float32Array(100000);// 填充數據
for (let i = 0; i < 100000; i++) {offsets[i * 3] = Math.random() * 100 - 50;offsets[i * 3 + 1] = Math.random() * 100 - 50;offsets[i * 3 + 2] = Math.random() * 100 - 50;colors[i * 3] = Math.random();colors[i * 3 + 1] = Math.random();colors[i * 3 + 2] = Math.random();sizes[i] = Math.random() * 2 + 0.5;
}// 設置屬性
particleGeometry.setAttribute('offset',new THREE.InstancedBufferAttribute(offsets, 3)
);
particleGeometry.setAttribute('color',new THREE.InstancedBufferAttribute(colors, 3)
);
particleGeometry.setAttribute('size',new THREE.InstancedBufferAttribute(sizes, 1)
);// 創建材質
const material = new THREE.ShaderMaterial({vertexShader: `...`,fragmentShader: `...`,uniforms: { /* ... */ }
});const particleSystem = new THREE.Points(particleGeometry, material);
scene.add(particleSystem);

5. Vue3粒子編輯器
5.1 項目結構
src/├── components/│    ├── ParticleEditor.vue  // 主編輯器│    ├── ParticlePreview.vue // 3D預覽│    ├── EffectLibrary.vue   // 效果庫│    └── ParticleParams.vue  // 參數控制└── App.vue
5.2 主編輯器
<!-- ParticleEditor.vue -->
<template><div class="particle-editor"><div class="sidebar"><EffectLibrary @select-effect="setActiveEffect" /><ParticleParams :effect="activeEffect" @update="updateEffect" /></div><div class="preview-container"><ParticlePreview ref="previewRef" :effect-config="activeEffect" /></div></div>
</template><script setup>
import { ref, reactive } from 'vue';
import { particleEffects } from './particle-presets';const activeEffect = ref(null);
const previewRef = ref(null);// 設置活動效果
function setActiveEffect(effect) {activeEffect.value = { ...effect };previewRef.value.applyEffect(activeEffect.value);
}// 更新效果
function updateEffect(newParams) {Object.assign(activeEffect.value, newParams);previewRef.value.updateEffect(activeEffect.value);
}
</script>
5.3 粒子預覽組件
<!-- ParticlePreview.vue -->
<script setup>
import { ref, onMounted, watch } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';const props = defineProps(['effectConfig']);
const canvasRef = ref(null);// 場景初始化
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0a0a2a); // 深藍色背景
const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
camera.position.z = 15;
const renderer = ref(null);
const controls = ref(null);
const particleSystem = ref(null);onMounted(() => {renderer.value = new THREE.WebGLRenderer({canvas: canvasRef.value,antialias: true});renderer.value.setSize(800, 600);controls.value = new OrbitControls(camera, renderer.value.domElement);// 添加基礎燈光const ambientLight = new THREE.AmbientLight(0xffffff, 0.3);scene.add(ambientLight);const directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);directionalLight.position.set(5, 10, 7);scene.add(directionalLight);// 啟動動畫循環animate();
});// 應用效果配置
function applyEffect(config) {// 清除舊系統if (particleSystem.value) {scene.remove(particleSystem.value);particleSystem.value.geometry.dispose();particleSystem.value.material.dispose();}// 創建新系統particleSystem.value = createParticleSystem(config);scene.add(particleSystem.value);
}// 更新效果
function updateEffect(config) {if (!particleSystem.value) return;// 更新材質particleSystem.value.material.size = config.particleSize;particleSystem.value.material.color = new THREE.Color(config.color);// 更新幾何體if (config.particleCount !== currentCount) {applyEffect(config);}
}// 動畫循環
function animate() {requestAnimationFrame(animate);// 更新粒子if (particleSystem.value) {updateParticles(particleSystem.value, props.effectConfig);}controls.value.update();renderer.value.render(scene, camera);
}
</script>
5.4 效果預設庫
<!-- EffectLibrary.vue -->
<template><div class="effect-library"><div v-for="effect in effects" :key="effect.id"class="effect-card":class="{ active: effect.id === activeId }"@click="selectEffect(effect)"><div class="thumbnail" :style="{background: `radial-gradient(circle, ${effect.color} 0%, #000 100%)`}"></div><h4>{{ effect.name }}</h4></div></div>
</template><script setup>
import { ref } from 'vue';const effects = ref([{id: 'fire',name: '火焰效果',color: '#ff5722',particleCount: 5000,particleSize: 0.5,// 其他參數...},{id: 'snow',name: '飄雪效果',color: '#ffffff',particleCount: 10000,particleSize: 0.2,// 其他參數...},{id: 'magic',name: '魔法粒子',color: '#9c27b0',particleCount: 8000,particleSize: 0.3,// 其他參數...},{id: 'stars',name: '宇宙星空',color: '#4fc3f7',particleCount: 20000,particleSize: 0.7,// 其他參數...}
]);const activeId = ref(null);
const emit = defineEmits(['select-effect']);function selectEffect(effect) {activeId.value = effect.id;emit('select-effect', effect);
}
</script>
5.5 參數控制面板
<!-- ParticleParams.vue -->
<template><div class="particle-params" v-if="effect"><h3>{{ effect.name }} 參數</h3><div class="control-group"><label>粒子數量: {{ effect.particleCount }}</label><input type="range" v-model.number="localEffect.particleCount" min="100" max="100000" step="100"@input="updateParams"></div><div class="control-group"><label>粒子大小: {{ effect.particleSize.toFixed(2) }}</label><input type="range" v-model.number="localEffect.particleSize" min="0.01" max="2" step="0.01"@input="updateParams"></div><div class="control-group"><label>粒子顏色</label><input type="color" v-model="localEffect.color"@change="updateParams"></div><div class="control-group" v-if="effect.type === 'fire'"><label>火焰強度: {{ effect.intensity.toFixed(2) }}</label><input type="range" v-model.number="localEffect.intensity" min="0.1" max="5" step="0.1"@input="updateParams"></div><!-- 其他效果特定參數 --></div>
</template><script setup>
import { ref, watch } from 'vue';const props = defineProps(['effect']);
const emit = defineEmits(['update']);const localEffect = ref({ ...props.effect });// 監聽外部變化
watch(() => props.effect, (newVal) => {localEffect.value = { ...newVal };
});// 更新參數
function updateParams() {emit('update', { ...localEffect.value });
}
</script>

6. 百萬級粒子優化
6.1 性能優化策略
>10,000
每幀更新
低頻更新
性能瓶頸
粒子數量
使用Instancing
更新頻率
使用Shader
使用CPU
移動端
降低數量+大小
6.2 渲染優化技術
  1. Frustum Culling

    // 自定義視錐剔除
    const frustum = new THREE.Frustum();
    const viewProjectionMatrix = new THREE.Matrix4();function updateCulling() {viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix,camera.matrixWorldInverse);frustum.setFromProjectionMatrix(viewProjectionMatrix);particleSystem.visible = frustum.intersectsSphere(particleSystem.geometry.boundingSphere);
    }
    
  2. Level of Detail

    // 根據距離調整細節
    function updateLOD() {const distance = camera.position.distanceTo(particleSystem.position);if (distance > 100) {particleSystem.material.size = 0.1;particleSystem.geometry.setDrawRange(0, 1000); // 只渲染部分粒子} else if (distance > 50) {particleSystem.material.size = 0.3;particleSystem.geometry.setDrawRange(0, 5000);} else {particleSystem.material.size = 0.5;particleSystem.geometry.setDrawRange(0, 10000);}
    }
    
  3. Batch Rendering

    // 合并粒子系統
    const mergedGeometry = new THREE.BufferGeometry();
    const particleSystems = [system1, system2, system3];particleSystems.forEach(system => {const geometry = system.geometry.clone();geometry.applyMatrix4(system.matrixWorld);mergedGeometry.merge(geometry);
    });const mergedParticles = new THREE.Points(mergedGeometry,baseMaterial
    );
    
6.3 內存優化
// 重用幾何體
const particlePool = [];
const POOL_SIZE = 10;function createParticlePool() {for (let i = 0; i < POOL_SIZE; i++) {const geometry = new THREE.BufferGeometry();const material = new THREE.PointsMaterial();const system = new THREE.Points(geometry, material);system.visible = false;scene.add(system);particlePool.push(system);}
}function getParticleSystem() {for (const system of particlePool) {if (!system.visible) {system.visible = true;return system;}}// 如果池已滿,創建新系統return createNewSystem();
}

7. 粒子效果案例
7.1 火焰效果
function createFireEffect() {const count = 5000;const geometry = new THREE.BufferGeometry();// 位置、顏色、大小屬性const positions = new Float32Array(count * 3);const colors = new Float32Array(count * 3);const sizes = new Float32Array(count);for (let i = 0; i < count; i++) {const i3 = i * 3;// 初始位置(火源中心)positions[i3] = (Math.random() - 0.5) * 2;positions[i3+1] = 0;positions[i3+2] = (Math.random() - 0.5) * 2;// 顏色(從黃到紅)const hue = 0.1 + Math.random() * 0.1;colors[i3] = 1.0; // Rcolors[i3+1] = hue; // Gcolors[i3+2] = 0.0; // B// 初始大小sizes[i] = Math.random() * 0.5 + 0.1;}geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));geometry.setAttribute('size', new THREE.BufferAttribute(sizes, 1));// 材質const material = new THREE.PointsMaterial({vertexColors: true,size: 0.5,blending: THREE.AdditiveBlending,depthWrite: false,transparent: true});return new THREE.Points(geometry, material);
}function updateFire(particles) {const positions = particles.geometry.attributes.position.array;const colors = particles.geometry.attributes.color.array;const sizes = particles.geometry.attributes.size.array;for (let i = 0; i < positions.length / 3; i++) {const i3 = i * 3;// 粒子上升positions[i3+1] += Math.random() * 0.1;// 隨機左右擺動positions[i3] += (Math.random() - 0.5) * 0.05;positions[i3+2] += (Math.random() - 0.5) * 0.05;// 顏色變暗(模擬冷卻)colors[i3+1] = Math.max(0, colors[i3+1] - 0.005);// 粒子縮小sizes[i] = Math.max(0.05, sizes[i] - 0.001);// 重置粒子if (positions[i3+1] > 10 || sizes[i] <= 0.05) {positions[i3+1] = 0;positions[i3] = (Math.random() - 0.5) * 2;positions[i3+2] = (Math.random() - 0.5) * 2;colors[i3+1] = 0.1 + Math.random() * 0.1;sizes[i] = Math.random() * 0.5 + 0.1;}}particles.geometry.attributes.position.needsUpdate = true;particles.geometry.attributes.color.needsUpdate = true;particles.geometry.attributes.size.needsUpdate = true;
}
7.2 數據可視化
function createDataVisualization(points) {const geometry = new THREE.BufferGeometry();// 位置和顏色const positions = new Float32Array(points.length * 3);const colors = new Float32Array(points.length * 3);points.forEach((point, i) => {const i3 = i * 3;// 位置positions[i3] = point.x;positions[i3+1] = point.y;positions[i3+2] = point.z;// 顏色(基于值)const color = new THREE.Color();color.setHSL(0.6 * point.value, 1.0, 0.5);colors[i3] = color.r;colors[i3+1] = color.g;colors[i3+2] = color.b;});geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));// 材質const material = new THREE.PointsMaterial({vertexColors: true,size: 2.0,sizeAttenuation: false});return new THREE.Points(geometry, material);
}

8. 常見問題解答

Q1:粒子顯示為方塊而不是圓形?

// 解決方案1:使用圓形紋理
material.map = createCircleTexture();// 解決方案2:在著色器中處理
void main() {float distance = length(gl_PointCoord - vec2(0.5));if (distance > 0.5) discard;// ...
}// 解決方案3:開啟抗鋸齒
renderer = new THREE.WebGLRenderer({ antialias: true });

Q2:移動端粒子性能差怎么辦?

  1. 減少粒子數量(<5000)
  2. 禁用大小衰減 sizeAttenuation: false
  3. 使用簡單著色器
  4. 降低更新頻率(每秒30幀)

Q3:如何實現粒子拖尾效果?

// 使用GPU粒子實現拖尾
const trailShader = `uniform sampler2D positionTexture;uniform sampler2D prevPositionTexture;void main() {vec2 uv = gl_FragCoord.xy / resolution.xy;vec4 position = texture2D(positionTexture, uv);vec4 prevPosition = texture2D(prevPositionTexture, uv);// 混合當前和之前位置vec4 newPosition = mix(position, prevPosition, 0.8);gl_FragColor = newPosition;}
`;// 渲染時繪制多條軌跡
for (let i = 0; i < TRAIL_LENGTH; i++) {const trailMaterial = new THREE.PointsMaterial({color: baseColor,size: baseSize * (1 - i/TRAIL_LENGTH),opacity: 1 - i/TRAIL_LENGTH,transparent: true});const trail = new THREE.Points(geometry, trailMaterial);scene.add(trail);
}

9. 總結

通過本文,你已掌握:

  1. 粒子系統核心組件(Points/PointsMaterial)
  2. 基礎粒子效果實現(星空/雨雪)
  3. 高級粒子技術(紋理/物理/交互)
  4. GPU加速與計算著色器
  5. Vue3粒子編輯器開發
  6. 百萬級粒子優化策略
  7. 實戰效果案例(火焰/數據可視化)

核心價值:Three.js粒子系統通過GPU加速渲染,結合著色器編程,實現了百萬級粒子的實時交互,為Web應用帶來影院級視覺效果。


下一篇預告

第十三篇:后期處理:效果增強
你將學習:

  • 后期處理管線原理
  • 內置效果鏈(Bloom/SSAO/Glitch)
  • 自定義ShaderPass開發
  • 性能優化:多采樣與降級
  • 高級特效:景深、運動模糊
  • Vue3實現后期處理編輯器

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918630.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918630.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918630.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LeetCode Day5 -- 二叉樹

目錄 1. 啥時候用二叉樹&#xff1f; &#xff08;1&#xff09;典型問題 &#xff08;2&#xff09;核心思路 2. BFS、DFS、BST 2.1 廣度優先搜索BFS &#xff08;1&#xff09;適用任務 &#xff08;2&#xff09;解決思路??&#xff1a;使用隊列逐層遍歷 2.2 深度…

<c1:C1DateTimePicker的日期時間控件,控制日期可以修改,時間不能修改,另外控制開始時間的最大值比結束時間小一天

兩個時間控件 <c1:C1DateTimePicker Width"170" EditMode"DateTime" CustomDateFormat"yyyy-MM-dd" CustomTimeFormat"HH:mm:ss" Style"{StaticResource ListSearch-DateTimePicker}" x:Name"dateTimePicker"…

文件完整性監控工具:架構和實現

文件完整性監控(FIM)作為一道關鍵的防御層&#xff0c;確保系統和網絡中文件及文件夾的完整性與安全性。文件完整性監控工具通過監控關鍵文件的變更并檢測未經授權的修改&#xff0c;提供關于潛在安全漏洞、惡意軟件感染和內部威脅的早期警報。為了使文件完整性監控工具發揮實效…

Linux信號量和信號

1.溫故知新上一篇博客&#xff0c;我們又知道了一種進程間通信的方案&#xff1a;共享內存。它是在物理內存中用系統調用給我們在物理內存開辟一個共享內存&#xff0c;可以由多個進程的頁表進行映射&#xff0c;共享內存不和管道一樣&#xff0c;它的生命周期是隨內核的&#…

騰訊測試崗位面試真題分析

以下是對騰訊測試工程師面試問題的分類整理、領域占比分析及高頻問題精選&#xff08;基于??92道問題&#xff0c;總出現次數118次??&#xff09;。問題按??7大技術領域??劃分&#xff0c;高頻問題標注優先級&#xff08;1-5&#x1f31f;&#xff09;&#xff1a; 不…

全面解析遠程桌面:功能實現、性能優化與安全防護全攻略

遠程桌面技術已成為工作與生活中不可或缺的協作工具&#xff0c;但在實際應用中&#xff0c;用戶常遇到連接失敗、卡頓延遲、安全隱患等問題。本文從遠程桌面功能原理、網絡與性能優化、安全防護策略、跨平臺兼容性等角度&#xff0c;詳細解析常見問題的解決方案&#xff0c;并…

【問題】Mybatis-plus框架使用@Select注解編寫查詢SQL,json字段查詢轉換失敗

問題描述在使用mybaits-plus的時候定義的Mapper接口實現了BaseMapper&#xff0c;沒有編寫Mapper對應的xml&#xff0c;大部分查詢使用框架的接口進行查詢基本屬性返回都是正常&#xff0c;復雜對象在sql中會進行查詢&#xff0c;但是返回對象中卻未包含相關屬性。問題原因 沒有…

Python多線程實現大文件下載

Python多線程實現大文件下載 在互聯網時代&#xff0c;文件下載是日常操作之一&#xff0c;尤其是大文件&#xff0c;如軟件安裝包、高清視頻等。然而&#xff0c;網絡條件不穩定或帶寬有限時&#xff0c;下載速度會變得很慢&#xff0c;令人抓狂。幸運的是&#xff0c;通過多線…

【R語言】RStudio 中的 Source on Save、Run、Source 辨析

RStudio 中的 Source on Save、Run、Source 辨析 在使用 RStudio 進行 R 語言開發時&#xff0c;我們會在主界面左上角看見三個按鈕&#xff1a;Source on Save、Run、Source 。 本文將帶你從概念、使用方法、快捷鍵、使用場景以及注意事項等方面詳細解析這三個功能。 文章目錄…

藍橋杯算法之搜索章 - 4

目錄 文章目錄 前言 一、記憶化搜索 二、題目概略 三、斐波拉契數 四、Function 五、天下第一 六、滑雪 總結 親愛的讀者朋友們&#xff0c;大家好啊&#xff01;不同的時間&#xff0c;相同的地點&#xff0c;今天又帶來了關于搜索部分的講解。接下來我將接著我前面文章的內容…

抗量子加密技術前瞻:后量子時代的密碼學革命

目錄抗量子加密技術前瞻&#xff1a;后量子時代的密碼學革命1. 量子計算威脅現狀1.1 量子霸權里程碑1.2 受威脅算法1.3 時間緊迫性2. 抗量子密碼學體系2.1 技術路線對比2.2 數學基礎革新3. 標準化進程3.1 NIST PQC標準化時間線3.2 當前推薦算法4. 技術實現方案4.1 Kyber密鑰交換…

基于STM32設計的礦山環境監測系統(NBIOT)_262

文章目錄 一、前言 1.1 項目介紹 【1】開發背景 【2】研究的意義 【3】最終實現需求 【4】項目硬件模塊組成 1.2 設計思路 【1】整體設計思路 【2】上位機開發思路 1.3 項目開發背景 【1】選題的意義 【2】摘要 【3】國內外相關研究現狀 【5】參考文獻 1.4 開發工具的選擇 【1】…

電腦如何安裝win10專業版_電腦用u盤安裝win10專業版教程

電腦如何安裝win10專業版&#xff1f;電腦還是建議安裝win10專業版。Win分為多個版本&#xff0c;其中家庭版&#xff08;Home&#xff09;和專業版&#xff08;Pro&#xff09;是用戶選擇最多的兩個版本。win10專業版在功能以及安全性方面有著明顯的優勢&#xff0c;所以電腦還…

多語言文本 AI 情感分析 API 數據接口

多語言文本 AI 情感分析 API 數據接口 AI / 文本處理 AI 模型快速分析文本情感傾向 多語言文本 / 情感分析。 1. 產品功能 支持多語言文本情感分析&#xff1b;基于特定 AI 模型&#xff0c;快速識別文本情感傾向&#xff1b;適用于評論分析、輿情監控等場景&#xff1b;全接…

【R語言】R語言的工作空間映像(workspace image,通常是.RData)詳解

R語言的工作空間映像&#xff08;.RData&#xff09;詳解 在使用 R 語言時&#xff0c;你可能會注意到&#xff0c;每次退出 R 會彈出一個提示&#xff1a; Save workspace image? [y/n/c] 如果你使用的是 Rstudio 這個 IDE 來進行R語言的開發&#xff0c;那么可能彈出的提示…

在線 A2C實踐

在線 A2C&#xff08;Actor-Critic&#xff09;算法在推薦系統中的實踐&#xff0c;核心是將推薦過程建模為實時交互的強化學習問題&#xff0c;通過 Actor 生成推薦策略、Critic 評估策略價值&#xff0c;實現 “決策 - 反饋 - 更新” 的閉環。從樣本設計到最終上線&#xff0…

Eclipse RCP產品動態模塊設計

文章目錄 遇到問題具體實踐效果演示應用下載 遇到問題 如果你是一個To C產品的設計者&#xff0c;勢必會遇到用戶需求高度分化的場景&#xff0c;隨之而來的是繁雜的功能列表&#xff0c;如何讓用戶只接觸與其任務直接相關的功能&#xff0c;隱藏無關元素&#xff1f; 具體實…

NLP自然語言處理: FastText工具與遷移學習基礎詳解

FastText工具與遷移學習基礎詳解 一、知識框架總覽 FastText工具核心功能與應用場景FastText模型架構與工作原理層次Softmax加速機制哈夫曼樹概念與構建方法 二、FastText工具核心解析 2.1 功能定位 雙重核心功能 文本分類&#xff1a;可直接用于文本分類任務&#xff0c;快速生…

uni-app 生命周期詳解

概述 uni-app 基于 Vue.js 框架開發&#xff0c;其生命周期包含了三個層面&#xff1a; 應用生命周期&#xff1a;App.vue 的生命周期頁面生命周期&#xff1a;各個頁面的生命周期Vue 組件生命周期&#xff1a;Vue.js 原生的組件生命周期 這三種生命周期在不同場景下會按特定順…

MCU外設初始化:為什么參數配置必須優先于使能

在微控制器領域&#xff0c;初始化參數配置階段至關重要。此時&#xff0c;雖無電源驅動&#xff0c;但微控制器在使能信號到來前&#xff0c;借初始化參數配置這一精細步驟&#xff0c;開啟關鍵準備進程。初始化參數配置如同物理坐標錨定、邏輯指令部署、內在秩序預設&#xf…