跳转到内容
查看源码

第一个场景

场景(.esn)就是图:它引入 Kernel 库,声明输入、参数和输出,并放置节点。接着上一页,在 rings/ 目录下新建 scene.esn:

use "kernels/";
param warmth: Float = 0.6;
node rings: demo.rings@1 { domain = vec2(256, 256); count = 8.0; }
node tint: demo.tint@1 { source <- rings.result; warmth = warmth; }
output result <- tint.result;
写法 含义
use "kernels/"; 引入目录下所有 .ent(也可以是单个文件或一个包 use "image.entpkg";)。
param warmth: Float = 0.6; 图参数,调用者可以覆盖(--param、协议 param)。
node rings: demo.rings@1 { … } 放置一个节点,按 id 引用已发布的 Kernel。
domain = vec2(256, 256); 没有输入的生成器必须给出定义域:Rows 写整数,Grid 写 vec2,Volume 写 vec3。也可以写 window()。
count = 8.0; 给节点的参数赋值:只能是字面量或图参数名,不能是表达式。
source <- rings.result; 连线:在本次求值中读取 rings 的输出,并构成依赖。连线只写在消费者一侧。
output result <- tint.result; 命名的图输出。第一个 Image 输出就是画面。
终端窗口
entelechy run scene.esn --out out.png
scene loaded
published demo.rings@1 g1 from kernels/rings.ent
published demo.tint@1 g2 from kernels/rings.ent
evaluated in 1.32ms: executed [tint+rings], reused 0 -> out.png

first-scene 的输出

executed [tint+rings] 说明两个节点被融合成了一次计算:tint 只在当前元素处 sample 了 rings,所以中间结果不必写出。用 graph 可以看到执行计划:

终端窗口
entelechy graph scene.esn
// published: demo.rings@1 g1, demo.tint@1 g2, native.cover@1 g0, …
// plan: 1 group(s)
// tint + rings: fused.tint@1 vec2(256, 256)

覆盖参数:

终端窗口
entelechy run scene.esn --out warm.png --param warmth=1.0
终端窗口
entelechy trace scene.esn --node tint --at 10 10
tint (demo.tint@1), element (10, 10), as the evaluation at time 0 runs it
c: Vec4 = vec4(0, 0, 1, 1)
-> result: Vec4 = vec4(0, 0, 0.4, 1)

trace 在解释器上运行一个元素,打印每个 let 的类型和值,不提交任何东西。

tests/rings.replay:

scene ../scene.esn
frame 0.0
expect count rings.result = 65536
expect 128 128 = 0.0 0.0 0.4
终端窗口
entelechy replay tests/rings.replay
tests/rings.replay: ok (1 frames, 2 checks)

完整的回放语法见回放测试。本页的三个文件可以打包下载。

下一页:实时替换——在运行中修改它。