最近这个项目挺火的,3D画细胞模型,技术上倒挺简单,主要是用Tripo模型来生3维,然后用Three.js来可视化。有人用它做了一个三星堆文物的3维可视化。

Tripo(VAST-AI 团队做的 3D 生成服务)有 API。喂一张图片进去,三十秒吐一个 .glb 模型出来。关键是,Tripo 是正经做 image-to-3D 的,生成的模型不是那种多视角拼凑的纸片,是水密的、带纹理的、能直接丢进 Blender 用的。

整个技术栈就比较简单,于是我给 tripo 的 API 写了个 R 皮。包名叫 cast3d

能干什么

简单来说就是一句话:

model <- generate_3d("your_photo.jpg")
view_3d(model)

一张图片进去,一个可以在 RStudio Viewer 里拖拽旋转的 3D 模型出来。

我拿 GPT 画了个噬菌体,然后让 cast3d 生成了 3D 版:

噬菌体示例

生成的模型是这样的——头部二十面体、颈环、尾鞘、基板六根尾丝,结构完整,不是糊成一团的那种:

一分钟上手

remotes::install_github("YuLab-SMU/cast3d")
library(cast3d)
 
# 先设 API Key(从 https://platform.tripo3d.ai/api-keys 拿)
cast3d_setup(api_key = "tsk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
 
# 一行搞定
model <- generate_3d("cat.jpg")
view_3d(model)

view_3d() 用的是 Three.js,操作跟各种 3D 软件一样:左键拖拽旋转,右键平移,滚轮缩放,双击复位。

如果你习惯配环境变量,直接写 ~/.Renviron

TRIPO_API_KEY=tsk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

包加载时自动读。

如果你的网络需要走代理才能访问外网(国内服务器常见),cast3d_setup 支持设代理:

cast3d_setup(api_key = "你的Key", proxy = "http://127.0.0.1:7897")

分步控制

generate_3d() 是快捷包装,内部拆成了三步。当你想看进度、设超时、或者批量处理时可以分别调:

# 提交任务
task <- create_3d_from_image("photo.jpg")
# ── Task: ef731ad6 ── Status: pending
 
# 轮询等待(每 3 秒查一次,最多等 5 分钟)
result <- poll_task(task, interval = 3, max_wait = 300)
# ✔ Task ef731ad6 complete
 
# 下载模型到本地缓存
model <- download_model(result)
# Model saved to .../cast3d/ef731ad6.glb (2.3 MB)

模型缓存在 tools::R_user_dir("cast3d", "data"),同一个 task 不会重复下载。

查看模型的几种姿势

直接看 GLB 文件

不限于 Tripo 生成的模型,任何标准 GLB 文件都可以:

view_3d("path/to/your_model.glb")

看看模型长什么样

model_info(model)
# $format: "GLB"
# $size_bytes: 2430000
# $vertices: 12500
# $faces: 8300

装了 rgl2gltf 的话会自动读顶点数和面数。

自定义背景

view_3d(model, background = "#1a1a2e", width = 800, height = 600)

Shiny 集成

如果你在做 web app,viewer 可以作为 Shiny 组件嵌入:

library(shiny)
library(cast3d)
 
ui <- fluidPage(
  glb_viewer_output("viewer", height = "600px")
)
 
server <- function(input, output, session) {
  model <- generate_3d("photo.jpg")
  output$viewer <- render_glb_viewer({
    view_3d(model)
  })
}
 
shinyApp(ui, server)

几点说明

API 费用:Tripo 有免费额度,够日常测试用。具体配额查 platform.tripo3d.ai 的 Wallet 页面。

什么图效果好:主体突出、正面或 3/4 视角、光照均匀的图片。背景太乱或者视角太刁钻,AI 也猜不准第三维。

模型版本:默认用 v2.5-20250123,是目前效果最好的 image-to-3D 版本。想省时间可以用 v1.4-20240625(快但精度略低)。create_3d_from_image(model_version = "v2.0-20240919") 指定即可。

能输文本吗:能。generate_3d_from_text("a ceramic teacup") 直接 text-to-3D。Tripo 的 text-to-3D 效果意外地好,比很多专门的 text-to-3D 模型靠谱。如果装了 aisdk(我们另一个 R 包,统一 LLM 调用接口),可以走 image → LLM 描述 → text-to-3D 的路线,有时候比直接 image-to-model 效果更好——尤其在图片细节复杂的情况下。

我的思考

我的想法和尝试都在我视频号里。

如果是我们数据可视化的图,硬塞进去生3D,已经尝试了效果不好。当然效果就算好,我们大概率也不敢在正经的场合用的,也就玩玩。不过数据本身是可以3维可视化的。在R里就是用rgl可视化,那么这个包,其实我提供了GLB格式的可视化,这等同于说,原来你做3维,在R里缺少你能直接在Rstudio、shiny, R markdown中可视化的工具,现在你都可以了。当然这里是用了threejs这个R包,不过之约目前主要面向地球仪/散点图等特定场景,直接加载任意 GLB 模型需要自己写一点代码,我用htmlwidgets给打通了。所以这个包的贡献:

  1. 你能在R里生3D模型了
  2. R的3D更现代化的可视化方式有了

目前只接了Tripo的模型,未来也可以接国内的模型,比如腾讯混元模型这些。

拿一张 梦中情人 自己的照片,生一个3D模型,3D打印出来,你就拥有一个专属手办,感觉可以安排上。