python线程池

ThreadPoolExecutor 是 Python 标准库 concurrent.futures 提供的线程池执行器。它会预先管理一组线程,让你把多个任务提交给线程池并发执行,而不用手动创建、启动和回收线程。

线程池可以理解成:提前准备一组线程,任务来了就交给空闲线程处理,用完线程不销毁,继续等待下一个任务。

阅读更多

threejs使用pbr物理材质

MeshStandardMaterial 是 three.js 里默认走 PBR 的材质。它的着色基于 metallic-roughness 工作流——也就是 glTF 用的那一套——光照响应是物理化的,跟 MeshPhongMaterial 那种靠高光指数凑出来的效果不是一个路子。

它一共两个核心旋钮:

参数 范围 含义
metalness 0–1 0 是电介质(塑料、木头、漆面、玻璃),1 是纯金属。中间值基本只在烘焙贴图里出现
roughness 0–1 0 是镜面,高光收成一个点;1 完全漫反射,没有高光

两个参数,配上一张 color、一张法线贴图,已经能覆盖场景里绝大部分东西:塑料外壳、木头桌面、没上漆的金属、混凝土、地面。日常够用了。

但它们有一条共同的边界——描述的全都是”同一个表面”。roughness 说的是这个表面有多粗糙,metalness 说的是这个表面是不是金属,color 说的是这个表面是什么颜色。三个答案指向的是同一层。

一辆车不是这么回事:

  • 车漆是两层。底下是带颜色的色漆,上面覆一层无色透明的清漆。清漆有自己的粗糙度,跟底色那层完全是两回事——底色可以很哑,清漆同时很亮。
  • 玻璃不是一个”表面”,是一个”体积”。光要穿过去,还要在穿过的那段路程里被染色。
  • 轮毂是纯金属,没有漫反射,看到的全是反射来的环境。这条 standard 能表达,但它会牵出环境贴图的问题。

前两条 MeshStandardMaterial 表达不了:它没法说”这个表面之上还盖着另一层,那层有自己的粗糙度”,也没法说”光会穿过这个表面,并在里面走一段”。

MeshPhysicalMaterial 就是来补这两块的。

阅读更多

threejs后处理实现轮廓线功能

鼠标移到光伏基站里的配电箱上,箱体亮起一圈黄边;移到旁边的汇流箱上,边就跟着换到汇流箱。这一圈边就是轮廓线,three.js 里对应的东西是后处理里的 OutlinePass。

先把一个容易混的地方分开:这圈边是”画”出来的,”鼠标在哪个箱体上”是”算”出来的。 判断鼠标指着谁用的是 Raycaster 射线拾取,把那个物体描一圈用的是 OutlinePass。两件事经常一起出现,但互不认识——OutlinePass 全程不关心鼠标,它只知道”这批物体要描边”。

这篇只讲描边那一半。

阅读更多

Three.js InstancedMesh 实例化渲染

场景里要放一万个一样的物体,最直接的写法是循环 new 一万个 Mesh,一个个 add 进场景。几十个没问题,上万之后帧率会掉下来一大截。

原因不在几何体:一万个立方体加起来也才 12 万个三角形,对 GPU 来说这点量很小。问题出在 DrawCall。

阅读更多

Vue 解决 LLM 对话过长问题:使用 markstream

先看一张截图。

iArchi 在 X 上回答「LLM 聊天变成长会话怎么办」:版本答案是使用 markstream

之前见过这个vue如何解决LLM对话过长问题,那条回复说的是答案:

LLM 聊天很容易变成长会话。节点数量会持续膨胀。虚拟滚动,只渲染当前屏幕看到的内容。其它只占位。

—— 版本答案是 使用 markstream,此题应 @simon_he1995

「虚拟滚动」这四个字在列表场景里是老生常谈,但把它搬到 LLM 聊天里,有一个前提条件会被打破。这篇就把这两句话中间的推理补上,再说怎么落地。

用到的组件是 markstream-vue,文档在 markstream.simonhe.me。示例项目是一个能跑起来的最小聊天 Demo:Vue 3 + Vite,消息列表交给 MarkstreamVirtualTimeline,正文交给 MarkdownRender。

阅读更多

Claude Code 专栏

Claude Code 使用笔记:CLI、Skill、MCP、工作流,以及怎么接到本地 3D / 前端项目上。

阅读更多

threejs加载3D检测框

在自动驾驶、点云可视化、目标检测等场景中,经常需要把算法输出的 3D 检测框叠加到点云上。

阅读更多

Three.js 加载大规模点云

在数字孪生、WebGIS、激光雷达、自动驾驶、测绘等场景中,点云数据很容易达到千万、上亿甚至更大的规模。

阅读更多