ARTICLE DETAIL

资讯详情

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

TiXL Image2dSDF 算子深度解析:将纹理灰度图转化为 SDF 距离场

TiXL Image2dSDF 算子深度解析:将纹理灰度图转化为 SDF 距离场 TiXL Image2dSDF 算子深度解析将纹理灰度图转化为 SDF 距离场【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3Image2dSDF是 TiXL实时动态图形创作软件Lib.field.generate.sdf算子库中一个极具实用价值的节点它把一张二维纹理的灰度信息直接当作带符号的距离数据从而让任意贴图、文字或 Logo 快速进入 SDF 体场field的世界。本文以该算子的官方文档.help/docs/operators/lib/field/generate/sdf/Image2dSDF.md为主线结合仓库中的算子源码、节点定义文件与官方示例完整讲解它的输入输出、底层着色器实现、内部节点结构以及实战接入方式。读完本文你将掌握如何在 TiXL 中把一张普通图片加工成可被光线步进Ray Marching渲染、可与其它 SDF 组合、可被偏移与缩放的二维距离场。算子定位SDF 生成器家族的一员Image2dSDF 归属于Lib.field.generate.sdf这一算子分组该分组在仓库中的完整目录为 Operators/Lib/Symbols/field/generate/sdf/分组说明见 .help/docs/operators/lib/field/generate/sdf/README.md。同组的算子既有程序化几何体生成器SphereSDF、BoxSDF、TorusSDF、CapsuleLineSDF、FractalSDF 等也有以纹理为数据源的生成器——除了本文主角还有 HeightMapSdf用纹理生成带位移高度的 SDF。Image2dSDF 的独特之处在于它不做几何体模拟而是把纹理的灰度值本身解读为距离。在典型工作流中Image2dSDF 生成的ShaderGraphNode会被送入RaymarchField进行光线步进渲染或被VisualizeFieldDistance直接可视化也可以像普通几何 SDF 一样通过CombineSDF参与布尔并、差、交运算。工作原理灰度即距离文档对 Image2dSDF 的描述只有一句话却点明了全部技术本质Uses the grayscale information of a texture as (signed) distance data. This works nicely with JumpFloodFill即纹理的灰度信息被当作带符号的距离数据使用。纹理越亮的区域采样出的距离值越小更接近表面从而实现图像内容越白越实、越黑越空的体场映射。文档特别推荐与JumpFloodFill搭配先用 JumpFloodFill 把一张二值化的轮廓/文字图膨胀成平滑的灰度距离图再喂给 Image2dSDF就能把简单的 alpha 轮廓变成具有平滑内外过渡的 SDF——这也是官方示例所采用的标准链路见下文实战章节。输入参数详解官方文档给出了 4 个输入参数以下表格在保留文档原始信息的基础上补充了从节点定义文件 Operators/Lib/Symbols/field/generate/sdf/Image2dSDF.t3 中确认的默认值参数名类型与相关性默认值来自 .t3 定义说明SdfImageTexture2DRequired必填null作为距离数据的源纹理读取其灰度信息必填未连接时算子不产生有效输出SdfScaleSingle0.5距离值的缩放系数控制灰度→距离的映射强度决定距离场厚度与衰减速度ImageSizeVector2(1.0, 1.0)图像在 XY 平面上的投影尺寸决定 SDF 在空间中的覆盖范围与宽高比OffsetSingle0.0对整个距离场施加的数值偏移可整体增厚正值或减薄负值表面这些默认值也可以直接从节点定义文件里逐项核对例如ImageSize的DefaultValue: { X: 1.0, Y: 1.0 }、SdfScale的DefaultValue: 0.5、Offset的DefaultValue: 0.0。在底层 C# 定义Operators/Lib/Symbols/field/generate/sdf/Image2dSDF.cs中四个输入槽分别以InputSlot形式声明并带有用于节点图序列化的 GUIDSdfImageInputSlotTexture2DGUIDc817ea37-...SdfScaleInputSlotfloatGUIDd7ed4ea1-...ImageSizeInputSlotVector2GUID1bcd6582-...OffsetInputSlotfloatGUID59297115-...输出ShaderGraphNode输出名类型ResultT3.Core.DataTypes.ShaderGraphNode输出是一个ShaderGraphNode着色器图节点而非直接渲染好的图像。这意味着 Image2dSDF 是场生成器而非渲染器它把一段可复用的 SDF 计算代码注入到最终组合的着色器图中供 RaymarchField 等消费方调用。源码中输出槽声明为SlotShaderGraphNodeGUID4a3cb304-...与整个 SDF 算子库的输出类型约定保持一致HeightMapSdf 等节点同样输出T3.Core.DataTypes.ShaderGraphNode。源码级剖析着色器代码是如何生成的Image2dSDF 的 C# 外壳本身只包含着色器设置的准备工作真正生成 SDF 逻辑的是其内部子节点ExecuteImage2dSdf源码见 Operators/Lib/Symbols/field/generate/sdf/_/ExecuteImage2dSdf.cs。它实现了IGraphNodeOp接口通过AddDefinitions与TryBuildCustomCode两个方法把一段 HLSL 注入着色器图1. 注入的 SDF 函数定义AddDefinitions向全局注入一个以节点实例命名的函数sdf2DColumn{ShaderNode}其核心逻辑如下float sdf2DColumn(float2 pos, float2 imageSize, float sdfScale) { float2 uv pos / imageSize; // 图像投影到 XY 平面 uv.y * -1; // 翻转 Y对齐纹理坐标系 uv 0.5; // 将 [-0.5, 0.5] 范围移到 [0, 1] float2 clampedUV clamp(uv, 0.0, 1.0); float2 delta uv - clampedUV; // 灰度越亮 → saturate 值越高 → texDist 越小越接近表面 float texDist 1 - saturate(SdfImage.SampleLevel(ClampedSampler, clampedUV, 0.0)); texDist * sdfScale; float2 worldDelta delta * imageSize; float outsideDist length(worldDelta); // 采样点位于图像范围内直接返回纹理距离 if (all(uv 0.0) all(uv 1.0)) return texDist; // 采样点在图像范围外近似计算到最近边缘/角落的距离 return sqrt(outsideDist * outsideDist texDist * texDist); }这段代码清晰地体现了文档灰度即距离的含义UV 换算把世界坐标pos除以imageSize得到投影 UV翻转 Y 并平移 0.5使图像中心对齐坐标原点范围钳制clamp(uv, 0.0, 1.0)保证采样始终合法灰度取反1 - saturate(...)让亮部白色对应近距离、暗部黑色对应远距离内/外区分图像范围内直接返回纹理距离范围外则用sqrt(outsideDist² texDist²)近似到最近边缘或角落的欧氏距离保证场在边界处连续。2. 采样纹理的注入AppendShaderResources负责把源纹理的ShaderResourceView以Texture2Dfloat {ShaderNode}SdfImage的形式注册到着色器图资源列表中带防重复添加检查。3. 距离写入主函数TryBuildCustomCode在着色器主函数中追加最终调用f.w (sdf2DColumn(p.xy, Size, Scale) Offset); f.xyz p.w 0.5 ? p.xyz : 1; // 范围内保存局部坐标即将 SDF 计算结果加上Offset后写入f.w同时在采样点位于表面内部p.w 0.5时保留局部坐标供后续材质、位移或推拉PushPull处理使用。内部节点结构两个子节点协作从 Image2dSDF.t3 可以看出Image2dSDF 并非单一计算节点而是由两个子节点组合而成的复合算子ExecuteImage2dSdfSymbolId8fd60f01-...实际执行 SDF 计算内部默认Scale 0.001、Size (1, 1)其Result直接连到算子的对外输出SrvFromTexture2dSymbolIdc2078514-...负责把外部的SdfImage纹理转换为着色器可采样的 SRV再喂给 ExecuteImage2dSdf 的SdfImageSrv输入。连线关系来自 .t3 的Connections段依次为外部SdfImage→SrvFromTexture2d→ ExecuteImage2dSdf 的 SRV 输入外部SdfScale→ ExecuteImage2dSdf 的Scale外部ImageSize→Size外部Offset→Offset。这种外壳算子 内部执行节点的封装模式也是整个Lib.field.generate.sdf库的常见结构源码注释明确指出该算子只包含为每个点准备 transform 矩阵 structuredBuffer这类着色器设置真正的IShaderGraph实现在内部节点中。实战示例文本 → JumpFloodFill → SDF → 光线步进仓库提供了官方示例Image2dSDFExample节点定义见 Operators/examples/Symbols/lib/field/generate/Image2dSDFExample.t3C# 骨架见 Image2dSDFExample.cs它演示了文档推荐的最佳实践链路生成轮廓图Text节点渲染出文字 ABC字体Examples:fonts/Roboto-Light.fnt字号 150输出到一个 1024×1024 的RenderTargetSDF 化JumpFloodFillMaxIterationCount 86把文字轮廓二值图膨胀为平滑灰度距离图——这正是文档所说与 JumpFloodFill 搭配效果良好转场Image2dSDF接收 JumpFloodFill 的输出作为SdfImage本例中设置为ImageSize (2, 2)、SdfScale 0.5组合结果通过CombineSDFCombineMethod 6K 0.07与FractalSDF、SphereSDF等程序化场做布尔融合渲染与后处理RaymarchFieldStepSize 0.918光线步进VisualizeFieldDistance可视化距离配合OrbitCameraDistanceToTarget 2.25、SetSDFMaterial、Bloom、PushPullSDFAmount -0.02以及TransformField由PerlinNoise3驱动扰动完成最终画面。这个示例完整覆盖了图片 → 距离场 → 3D 渲染的全部环节是理解 Image2dSDF 在实际项目中最直接的参考——你可以在 TiXL 编辑器左侧库面板Lib/field/generate/sdf分组中找到 Image2dSDF在examples分组中找到 Image2dSDFExample 并直接运行观察效果。使用建议与调试提示必填项先接好SdfImage是 Required 输入务必先连接纹理若输入来自 JumpFloodFill、RenderTarget 等注意其输出需为可采样的纹理资源官方示例通过SrvFromTexture2d自动完成 SRV 转换。SdfScale 决定质感默认0.5适合多数情况数值越大距离场越陡峭表面更锐利结合Offset可整体增厚/减薄表面二者常配合PushPullSDF做动画。ImageSize 控制空间比例默认(1, 1)为方形覆盖若源图是宽幅 Logo可调整 X/Y 比例以匹配目标空间避免场被拉伸变形。调试可视化将Result直接连到VisualizeFieldDistance即可直观看到距离场渐变比直接走 RaymarchField 更容易排查场为空/场过大等问题。组合与变换Image2dSDF 输出的ShaderGraphNode与同库程序化 SDFSphere、Box、Fractal 等类型一致可自由进出CombineSDF、TransformField实现图片文字融进几何场景的复杂效果。延伸阅读同分组纹理类 SDF 生成器HeightMapSdf用纹理生成带高度的 SDF可与本文对比理解灰度即距离与灰度即高度两种思路算子库分组总览.help/docs/operators/lib/field/generate/sdf/README.md算子源码入口Image2dSDF.cs、内部实现 ExecuteImage2dSdf.cs节点定义含全部默认值与连线Image2dSDF.t3官方示例Image2dSDFExample.t3【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表