ThreadPoolExecutor 是 Python 标准库 concurrent.futures 提供的线程池执行器。它会预先管理一组线程,让你把多个任务提交给线程池并发执行,而不用手动创建、启动和回收线程。
线程池可以理解成:提前准备一组线程,任务来了就交给空闲线程处理,用完线程不销毁,继续等待下一个任务。
ThreadPoolExecutor 是 Python 标准库 concurrent.futures 提供的线程池执行器。它会预先管理一组线程,让你把多个任务提交给线程池并发执行,而不用手动创建、启动和回收线程。
线程池可以理解成:提前准备一组线程,任务来了就交给空闲线程处理,用完线程不销毁,继续等待下一个任务。
MeshStandardMaterial 是 three.js 里默认走 PBR 的材质。它的着色基于 metallic-roughness 工作流——也就是 glTF 用的那一套——光照响应是物理化的,跟 MeshPhongMaterial 那种靠高光指数凑出来的效果不是一个路子。
它一共两个核心旋钮:
| 参数 | 范围 | 含义 |
|---|---|---|
metalness |
0–1 | 0 是电介质(塑料、木头、漆面、玻璃),1 是纯金属。中间值基本只在烘焙贴图里出现 |
roughness |
0–1 | 0 是镜面,高光收成一个点;1 完全漫反射,没有高光 |
两个参数,配上一张 color、一张法线贴图,已经能覆盖场景里绝大部分东西:塑料外壳、木头桌面、没上漆的金属、混凝土、地面。日常够用了。
但它们有一条共同的边界——描述的全都是”同一个表面”。roughness 说的是这个表面有多粗糙,metalness 说的是这个表面是不是金属,color 说的是这个表面是什么颜色。三个答案指向的是同一层。
一辆车不是这么回事:
前两条 MeshStandardMaterial 表达不了:它没法说”这个表面之上还盖着另一层,那层有自己的粗糙度”,也没法说”光会穿过这个表面,并在里面走一段”。
MeshPhysicalMaterial 就是来补这两块的。
鼠标移到光伏基站里的配电箱上,箱体亮起一圈黄边;移到旁边的汇流箱上,边就跟着换到汇流箱。这一圈边就是轮廓线,three.js 里对应的东西是后处理里的 OutlinePass。
先把一个容易混的地方分开:这圈边是”画”出来的,”鼠标在哪个箱体上”是”算”出来的。 判断鼠标指着谁用的是 Raycaster 射线拾取,把那个物体描一圈用的是 OutlinePass。两件事经常一起出现,但互不认识——OutlinePass 全程不关心鼠标,它只知道”这批物体要描边”。
这篇只讲描边那一半。
场景里要放一万个一样的物体,最直接的写法是循环 new 一万个 Mesh,一个个 add 进场景。几十个没问题,上万之后帧率会掉下来一大截。
原因不在几何体:一万个立方体加起来也才 12 万个三角形,对 GPU 来说这点量很小。问题出在 DrawCall。
Vue 解决 LLM 对话过长问题:使用 markstream
先看一张截图。

之前见过这个vue如何解决LLM对话过长问题,那条回复说的是答案:
LLM 聊天很容易变成长会话。节点数量会持续膨胀。虚拟滚动,只渲染当前屏幕看到的内容。其它只占位。
—— 版本答案是 使用 markstream,此题应 @simon_he1995
「虚拟滚动」这四个字在列表场景里是老生常谈,但把它搬到 LLM 聊天里,有一个前提条件会被打破。这篇就把这两句话中间的推理补上,再说怎么落地。
用到的组件是 markstream-vue,文档在 markstream.simonhe.me。示例项目是一个能跑起来的最小聊天 Demo:Vue 3 + Vite,消息列表交给 MarkstreamVirtualTimeline,正文交给 MarkdownRender。
Claude Code 使用笔记:CLI、Skill、MCP、工作流,以及怎么接到本地 3D / 前端项目上。
Claude Code 配置 Chrome DevTools MCP 指南
本文详细介绍如何在 Windows 系统上为 Claude Code 配置 Chrome DevTools MCP,包括踩坑经验和解决方案。
在自动驾驶、点云可视化、目标检测等场景中,经常需要把算法输出的 3D 检测框叠加到点云上。
在数字孪生、WebGIS、激光雷达、自动驾驶、测绘等场景中,点云数据很容易达到千万、上亿甚至更大的规模。
把经纬度转到墨卡托,再映射到 Three.js 世界坐标,才能把行政区轮廓挤出到地图上。