☰
WebGLStudio.js 图形化节点编辑完全指南:用 Graph 组件连接场景属性与行为逻辑
2026/10/13 3:05:14 网站建设 项目流程
  • 图形学
  • 前端
  • 开发工具

【免费下载链接】webglstudio.js

A full open source 3D graphics editor in the browser, with scene editor, coding pad, graph editor, virtual file system, and many features more.

项目地址:https://gitcode.com/gh_mirrors/we/webglstudio.js
点击查看免费下载

WebGLStudio.js 内置了基于 LiteGraph 的可视化节点编辑系统(Graph),无需编写代码即可将场景中不同组件的属性"连线"起来,实现属性同步、数值运算与渲染特效控制。本文以官方文档 guides/graphs.md 为核心,结合编辑器源码(editor/js/modules/graph.js、editor/js/widgets/ui/graphWidget.js、editor/js/extra/litescene.js)逐层拆解:如何在场景节点上创建 Graph 组件、区分行为图(GraphComponent)与渲染图(FXGraphComponent)、如何从检查器拖拽属性进画布、如何连线与调整节点,让你快速上手这套"拖线即编程"的工作流。

Graph 是什么:用连线替代代码

在 WebGLStudio.js 中,Graph(图形化节点编辑器)允许开发者通过可视化节点与连线来控制组件行为,或将不同组件的属性互连。相比手写脚本,这种方式更直观、更不易出错,但表达能力也更有限——它适合解决"两个属性保持相等或存在关联关系"这类问题,而非实现复杂逻辑。

一个典型的场景:移动场景中的一个节点时,希望另一个节点的 Y 位置自动跟随。传统做法是写脚本监听变换事件,而用 Graph 只需把"节点 A 的 Y 属性"用一根线接到"节点 B 的 Y 属性"上即可。

从源码结构看,这套能力分为三层:

  • LS.Components.GraphComponent(行为图组件):挂载在任意场景节点上,负责驱动普通逻辑图;
  • LS.Components.FXGraphComponent(渲染图组件):挂载在节点上,在渲染管线中执行,可输出纹理、颜色、深度等渲染结果;
  • LS.GraphCode(图资源):将一张图以资源形式存储,可被多个 GraphComponent 共享(见 editor/js/extra/litescene.js 中的GraphCode构造函数,其内部持有LiteGraph.LGraph实例,并在_graph._graphcode上与图互相引用)。

图的值可以来自场景中的其他属性,也可以由更复杂的计算产生——随机数、三角函数、数学运算等节点都可用。这正是 LiteGraph 生态所提供的能力。

创建 Graph 组件:行为图与渲染图

要在场景中使用图,首先需要给场景中的任意节点挂载一个 Graph 组件。WebGLStudio.js 提供了两种 Graph 组件类,用途不同:

组件类适用场景典型执行内容
GraphComponent行为/逻辑控制属性同步、数学运算、触发动作、更新变换
FXGraphComponent渲染特效后处理、纹理生成、光照合成、渲染帧输出

创建方式有两种:

  1. 在Graph 标签页(工具栏上方图标为 tabicon-graph.png)点击顶部的New按钮,在弹出的对话框中用Graph Type下拉框选择GraphComponent或FXGraphComponent,并选择要挂载的目标Node,然后点击Create Graph。对应实现见 graphWidget.js 的onNewGraph:它创建new LS.Components[graph_type]()并root.addComponent(component)到所选节点上。
  2. 在任意节点上通过 Inspector 添加组件(GraphComponent/FXGraphComponent),添加后即可在组件面板中编辑。

值得注意的默认行为(源码级细节):

  • 新建GraphComponent时若未提供序列化数据,会自动创建一个scene/node节点作为默认内容(litescene.js);
  • 新建FXGraphComponent时默认图内已有一个名为"Rendered Frame"的scene/frame节点,且该节点被标记为ignore_remove与ignore_rename(不可删除、不可改名),它是渲染帧的入口(litescene.js)。

选择图何时执行:on event

GraphComponent有一个核心配置项on event(on_event属性),决定图在什么时机被驱动。源码中定义的可选值如下(litescene.js):

GraphComponent["@on_event"] = { type:"enum", values: ["start","render","beforeRenderScene","afterRenderScene","update","trigger"] };
值含义
start场景启动时执行一次(对应onSceneEvent中的start事件,会向图内节点广播onStart并置图状态为运行中)
render渲染主通道前执行(源码将beforeRenderMainPass事件翻译为render)
beforeRenderScene/afterRenderScene场景渲染前后执行
update每帧更新阶段执行(默认值)
trigger仅当组件收到trigger事件时执行

在 Inspector 中,该配置以下拉框呈现:inspector.addCombo("on event", component.on_event, { values: LS.Components.GraphComponent["@on_event"].values ... })(见 graph.js)。此外还有一个redraw(force_redraw)复选框,勾选后每次运行图都会强制请求重绘帧(对应runGraph中if(this.force_redraw) this._root.scene.requestFrame(),litescene.js)。

对于FXGraphComponent,Inspector 还会额外显示Frame Settings(渲染帧上下文配置)、Antialiasing(use_antialiasing)和Use node camera(use_node_camera)等渲染专属选项(graph.js)。渲染图挂载到场景后,会绑定BEFORE_RENDER、ENABLE_FRAME_CONTEXT、SHOW_FRAME_CONTEXT、RENDER_GUI四个渲染生命周期事件,并向资源管理器注册:color_uid、:depth_uid、:extra_uid三类内部资源,供纹理类节点读写(litescene.js)。

打开图编辑器:Edit Graph

创建组件后,在 Inspector 的组件面板中点击Edit Graph按钮即可打开图编辑器视图。对应实现(graph.js):

inspector.addButton(null,"Edit Graph", { callback: function() { GraphModule.openTab(); GraphModule.editInstanceGraph( component, { id: component.uid, title: component._root.uid } ); }});

它会切换到Graph 标签页,并在标签页下部的图编辑区中载入该组件的图。编辑器整体布局(graph.js)分为上下两部分:

  • 上部是 3D 场景视口(可点击顶部3D按钮切换显隐);
  • 下部是图编辑画布(LGraphCanvas),背景为 litegraph_grid.png 网格。

图编辑器的顶部工具栏(graphWidget.js)提供以下操作:

按钮功能
New新建一张图(选择类型与挂载节点)
Open弹出对话框,列出场景中所有GraphComponent与FXGraphComponent供选择打开
Save保存当前图(仅对from_file的图有效,会同步到对应 GraphCode 资源)
Compile编译图:将画布内容序列化写入 GraphCode,并传播到所有引用该资源的组件
Run Step手动执行一步图(graph.runStep(1)并刷新场景)
Redraw切换画布是否持续重绘
Detach将当前图弹出为独立浮动窗口

快捷键

图编辑器还支持几个实用的键盘快捷键(graph.js):

  • Ctrl + S:保存图;
  • Ctrl + Enter:编译图(Compile);
  • F6:重新加载编辑器。

创建节点:右键菜单与拖拽

图打开后,有多种方式把节点加入画布:

1. 右键菜单创建

在画布空白处右键,会弹出节点创建菜单,节点按类别分组排列,数量众多。选择任意节点后它就会出现在画布中。这一交互由LGraphCanvas的内置右键菜单实现(LiteGraph 核心能力)。

2. 从 Inspector 拖入组件或属性

如果你想把场景中的任意属性带入图内,直接把组件或属性从Inspector 检查器拖到画布即可:

  • 拖组件:按住组件名称旁边的组件图标拖拽;
  • 拖属性:按住属性名称旁边的圆球图标拖拽。

拖入后画布中会出现对应的 GraphNode。源码中注册了多种可拖入类型(graphWidget.js):

拖入类型生成的节点类型说明
SceneNode(场景节点)scene/node引用场景中的某个节点
Component(组件)scene/transform或scene/componentTransform 组件生成变换节点,其他组件生成组件节点
Material(材质)scene/material引用指定材质
property(属性)scene/property以 locator(属性定位符)绑定具体属性
resource(资源,图片等)texture/texture拖入图片资源会自动创建纹理节点并加载

此外,在场景中选中对象后,右键图画布还会出现"Add <类名>"快捷菜单,直接把当前选中对象(节点、组件或变换)添加为图中的节点(graphWidget.js)。

节点插槽:输入、输出与自定义

GraphNode 默认带有输入(inputs)和输出(outputs)插槽。你可以在节点上右键,从Inputs/Outputs菜单中为节点添加新的输入或输出(是否可加取决于节点类型本身)。

以输出为例,源码允许为节点新增自定义事件输出(graphWidget.js):

options.push({content:"New event", className: "event", callback: function( node ){ LiteGUI.prompt("Enter event name", function(v){ if(!v) return; node.addOutput( "on_" + v, LiteGraph.EVENT ); }); }});

输入与输出的数据类型会决定哪些节点可以互相连接——WebGLStudio.js 用连线颜色区分类型,其中Component类型连线为紫色(LGraphCanvas.link_type_colors["Component"] = "#D99",graphWidget.js)。

连接与断开:拖线即绑定

连接两个节点的值,只需把源节点的输出插槽拖到目标节点的输入插槽:

  • 拖动输出端到输入端 → 建立数据流连接;
  • 单击输入端的连接点 → 断开该连接。

连接建立/断开后,编辑器会自动刷新场景以反映新数据流(graphcanvas.onConnectionChange中setTimeout(function(){ LS.GlobalScene.refresh(); }, 100),graphWidget.js)。

当你把鼠标悬停在一条连线上时,若该连线传输的数据是GL.Texture(纹理),还会弹出纹理预览工具提示(onDrawLinkTooltip,graphWidget.js)。

编辑节点属性:双击节点

想要调整任意节点的属性,双击节点即可在检查器(Inspector)中查看和编辑其属性。节点检查面板(graphWidget.js)提供:

  • Title / ID:节点标题与唯一 ID;
  • Size:节点在画布中的尺寸(Vector2);
  • Mode:节点的执行模式(Always始终执行 /On Event事件驱动 /On Trigger触发执行 /Never永不执行);
  • properties 面板:根据节点类型自动生成属性控件——若节点定义了widgets_info则按其声明渲染,否则依据属性类型自动推断控件(数值、布尔、字符串、向量等);
  • 底部按钮:Collapse(折叠节点)、Remove(删除节点)、Show JSON(查看节点序列化 JSON);
  • 描述信息:graphnode.help或constructor.desc会显示在面板底部,便于理解节点用途。

特殊节点:scene/global(全局变量)

图中若包含scene/global类型的节点,它的Name / Type / Value(及 Min/Max)会直接呈现在所属组件的 Inspector 面板上(graph.js),相当于把图内的全局变量"提升"到组件层级,可像普通属性一样实时调节,甚至支持与动画关键帧联动(pretitle: AnimationModule.getKeyframeCode(...))。调节后若组件的on_event为render或update,会立即执行一步图并刷新场景。

图的存储与共享:inner graph 与 graph file

Graph 组件支持两种存储方式(源码中由from_file标志区分):

  • inner graph(内嵌图):from_file = false,图直接序列化在组件内部,随场景保存;工具栏中的Save按钮对这类图不可用;
  • graph from file(文件图):from_file = true,图存储为独立的GraphCode资源(.graph文件),同一份图可被多个组件共享;编辑后需点击Compile或Save,将画布内容写回 GraphCode 并传播到所有引用它的组件(graphcode.propagate(),graphWidget.js)。

在组件 Inspector 中(graph.js)可以通过右键动作在两种模式间切换:

  • Convert to Inner Graph:转为内嵌图;
  • Convert to Graph From File:转为文件图(需指定图文件名)。

另外,组件上还有两个实用动作(graph.js):

  • Set Title:为图设置标题;
  • Show Graph JSON:在弹出的 JSON 检查器中查看整张图的序列化结构——这也是排查连线问题的好帮手。

深入原理:图如何驱动场景

从实现层面看,GraphComponent每次执行调用的是this._graph.runStep(1, LS.catch_exceptions)(litescene.js),即 LiteGraph 的LGraph.runStep单步求值:所有Always模式节点按拓扑顺序执行一次,把输出数据沿连线推送到下游输入。而FXGraphComponent则完全绑定渲染管线:在BEFORE_RENDER阶段向所有节点广播onPreRenderExecute预读纹理,在帧上下文启用后执行图,最终把渲染结果注册为:color_uid、:depth_uid、:extra_uid三类可复用资源(litescene.js)。理解这条链路,有助于判断"为什么我的图在某个时机没生效"——通常要回到on event配置与节点的Mode设置上排查。

更多资料

  • 图编辑器底层基于LiteGraph节点引擎实现,WebGLStudio.js 运行时内置 litegraph.js,组件与编辑器的集成代码见 graph.js、graphWidget.js;
  • 图组件的完整序列化字段、执行逻辑与渲染绑定位于 litescene.js 的GraphComponent(约 L44489 起)与FXGraphComponent(约 L44927 起);
  • 更多关于节点系统本身的机制(节点类型注册、图序列化、运行状态机等)可参考 LiteGraph 项目文档;
  • 编辑器的整体架构说明见 guides/editor_architecture.md,其他脚本模块清单见 guides/editor_scripts.md。
  • 图形学
  • 前端
  • 开发工具

【免费下载链接】webglstudio.js

A full open source 3D graphics editor in the browser, with scene editor, coding pad, graph editor, virtual file system, and many features more.

项目地址:https://gitcode.com/gh_mirrors/we/webglstudio.js
点击查看免费下载
上一篇:Haystack 评估结果解析:EvaluationRunResult 类完整指南
下一篇:桌面端调索尼耳机降噪免翻手机:SonyHeadphonesClient 5 分钟上手

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询