Show HN:一个CSS 3D引擎(无需WebGL)

Hacker News Top 工具

摘要

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

  • rotXrotY 控制轨道角度(单位:度)。
  • zoom 缩放投影场景。
  • target 在世界坐标中平移相机目标点。
  • distance 增加摄像机拉远距离。
  • PolyCamera 是正交投影默认相机。使用 PolyPerspectiveCamera 可获得透视景深。

PolyScene

  • polygons 直接渲染静态 Polygon[]
  • directionalLightambientLight 控制场景光照。
  • textureLighting 选择 "baked""dynamic"
  • textureQuality 控制纹理图集栅格预算。
  • strategies 可禁用选中的渲染策略,用于诊断。
  • autoCenter 围绕渲染网格的边界框旋转,而非世界原点。

PolyMesh

  • src 加载 .obj.gltf.glb.vox 文件。
  • mtl 加载配套的OBJ材质。
  • polygons 接受预解析的几何体。
  • positionscalerotation 变换网格容器。
  • 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/polycssVanilla 自定义元素和命令式 createPolyScene API。
@layoutit/polycss-reactReact 组件、hooks、控件和核心重新导出。
@layoutit/polycss-vueVue 3 组件、composables、控件和核心重新导出。

使用 PolyCSS 制作

Layoutit Voxels (https://voxels.layoutit.com) -> 一个CSS体素编辑器

Layoutit Terra (https://terra.layoutit.com) -> 一个CSS地形生成器

许可证

MIT

相似文章

pascalorg/editor

GitHub Trending (daily)

一个使用 React Three Fiber 和 WebGPU 构建的3D建筑编辑器,采用 Turborepo 单体仓库结构,包含 core、viewer 和 editor 包,分别用于模式定义、3D渲染和交互工具。

Canvas 中的 HTML 演示

Hacker News Top

来自 Chrome DevRel 团队的 CSS 和 Web UI 演示合集,包括 Canvas 中的 HTML 演示。

CSS原生视差效果

Hacker News Top

使用滚动驱动动画时间线的CSS原生视差效果,提供了一个高性能且简单的工具类,无需JavaScript。