INTERACTIVE RENDERING NOTEBOOK / 01

别急着读实现。
先把参数弄坏。

把圆角拉到放不下,把图片翻转,把贝塞尔曲线拆成折线,在 endFrame() 前后观察 command queue。每个实验都对应 WhatsCanvas 当前的一段真实分支。

about_this_lab.txt

$ 这不是 API 清单。

$ 左侧控件改变输入,画布显示中间结果。

$ 右侧读数告诉你代码会选择哪条路径。

浏览器 Canvas 用于复现几何和合成概念,并未直接执行 C++ renderer。函数名、限制和分支来自仓库当前实现。

00

LAB MAP

从一次 API 调用,走到最终像素

可以顺序操作,也可以直接跳到你最想拆开的 API。

01Frame命令何时执行 02RoundRect半径、细分与缓存 03Imagesrc/dst、UV 与采样 04Path曲线怎样变成三角形 05Text排版之后的三条路 06ClipScissor 与 coverage mask 07Statesave/restore 到底保存什么 08Layer整体 alpha 与离屏合成
01

COMMAND LIFECYCLE

drawText() 返回时,屏幕可能还没变化

按顺序录制几条命令。只有点击 endFrame(),右侧 framebuffer 才更新。

API CONSOLEIDLE
COMMAND QUEUE 0
队列为空
    framebuffer.previewpresented: 0

    试一次:先录制两个 draw,再点第二次 beginFrame()。队列会被清掉,framebuffer 保持原样。

    beginFrame()record commandsendFrame(): compile + execute + consumepresent/read
    02

    PRIMITIVE FAST PATH

    把圆角拉到放不下,看看四个半径怎样一起缩

    左侧画布显示约束后的轮廓和细分点;右侧实时给出 fast path、segment count 和缓存复用量。

    round_rect.mesh

    橙色点是离散后的圆弧。放大 zoom 后,物理误差增加,代码会提高每个角的细分数。

    03

    TEXTURE SAMPLING

    裁剪框移动 1 像素,UV 到底变了多少

    拖动源区域和缩放比例。左边是生成的 sprite sheet,右边是实际采样结果。

    source.texture256 × 256
    destination.quadBATCH: ELIGIBLE

    04

    GEOMETRY TRANSFORMATION

    拖动控制点,亲眼看着 Bézier 消失

    橙色控制点可以拖动。切换阶段后,画布依次显示 curve、flattened contour、fill triangles 和 AA fringe。

    path.pipeline拖动 P1 / P2

    教学演示使用可调固定采样,便于观察顶点变化;WhatsCanvas 实际曲线展开使用自己的容差规则。

    05

    TEXT AFTER SHAPING

    11px × 1.5 为什么按 17px 栅格化,却仍占 11px 布局

    改变字号和 DPR,观察 raster size、逻辑回缩与 ClearType 资格如何联动。

    glyph.outputGLYPH ATLAS
    06

    CLIP COVERAGE

    同样一句 clip*,矩形只要四个整数,圆形需要一张 mask

    切换形状并增加裁剪层数。右侧会放大显示最终 coverage accumulator。

    content + coarse boundsSCISSOR
    coverage.accumulatorMASK
    07

    GRAPHICS STATE STACK

    restore() 不会擦掉红色矩形

    拖动步骤,观察 current matrix、clip 和 save count。已经录制的 command 会留在画面里。

    state.timelineSTEP 0 / 6
    初始savetranslateclipdrawrestoredraw
    08

    OFFSCREEN COMPOSITING

    三个半透明图元,和一个半透明图层差在哪里

    左右两幅图使用同一组形状。左边逐个混合,右边先画入离屏 Canvas,再整体合成。

    per_item_alpha3 × COMPOSITE
    saveLayer_alpha1 × COMPOSITE