DEV Community

alphanine
alphanine

Posted on

Turing Render: A Cel Style for Anime-Look Robot Animation

Turing RT now renders USD scenes in the Cel style of Turing CAD — the same SO-101 view in realtime ray tracing and in cel. / Turing RT 现在能把 USD 场景渲染成 Turing CAD 的三渲二风格:同一视角下的实时光追与三渲二对比。

Cel style vs realtime ray tracing on the SO-101 arm

The same SO-101 view rendered by Turing RT in realtime ray tracing and in the new cel style (1920x1280 renders, cropped).


Situation

Turing CAD already had a Cel Shaded viewport style: parts in their material colours, one hard step from light to a cooler shadow tone, a hard white highlight, dark parts painted charcoal, metal as two flat bands, and black ink. Looking at it, the user saw that this anime look could be used for animation. The CAD viewport is a small Metal rasterizer built for modelling, though. It draws CAD data directly and does not read USD, so Turing Sim, where robots actually move, had no way to show that look.

Task

We first had to decide where the look belongs. The user asked whether the CAD rasterizer could become a standalone renderer, the way Mantra was for Houdini. We decided against it. A standalone renderer is fine, but Mantra's weakness was its private scene format, which Houdini later fixed by moving to Karma, a Hydra render delegate that reads USD. Turing RT is already that kind of renderer and already runs inside Turing Sim. So the plan was to port the shading rules into Turing RT, not the CAD rasterizer's code.

What made it hard:

  • The look depends on hard steps and crisp lines. A path tracer's noise and denoiser would smear both.
  • Ink needs to know where one surface ends and another starts. Turing RT has no B-rep face ids and no rasterized G-buffer.
  • It has to stay fast enough to scrub and play animation.

Action

  1. Cel style in Turing RT (turing:style = 1). A new two-kernel path. celSurface traces one camera ray and one shadow ray per pixel and writes position, part, normal and the cel tone. celInk compares each pixel with its neighbours. A neighbour that is nearer, and not on the pixel's tangent plane, puts the pixel behind an outline. That gives silhouettes and occlusion lines on the far side, like the inverted hull Turing CAD draws (3 px). Normals that bend more than 35°, and two parts meeting flush, give a centred edge (2 px). Every pixel in a pass uses the same sub-pixel offset, so neighbours are compared like with like. 32 passes are averaged for anti-aliasing. Shadows are cast by the scene's key light: the first distant light, else another light, else the built-in sun.
  2. Cel Shaded mode in Turing Sim. A fourth entry in the render-mode menu sets the style on Turing RT, in both the native viewport and the in-viewport Hydra fallback.
  3. Command line. turing-render render --style cel --frame N renders one animation frame from USD.

Settings turing:celShadow, turing:outlineWidth and turing:edgeWidth are declared in the delegate and the Python package together, and an existing test keeps their defaults in step. Validation:

  • A new GPU test checks flat face colour, a cooler shadow tone, a cast shadow on the ground, ink at the silhouette, and no ink when the widths are 0.
  • Turing RT's existing 58 tests still pass.
  • Turing Sim's render-mode tests pass. One unrelated Sim test was already failing on stale expectations and was left alone.

Result

On the SO-101 follower arm at 1920×1280, a cel pass takes about 2.2 ms on the development Mac. The anti-aliased image converges in 0.2 s; realtime ray tracing took 6.4 s to settle on the same view. The arm reads like an animation frame. The parts keep their colours, the servos are charcoal rather than black, and ink lands on part boundaries and hard creases but not on fillets.

Limits remain:

  • Tangent B-rep edges get no ink, because edges come from shading normals rather than face ids.
  • Glass and opacity cutouts are drawn opaque.
  • The light is fixed in the world; there is no light-follows-view option yet.
  • Sim's Cel Shaded mode has passed tests but has not yet been tried in the running app.

Next: try it while a Sim animation plays, then decide whether B-rep face ids are worth exporting for tangent edges.


背景

Turing CAD 已经有一个 Cel Shaded 视口风格:零件用材质颜色,亮部到偏冷的暗部只有一次硬过渡,有一个硬白高光;深色零件涂成炭灰,金属只画两段平色,再加黑色墨线。用户看了以后觉得这种三渲二风格完全可以拿来做动画。但 CAD 视口是一个为建模写的小型 Metal 光栅器,直接画 CAD 数据,不读 USD。机器人真正动起来的地方是 Turing Sim,那里看不到这种风格。

目标与难点

先要决定这种风格放在哪里。用户问过:能不能把 CAD 的渲染器独立出来,像 Houdini 当年的 Mantra 那样?我们的结论是不这样做。独立渲染器本身没问题;Mantra 的短板是它的专用场景格式,Houdini 后来换成了 Karma,一个读 USD 的 Hydra 渲染代理。Turing RT 已经是这种渲染器,而且已经跑在 Turing Sim 里。所以方案是把着色规则移植进 Turing RT,而不是搬 CAD 光栅器的代码。

难点有三个:

  • 这种风格靠硬过渡和干净的线条,路径追踪的噪声和降噪会把两者都抹糊。
  • 描线需要知道一个面在哪里结束、另一个面从哪里开始,而 Turing RT 没有 B-rep 面编号,也没有光栅化的 G-buffer。
  • 速度要快到能拖动时间轴、播放动画。

解决思路与行动

  1. Turing RT 的三渲二风格(turing:style = 1)。 新增一条由两个 kernel 组成的渲染路径。celSurface 每像素打一条相机光线和一条阴影光线,写出位置、所属零件、法线和三渲二颜色。celInk 把每个像素和周围像素比较。如果邻居更近,而且不在本像素的切平面上,本像素就落在轮廓线后面。这样外轮廓和遮挡线画在远侧,效果和 Turing CAD 的反向外壳一样(3 px)。法线夹角超过 35° 的硬折边、以及两个零件平齐贴合的地方,画居中的边线(2 px)。同一遍里所有像素用同一个亚像素偏移,所以相邻像素的比较是对等的;累加 32 遍完成抗锯齿。投影由场景主光产生:优先取第一个平行光,没有就取其他灯,再没有就用内置太阳。
  2. Turing Sim 的 Cel Shaded 模式。 渲染模式菜单里多了第四项,在原生视口和视口内 Hydra 两种路径下都会把这个风格设置给 Turing RT。
  3. 命令行。 turing-render render --style cel --frame N 可以从 USD 渲染单帧动画。

turing:celShadow、turing:outlineWidth、turing:edgeWidth 三个设置在渲染代理和 Python 包里同时声明,已有测试保证两边的默认值一致。验证情况:

  • 新增一个 GPU 测试,检查面颜色是平的、暗部偏冷、地面上有投影、轮廓处有墨线、线宽设为 0 时没有墨线。
  • Turing RT 原有的 58 个测试仍全部通过。
  • Turing Sim 的渲染模式测试通过。Sim 另有一个测试原本就因期望值过时而失败,与这次改动无关,这次没有动它。

结果与下一步

在开发用的 Mac 上,SO-101 从动臂 1920×1280 渲染一遍约 2.2 ms,抗锯齿后的图 0.2 s 收敛;同一视角下实时光追要 6.4 s 才稳定。渲出来的机械臂像一帧动画:零件保留各自颜色,舵机是炭灰而不是纯黑,墨线画在零件交界和硬折边上,圆角上没有。

还有这些限制:

  • B-rep 的相切边不画线,因为线条来自着色法线而不是面编号。
  • 玻璃和镂空按不透明处理。
  • 光源固定在世界中,还没有“光随视角”的选项。
  • Sim 的 Cel Shaded 模式已经通过测试,但还没有在运行中的应用里实际试过。

下一步:在 Sim 播放动画时实际试用,再决定是否值得为相切边导出 B-rep 面编号。

Top comments (0)