Show HN:一个CSS 3D引擎(无需WebGL)
摘要
PolyCSS 是一个 CSS 多边形网格库,能将 3D 模型渲染为真实的 HTML 元素(使用 CSS matrix3d),支持 OBJ/MTL、GLB 和 VOX 格式,可与 React、Vue 或原生 JavaScript 配合使用。
查看缓存全文
缓存时间: 2026/06/01 16:44
LayoutitStudio/polycss 来源:https://github.com/LayoutitStudio/polycss
PolyCSS
一个CSS多边形网格库。面向DOM的3D引擎。将OBJ/MTL、GLB和VOX文件渲染为真实的HTML元素,并通过CSS matrix3d(...) 进行变换。支持颜色、纹理、光照、阴影、形状和动画。可与React、Vue或纯JavaScript配合使用。访问 polycss.com (https://polycss.com) 获取文档和模型示例。
安装
# Vanilla
npm install @layoutit/polycss
# React
npm install @layoutit/polycss-react
# Vue
npm install @layoutit/polycss-vue
你也可以直接从CDN加载PolyCSS。以下是一个最简的自定义元素场景:
<!DOCTYPE html>
<html>
<body>
<poly-scene>
<poly-camera rotX="65" rotY="45"></poly-camera>
<poly-mesh src="https://polycss.com/gallery/obj/cottage.obj" mtl="https://polycss.com/gallery/obj/cottage.mtl"></poly-mesh>
</poly-scene>
</body>
</html>
框架组件
React 和 Vue 暴露了相同的组件模型。<PolyCamera> 拥有视点,<PolyScene> 拥有光照和纹理图集选项,<PolyMesh> 加载或接收多边形数据。
import { PolyCamera, PolyScene, PolyOrbitControls, PolyMesh } from "@layoutit/polycss-react";
export default function App() {
return (
<PolyScene>
<PolyCamera rotX={65} rotY={45} />
<PolyOrbitControls />
<PolyMesh src="https://polycss.com/gallery/obj/cottage.obj" mtl="https://polycss.com/gallery/obj/cottage.mtl" />
</PolyScene>
);
}
API 参考
PolyCamera
rotX、rotY控制轨道角度(单位:度)。zoom缩放投影场景。target在世界坐标中平移相机目标点。distance增加摄像机拉远距离。PolyCamera是正交投影默认相机。使用PolyPerspectiveCamera可获得透视景深。
PolyScene
polygons直接渲染静态Polygon[]。directionalLight和ambientLight控制场景光照。textureLighting选择"baked"或"dynamic"。textureQuality控制纹理图集栅格预算。strategies可禁用选中的渲染策略,用于诊断。autoCenter围绕渲染网格的边界框旋转,而非世界原点。
PolyMesh
src加载.obj、.gltf、.glb或.vox文件。mtl加载配套的OBJ材质。polygons接受预解析的几何体。position、scale和rotation变换网格容器。autoCenter将网格边界框中心移至局部原点。meshResolution选择"lossy"(默认)或"lossless"优化。castShadow在动态光照模式下发射CSS投影阴影。
控制
<PolyOrbitControls>添加拖拽轨道、Shift+拖拽平移、滚轮缩放,以及可选自动旋转。<PolyPanControls>使用平移优先的地图式输入。<PolyWASDControls>提供键盘和指针锁定导航。<PolyTransformControls>为选中的网格手柄添加平移/旋转控件。
快照导出
Vanilla 包导出 exportPolySceneSnapshot(target)。它会克隆当前渲染的 .polycss-camera / .polycss-scene DOM,注入该快照所需的PolyCSS样式,内联CSS url(...) 图片资源为 data:image/...;base64,...,移除脚本和内联事件处理器,返回一个不包含PolyCSS运行时的独立HTML文档字符串。它也适用于渲染后的React/Vue场景;从 @layoutit/polycss 导入并将渲染后的相机或场景元素传递给它。
import { exportPolySceneSnapshot } from "@layoutit/polycss";
const html = await exportPolySceneSnapshot(scene.host);
如果任何引用的资源无法内联,函数会抛出 PolySceneSnapshotError,并包含 code: "ASSET_INLINE_FAILED"。
多边形数据模型
每个多边形描述一个可渲染的面:
const polygons = [
{
vertices: [[0, 0, 0], [60, 0, 0], [0, 60, 0]],
color: "#f97316",
},
{
vertices: [[0, 0, 0], [60, 0, 0], [60, 60, 0], [0, 60, 0]],
texture: "/texture.png",
uvs: [[0, 0], [1, 0], [1, 1], [0, 1]],
},
];
当你需要逐个面的DOM事件或自定义样式时,可直接渲染多边形:
{polygons.map((polygon, index) => (
<poly-mesh-polygon
key={index}
polygon={polygon}
onClick={() => console.log("clicked polygon", index)}
className="my-polygon"
/>
))}
加载网格文件
使用 loadMesh() 解析支持的模型格式:
import { createPolyCamera, createPolyScene, loadMesh } from "@layoutit/polycss";
const host = document.getElementById("polycss")!;
const camera = createPolyCamera({ rotX: 65, rotY: 45 });
const scene = createPolyScene(host, { camera });
const mesh = await loadMesh("https://polycss.com/gallery/obj/cottage.obj", {
mtlUrl: "https://polycss.com/gallery/obj/cottage.mtl",
});
scene.add(mesh);
支持的格式:
- OBJ + MTL,包括
map_Kd纹理和UV坐标。 - glTF / GLB,包括内嵌图片和
TEXCOORD_0。 - MagicaVoxel
.vox,在符合条件时使用直接体素快速路径。 - 生成的基元:立方体、平面、圆环、球体、环面、圆柱、圆锥,以及柏拉图立体。
性能
PolyCSS 通过 DOM 渲染,因此性能主要受两个因素影响:挂载的叶子节点数量,以及浏览器需要绘制的纹理图集面积。渲染器尽量保持常见情况的低成本。简单表面保持为纯CSS元素,而有纹理、不规则或高细节几何体仅在必要时回退到基于图集的切片。
每个可见多边形被输出为一个叶子元素;渲染器选择最能表示该多边形的最廉价CSS基元,然后使用 matrix3d(...) 将该基元放置在3D空间中。
<poly-rect>使用固定盒子的background: currentColor表示实心矩形和稳定四边形。<poly-triangle>使用corner-shape表示稳定三角形和倒角实心体,必要时使用border-width三角形回退。<poly-clip>在浏览器支持时使用border-shape: polygon(...)裁剪实心多边形。<poly-atlas>使用background-image映射压缩的纹理图集切片,是纹理化或不支持形状的通用回退。
包
| 包 | 描述 |
|---|---|
@layoutit/polycss-core | 纯数学、解析器、光照、相机助手、网格优化。没有浏览器全局变量。 |
@layoutit/polycss | Vanilla 自定义元素和命令式 createPolyScene API。 |
@layoutit/polycss-react | React 组件、hooks、控件和核心重新导出。 |
@layoutit/polycss-vue | Vue 3 组件、composables、控件和核心重新导出。 |
使用 PolyCSS 制作
Layoutit Voxels (https://voxels.layoutit.com) -> 一个CSS体素编辑器
Layoutit Terra (https://terra.layoutit.com) -> 一个CSS地形生成器
许可证
MIT
相似文章
pascalorg/editor
一个使用 React Three Fiber 和 WebGPU 构建的3D建筑编辑器,采用 Turborepo 单体仓库结构,包含 core、viewer 和 editor 包,分别用于模式定义、3D渲染和交互工具。
@andreasawires:在浏览器中渲染约1亿个三角形。在@threejs上使用随意Nanite风格的分组网格(meshlets)。支持GLB直接拖入和PBR。
一位开发者演示了使用Three.js和Nanite风格的分组网格在浏览器中渲染约1亿个三角形,支持GLB直接拖入和PBR。
Canvas 中的 HTML 演示
来自 Chrome DevRel 团队的 CSS 和 Web UI 演示合集,包括 Canvas 中的 HTML 演示。
Show HN: CADara – 我开发了一个开源的浏览器内 CAD 工具
CADara 是一个开源的浏览器端 CAD 工具,让用户可以直接在网页浏览器中创建 3D 模型。
CSS原生视差效果
使用滚动驱动动画时间线的CSS原生视差效果,提供了一个高性能且简单的工具类,无需JavaScript。