ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Godot 数位板输入实战:基于 graphics_tablet_input 演示构建支持压感与倾斜的绘图应用

Godot 数位板输入实战:基于 graphics_tablet_input 演示构建支持压感与倾斜的绘图应用 示例工程【免费下载链接】godot-demo-projectsDemonstration and Template Projects项目地址https://gitcode.com/GitHub_Trending/go/godot-demo-projects点击查看免费下载本篇文章以 godot-demo-projects 仓库中的 graphics_tablet_input 演示项目 为主体系统讲解在 Godot 中接入数位板输入压感、倾斜、笔尖反转/橡皮擦检测的完整方案如何获取数位板数据、如何用Line2D绘制带压感笔锋的线条、如何通过关闭输入累积与 V-Sync 降低延迟以及如何配置 MSAA 2D 抗锯齿让线条边缘更锐利。读完本文你将能基于这套骨架搭建自己的绘图、笔记或批注类应用。左侧为功能侧边栏线色、线宽、压感开关、倾斜向量显示、MSAA 2D、最大 FPS、V-Sync 与输入累积开关右侧白色画布上绘制了不同颜色与粗细的笔迹底部状态标签实时显示压感、倾斜向量与笔是否倒置。项目概览一个为响应式绘图而生的演示graphics_tablet_input 是仓库 misc 分类下的一个 GDScript 2D 演示其 project.godot 中声明了项目描述 A demo showing how to use graphics tablet input in Godot.渲染器为 Mobilerenderer/rendering_methodmobile主场景为res://graphics_tablet_input.tscn。整个项目由三个文件构成核心逻辑graphics_tablet_input.gd约 190 行的主脚本承载输入处理、笔画管理、设置项回调的全部逻辑graphics_tablet_input.tscn场景布局包含画布ColorRect、侧边栏PanelContainer与全部 UI 控件及其信号连接project.godot项目配置含输入动作Input Actions映射、低处理器占用模式、MSAA 2D 与 V-Sync 的默认设置。演示的运行形态是一块白色画布加左侧设置面板。它支持两种输入方式数位板推荐与鼠标。数位板能带来完整的压感与倾斜体验鼠标只能画出等宽线条——这也正是该演示强调using a tablet is recommended的原因。数位板输入基础Godot 对压感、倾斜与橡皮擦的原生支持支持的数据维度Godot 对数位板输入是全支持的通过鼠标输入事件InputEventMouseMotion即可携带数位板专有数据。README 明确列出了三个核心维度压感Pressure笔尖对板面的压力取值区间为 0.0 到 1.0倾斜Tilt笔身相对板面的倾斜角度以二维向量Vector2报告笔尖反转/橡皮擦Pen Inversion通过pen_inverted布尔值判断用户是否把笔倒过来使用橡皮擦。需要注意的硬件前提部分平台与数位板可能不支持报告倾斜tilt因此依赖倾斜功能的应用必须做好数据缺失的兜底。读取方式与对应的 API在 graphics_tablet_input.gd 的_input()回调中演示用InputEventMouseMotion一次性取出全部数位板数据if input_event is InputEventMouseMotion: var event_mouse_motion : input_event as InputEventMouseMotion tablet_info.text Pressure: %.3f\nTilt: %.3v\nInverted pen: %s % [ event_mouse_motion.pressure, event_mouse_motion.tilt, Yes if event_mouse_motion.pen_inverted else No, ]其中字段类型含义演示中的用途pressurefloat0.0–1.0笔压实时显示到状态标签驱动笔画宽度曲线tiltVector2笔的倾斜向量实时显示绘制可视化箭头pen_invertedbool是否使用橡皮擦端状态标签显示 Yes/NopositionVector2笔尖在画布上的坐标作为Line2D的新增点此外项目启动时在_ready()中调用 DisplayServer.tablet_get_current_driver() 获取当前使用的数位板驱动名称并显示在%TabletDriver标签上。在_input()里还判断了InputEventKey用于处理线宽增减快捷键increase_line_width/decrease_line_width动作对应 project.godot 中/与-/_的按键映射。鼠标输入与数位板输入的区别由于鼠标事件同样以InputEventMouseMotion上报鼠标也能在本演示中绘图但鼠标的pressure恒为 0或极小值因此压感笔锋永远不会触发。如果项目需要区分设备可以进一步检查事件中的设备信息或数位板专属字段本演示并未做此区分仅靠pressure 0的阈值逻辑天然完成鼠标等宽线、数位板可变宽线的差异化体验。笔画渲染管线用 Line2D 实时绘制可压感变宽的笔迹每次抬笔创建新的 Line2D 节点README 明确说明每当你抬笔并开始一条新线就会创建一个新的Line2D节点。对应的实现是 start_stroke()func start_stroke() - void: var new_stroke : Line2D.new() new_stroke.begin_cap_mode Line2D.LINE_CAP_ROUND new_stroke.end_cap_mode Line2D.LINE_CAP_ROUND new_stroke.joint_mode Line2D.LINE_JOINT_ROUND new_stroke.round_precision mini(line_width, 8) new_stroke.default_color line_color new_stroke.width line_width if pressure_sensitive: new_stroke.width_curve Curve.new() add_child(new_stroke) ...这里封装了创建一条新笔画的完整初始化圆头端点LINE_CAP_ROUND、圆角连接LINE_JOINT_ROUND并且round_precision会根据当前线宽动态取值——mini(line_width, 8)意味着线宽越大圆弧精度越高同时不超过默认精度 8在视觉效果与性能之间取得平衡。Line2D通过不断追加点来生长当pressure 0时stroke.add_point(event_mouse_motion.position)把笔尖坐标压入当前笔画同时把压力值存入pressures数组。用 width_curve 实现压感笔锋动态重建宽度曲线压感变宽的实现是本演示最核心的技巧。README 指出该演示use a width curve that is continuously recreated to match the lines actual profile as the line is being drawn也就是每来一个新压力点就清空并重建整条Curveif width_curve: width_curve.clear_points() for pressure_idx in range(pressures.size()): width_curve.add_point(Vector2( float(pressure_idx) / pressures.size(), pressures[pressure_idx] ))Curve的 x 轴是点在整条笔画中的归一化位置pressure_idx / pressures.size()取值 0.0–1.0y 轴是该点的压力值。Line2D.width_curve会按这条曲线在整条线上逐点调制宽度于是压力大的区域线条变粗、压力小的区域线条变细形成自然的笔锋过渡。width_curve只在压感开关打开时创建见start_stroke()中的if pressure_sensitive分支关闭压感时置为null从而避免无谓的曲线重建开销。长笔画自动分段避免性能退化主脚本开头有常量注释# Automatically split lines at regular intervals to avoid performance issues定义了const SPLIT_POINT_COUNT 1024并在追加点时检查if stroke.get_point_count() SPLIT_POINT_COUNT: start_stroke()一旦当前笔画点数达到 1024就自动开启一条新笔画。注释中说明了根因宽度曲线width curve在每个新点上都要被完整重建这属于重负载操作且输入累积被关闭后事件频率极高、点数增长极快分段可以防止单条Line2D无限膨胀导致卡顿。这是绘图应用中一个非常实用的工程化细节。抗锯齿依赖 2D MSAA 而非 Line2D 内建抗锯齿README 明确指出Line antialiasing is provided by enabling 2D MSAA in the Project Settings.——线条的平滑并不来自Line2D自身的采样而是由渲染层面的 2D MSAA多重采样抗锯齿提供。因此项目在 project.godot 中预设了anti_aliasing/quality/msaa_2d3对应 8× MSAA场景侧边栏中的 MSAA 2D 下拉框则提供 Disabled / 2× / 4× / 8× 四档实时切换切换逻辑在 _on_msaa_item_selected() 中通过get_viewport().msaa_2d index as Viewport.MSAA直接赋值。降低输入延迟的关键配置关闭输入累积与 V-SyncInput.use_accumulated_input false在_ready()第一行演示就关闭了输入累积Input.use_accumulated_input false其原理在代码注释中讲得很清楚开启输入累积时Godot 会把一个渲染帧内的所有输入合并成一个事件导致你只能按帧率粒度采样笔的位置关闭后可以查询到操作系统报告的每一个输入事件位置精度不再受帧率限制。代价是 CPU 占用更高因此只有当应用确实需要精确输入坐标时才应关闭例如绘图、批注、手写识别等场景。_on_input_accumulation_toggled回调把该设置暴露到侧边栏开关上用户可实时对比开启/关闭的差异——开启后能明显看到线条变得锯齿化如场景中InputAccumulation控件 tooltip 所述lines can become visibly jagged otherwise。V-Sync 与低处理器占用模式README 指出输入累积与 V-Sync 在该演示中默认关闭以获得even at low FPS即使帧率低也清晰锐利的线条。项目层面 project.godot 设置了window/vsync/vsync_mode0关闭 V-Sync并在[application]中开启run/low_processor_modetrue低处理器占用模式。注意一个配套细节由于启用了低处理器模式演示中Max FPS滑块不再直接设置帧率上限而是改写低处理器模式的休眠间隔。看 _on_max_fps_value_changed() 的实现warning_ignore(narrowing_conversion) OS.low_processor_usage_mode_sleep_usec 1_000_000.0 / value把 FPS 数值滑块范围 10–240默认 145换算成微秒级帧间隔写入OS.low_processor_usage_mode_sleep_usec。而 V-Sync 开关则通过DisplayServer.window_set_vsync_mode(...)在运行时动态切换VSYNC_ENABLED/VSYNC_DISABLED。平台限制务必注意README 特别强调在 Android、iOS 与 Web 平台上V-Sync 由系统层面强制开启无法在应用内关闭。因此移动端与网页端部署时该开关的实际效果有限。倾斜向量的可视化自定义绘制_drawshow_tilt_vector开关控制是否在画布上实时绘制一条红色半透明箭头直观展示数位板报告的倾斜向量。实现位于 _draw()func _draw() - void: if show_tilt_vector: draw_line(event_position, event_position event_tilt * 50, Color(1, 0, 0, 0.5), 2, true)每次InputEventMouseMotion到达时脚本更新event_position与event_tilt并调用queue_redraw()下一帧即以笔尖当前位置为起点、沿倾斜向量方向放大 50 倍绘制一条 2 像素宽的半透明红线。这既是对tilt数据的直观调试工具也展示了Control._draw()自定义绘制的标准用法。场景中ShowTiltVector控件的 tooltip 也再次提醒并非所有数位板都支持倾斜开关默认开启button_pressed true数据缺失时箭头会退化为零向量。操作与快捷键完整的可交互面板侧边栏控件一览场景 graphics_tablet_input.tscn 在左侧PanelContainer中组织了全部设置项控件与信号连接关系如下表控件类型作用连接的回调Undo Last LineButton删除最后一条笔画_on_undo_last_line_pressedClear All LinesButton清空全部笔画_on_clear_all_lines_pressedLine ColorColorPickerButton切换线色_on_line_color_changedLine WidthHSlider0.5–20.0步长 0.5调整线宽_on_line_width_value_changedPressure-SensitiveCheckButton开关压感笔锋_on_pressure_sensitive_toggledShow Tilt VectorCheckButton开关倾斜向量显示_on_show_tilt_vector_toggledMSAA 2DOptionButton0/2×/4×/8×切换 2D 抗锯齿档位_on_msaa_item_selectedMax FPSHSlider10–240默认 145调整低处理器模式帧间隔_on_max_fps_value_changedV-SyncCheckButton运行时开关 V-Sync_on_v_sync_toggledInput AccumulationCheckButton运行时开关输入累积_on_input_accumulation_toggledTabletInfoLabel实时显示压感/倾斜/橡皮擦状态脚本内更新TabletDriverLabel显示当前数位板驱动脚本内更新快捷键映射project.godot 的[input]节定义了六个输入动作部分同时以Shortcut资源挂接到按钮上见 .tscn 中的InputEventActionShortcut组合便于纯键盘操作动作默认按键功能undo_last_lineCtrlZ撤销最后一条笔画clear_all_linesCtrlShiftZ清空全部笔画change_line_colorC打开颜色选择increase_line_width/线宽 0.5decrease_line_width-/_线宽 −0.5toggle_pressure_sensitiveP切换压感笔锋toggle_tilt_vectorT切换倾斜向量显示撤销与清空背后的实现细节_on_undo_last_line_pressed()与_on_clear_all_lines_pressed()都通过find_children(, Line2D)收集场景中所有Line2D节点再删除。代码注释揭示了两个容易踩坑的细节空的残留笔画只要发生鼠标移动事件就会新建一条Line2D即使还没画出可见内容所以撤销一次不一定只删一条线——列表末尾可能存在多条空笔画用户可能需要多次撤销。因此_on_undo_last_line_pressed()会先尝试删除末尾的空线再删除其前一条并据此判断按钮的禁用状态find_children(, Line2D).size() 2时视为已清空。新线即时生成删除后立即调用start_stroke()准备下一条笔画保证撤销后仍可继续绘制。Clear All Lines则循环queue_free()所有Line2D并同样重启一条新笔画。设置变更的即时生效技巧细心的读者会发现_on_line_color_changed、_on_line_width_value_changed、_on_pressure_sensitive_toggled三个回调都调用了start_stroke()。原因注释写得很清楚Required to make the setting change apply immediately.——线色、线宽、压感开关只对之后新建的Line2D生效通过立刻开启一条新笔画让修改从下一次落笔的瞬间就体现出来而不会影响已画完的旧线条。交互数据链路小结从数位板事件到画面把整条数据链路串起来一次带压感的落笔会经历系统报告InputEventMouseMotion携带position、pressure、tilt、pen_inverted_input()判断pressure 0向当前stroke追加点、记录压力值、重建width_curve若开启压感pressure 0则触发start_stroke()开启新线并启用撤销/清空按钮点数达到SPLIT_POINT_COUNT1024时自动分段新建笔画_draw()根据event_position/event_tilt绘制倾斜向量渲染端以 8× MSAA 平滑线条边缘配合关闭输入累积与 V-Sync 的配置获得低延迟、高精度的绘制体验。运行与验证导入演示项目后直接用 Godot 打开 misc/graphics_tablet_input/project.godot 运行即可。在支持数位板的平台上用笔在白色画布上书写可以直观看到压力不同线宽不同、倾斜箭头随笔身转动、倒置笔尖时状态栏 Inverted pen: Yes。侧边栏可实时对比 V-Sync 与输入累积开关对响应性的影响MSAA 档位切换则直接影响线条边缘的平滑度。排障提示Windows 平台驱动问题README 针对 Windows 用户给出了两条明确的排障建议务必照做切换数位板驱动如果遇到问题请在 Project Settings项目设置 → Display → Window → Windows中把数位板驱动从默认的winink改为wintab切换输入模式把数位板的输入模式从相对模式relative改为绝对模式absolute。上述配置属于平台相关设置改动后需重启项目验证。当前驱动可通过侧边栏底部的 Tablet driver 标签查看由DisplayServer.tablet_get_current_driver()报告。把演示迁移到自己的绘图应用要点清单基于该演示搭建自己的绘图/批注应用时可复用的要点如下采集在_input()中监听InputEventMouseMotion同时兼容鼠标与数位板用pressure、tilt、pen_inverted区分能力差异渲染每条笔画一个Line2D节点圆头圆角样式用width_curve动态重建实现压感笔锋注意round_precision随线宽自适应性能关闭输入累积Input.use_accumulated_input false以获得精确坐标关闭 V-Sync 降低延迟用 1024 点分段策略防止单线过长关注低处理器占用模式下 FPS 与low_processor_usage_mode_sleep_usec的换算关系画质在 Project Settings 中启用anti_aliasing/quality/msaa_2d该演示默认 8×为Line2D提供抗锯齿交互为设置项绑定快捷键与Shortcut资源通过删除后立即start_stroke()保持绘图状态连续注意空笔画残留导致需要多次撤销的边界情况兼容性牢记 V-Sync 在 Android/iOS/Web 被系统强制开启倾斜数据并非所有数位板都支持Windows 下可切换 wintab/winink 驱动与绝对/相对输入模式。从数据采集、笔画渲染、性能取舍到平台兼容该演示几乎覆盖了绘图类应用的全部关键环节且全部逻辑集中在 graphics_tablet_input.gd 这一份约 190 行的脚本中非常适合作为二次开发的起点。赞分享示例工程【免费下载链接】godot-demo-projectsDemonstration and Template Projects项目地址https://gitcode.com/GitHub_Trending/go/godot-demo-projects点击查看免费下载相关推荐Windows 通用传感器开发实战基于 Windows-universal-samples 的 Inclinometer 倾斜传感器示例深度解析Windows 通用传感器开发实战基于 Windows universal samples 的 Inclinometer 倾斜传感器示例深度解析 本篇文章以本示例工程如何自定义gernet_m.idstcv_in1k使用timm库进行模型微调的完整教程如何自定义gernet_m.idstcv_in1k使用timm库进行模型微调的完整教程 在深度学习图像分类任务中gernet_m.idstcv_in1k是一Godot 4 物理光照与相机单位实战基于 godot-demo-projects 的 Physical Light and Camera Units 演示Godot 4 物理光照与相机单位实战基于 godot demo projects 的 Physical Light and Camera Units 演示示例工程上一篇Hummingbot项目集成HashKey Global永续合约API技术解析下一篇DeepSpeed Learning Rate Range TestLRRT实战指南用学习率范围测试定位大 Batch 训练的可用学习率上界创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表