尧图精选

TiXL AsciiRender 算子实战:用 HLSL 与字体纹理实现《黑客帝国》风格 ASCII 字符画

🕒 发布时间:2026/9/20 4:57:42 📁 来源:尧图网络
音视频图形学桌面应用【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址https://gitcode.com/GitHub_Trending/t3/t3点击查看免费下载导读AsciiRender 是 TiXL 开源实时动态图形软件t3.sln中位于Lib.image.fx.stylize命名空间下的一个图像特效算子其核心作用是把输入图像按亮度映射成一组灰度深浅不同的 ASCII 字符呈现出黑客帝国The Matrix式的字符雨/字符画视觉风格。读完本文你将掌握该算子的全部 13 个输入参数与默认值、其底层 HLSL 着色器的逐行原理网格划分 → 亮度映射 → 字形索引 → 上屏混合以及如何用 BuildAsciiFontSorting 的字符过滤机制、AnimVec2无限垂直滚动和官方示例工程在实时渲染管线中搭出可动画、可调色的完整字符画效果。算子定位与核心概念该算子隶属于Lib.image.fx.stylize图像 → FX → 风格化分类其文档定位为Draws the incoming image as shaded ASCII characters, similar to The Matrix.即将输入图像绘制为带明暗shaded的 ASCII 字符。与之同类的风格化算子还包括 MosiacTiling递归平铺、VoronoiCells沃罗诺伊单元、DitherFloyd–Steinberg 抖动、HoneyCombTiles六边形、SubdivisionStretch细分拉伸等可互相组合出丰富的风格化效果参见 stylize 目录 README。在 TiXL 的节点图中该算子对应符号AsciiRender其实现由三部分构成C# 算子定义AsciiRender.cs 声明了输入输出槽Slot符号图Symbol GraphAsciiRender.t3 编排了从加载字体、构建字符映射纹理、绑定着色器到绘制全屏三角形的完整子图像素着色器AsciiRender.hlsl 负责逐像素完成字符画的核心计算。系统内部如何画出字符从 AsciiRender.t3 的连接关系可以看出该算子的渲染流水线是LoadImageL242读取Lib:images/font-6x6px.png即仓库中的 font-6x6px.png96×96 的 16×16 字体表BuildAsciiFontSortingL379按亮度对字符排序并生成一张 1×N 的 R32_Float 映射纹理PixelShaderL254以psMain为入口编译 AsciiRender.hlslVertexShader使用 Default2-vs.hlsl 的vsMainDraw以 6 顶点两个三角形绘制全屏输出到RenderTargetWithDepthBufferfalse、Clearfalse启用SourceAlpha混合最终从输出槽OutputT3.Core.DataTypes.Texture2D交给下游。输入参数详解含默认值与取值建议下表完整列出了该算子的全部输入参数默认值取自 AsciiRender.t3参数名类型默认值说明ImageATexture2D必需—null被字符化的输入图像。必须连接纹理否则无内容可采样FillVector4(1,1,1,1)字符前景填充色RGBABackgroundVector4(0.000001, 0.000001, 0.000001, 1)背景色。当其 Alpha 小于 1 时会走背景透明混合分支见下文 shader 解析MixInColorsSingle0字符内混入多少原始图像颜色0时字符为纯 Fill 色1时完全使用 ImageA 像素色shader 中为MaxInColorsScaleFactorSingle3字符缩放因子。影响每个字符单元的分辨率占比值越大字符越胖/少值越小字符越细密OffsetVector2(0,0)字符网格整体平移单位网格单元可在 X 方向或 Y 方向滚动FontCharSizeInt2(6,6)单个字符在字体表中的像素尺寸像素默认对应 6×6 像素字模GainAndBiasVector2(0.5, 0.5)亮度重映射的 Gain/Bias 参数用于控制灰阶到字符分布的对比度曲线RandomizeSingle0每个字符单元加入的随机偏移强度shader 中为Scatter0–1 之间越大噪点越明显FontFilePathStringLib:images/font-6x6px.png字体表图片路径16×16 个字符的图集支持Lib:资源前缀FilterCharactersString只保留列表中的字符参与字符画渲染空串表示使用全部字符GenerateMipsBooleanfalse是否为输出渲染目标生成 Mip 链下游做模糊/缩放时更平滑ResolutionInt2(0,0)输出渲染目标分辨率(0,0)表示跟随输入图像尺寸各参数在 C# 槽定义中的 Guid 对应关系可对照 AsciiRender.cs 逐一核实。官方示例中的推荐参数组合仓库自带的示例工程 AsciiRenderExample.t3 给出了一套经过调校的组合对应 C# 壳 AsciiRenderExample.csRandomize 0.47中等的字符随机散布避免字符过于整齐FilterCharacters ,03.;?\- $OoT3只保留标点与部分字母字符密度更黑客帝国Resolution (2048, 2048)2K 方形渲染目标保证字符边缘锐利上游用PerlinNoise驱动Blur的 Size、DepthOfField的 Amount并用LoadImage加载Examples:images/t3-logo-alpha.png作为输入图。着色器原理逐行解析核心计算全部位于 AsciiRender.hlsl 的psMain中分为五个阶段1. 网格划分与单元定位float aspectRatio TargetWidth / TargetHeight; float2 p psInput.texCoord; p - 0.5; float2 fontCharWidth FontCharSize; float2 divisions float2(TargetWidth / fontCharWidth.x, TargetHeight / fontCharWidth.y) / ScaleFactor; float2 fixOffset Offset * float2(-1, 1) / divisions; p fixOffset; float2 p1 p; float2 gridSize float2(1 / divisions.x, 1 / divisions.y); float2 pInCell mod(p1, gridSize); float2 cellIds (p1 - pInCell 0.5); float2 cellTiles cellIds - fixOffset; pInCell * divisions;divisions用目标分辨率除以FontCharSize再除以ScaleFactor得到屏幕被切成的字符单元数量ScaleFactor越大单元越少越粗。坐标先归一化到[-0.5, 0.5]Offset经float2(-1, 1)翻转 Y 后除以 divisions 得到单元单位的偏移。cellIds是当前像素所在的字符网格 IDpInCell是该像素在单元内的局部坐标已乘以 divisions单位是字模像素。2. 亮度采样与 Gain/Bias 重映射float4 colFromImageA ImageA.Sample(texSampler, cellTiles); float grayScale (colFromImageA.r colFromImageA.g colFromImageA.b) / 3; float dBiased ApplyGainAndBias(grayScale, GainAndBias);每个单元以cellTiles单元中心采样一次ImageA取 RGB 均值得到亮度再经ApplyGainAndBias重映射。该函数定义在 bias-functions.hlsl组合了GetBiasx / ((1/bias - 2)(1-x) 1)与 Schlick 风格的GetSchlickBias通过 Gain对比度与 Bias整体明暗偏移控制亮度分布曲线GainAndBias默认(0.5, 0.5)即近似恒等映射。3. 随机散射与防溢出钳制float randomOffset hash11u((uint)(cellIds.x * TargetWidth 0.5) (uint)(cellIds.y * TargetHeight 0.5) * 73939133); dBiased randomOffset * Scatter; dBiased clamp(dBiased, 0.0001, 0.999); // Prevent spilling from white to blackhash11u定义于 hash-functions.hlsl以单元 ID 做种子生成确定性伪随机数乘以RandomizeScatter后叠加到亮度上让字符选择带有颗粒感。钳制到[0.0001, 0.999]是为了避免亮度越界导致字符从白直接溢出到黑代码注释原文Prevent spilling from white to black。4. 字符索引与字模取样float4 letter FontSortingOrder.SampleLevel(texSamplerPoint, float2(dBiased, 0.4), 0); float letterIndex letter * 256; float rowIndex floor(letterIndex / 16); float columnIndex floor(letterIndex % 16); float2 letterPos float2(columnIndex, rowIndex) / 16; float2 uv pInCell / 16 letterPos; float4 colorFromFont ImageB.SampleLevel(texSamplerPoint, uv, 0);FontSortingOrder是BuildAsciiFontSorting生成的 1×N 的 R32_Float 亮度排序纹理按亮度 dBiased 查表得到 0–255 的字符索引256 16×16 字模表。索引换算成字模表里的行列pInCell / 16 letterPos拼出该字符在字体图集ImageB上的采样坐标用点采样读取字模像素colorFromFont.r0背景笔画透明1笔画实心。5. 前景/背景/原色混合if (Background.a 1) { float4 orgColor ImageA.Sample(texSampler, psInput.texCoord); return lerp(lerp(orgColor, Background, Background.a), Fill, colorFromFont.r); } return lerp(Background, lerp(1, colFromImageA, MaxInColors) * Fill, colorFromFont.r);当Background的 Alpha 1 时先按背景色与原始像素混合再按字模笔画覆盖 Fill 色实现背景半透明透出原图的效果否则字符色 lerp(1, colFromImageA, MaxInColors) * Fill即MixInColors控制字符内部是纯 Fill 色还是混入原图颜色最后在背景与字符色之间用colorFromFont.r插值。字体排序机制BuildAsciiFontSorting字符的亮度 → 字形映射并非手工指定而是由算子图内置的 BuildAsciiFontSorting 自动计算其流程SortAsciiLetters加载字体表位图默认font-6x6px.png96×96 16 行 × 16 列按Rows16、Columns16划分 256 个字符单元遍历每个像素按位置归入对应字符单元累加RGB得到该字符的笔画亮度若FilterCharacters非空只统计保留字符其余字符亮度被置为999999999且索引归 0从而在排序后被挤到最暗端而不会被选用同时对每个字符加入new Random(23)固定种子的 0–0.6 随机扰动让同亮度字符的先后顺序可控按亮度升序排序得到最暗字符 → 最亮字符的亮度表在 Update 中写入 1×N、Format.R32_Float的映射纹理MappingTexture其中filterOutFactor (256 - filterCharCount) / 256用于把过滤掉的字符从索引空间中拉伸移除。算子图默认传给它的过滤字符为%$_()^0123456789./-.:\\见 AsciiRender.t3而FilterCharacters输入参数允许你随时覆盖这一集合——例如示例工程用的,03.;?\- $OoT3。这也解释了为什么修改FontFilePath换成任意 16×16 字符图集或FilterCharacters后字符画的字体气质会发生根本变化。动画技巧结合 AnimVec2 实现无限垂直滚动文档给出了一个高价值的实战提示Tip: You can connect [AnimVec2] with the Endless vertical to the offset.即把AnimVec2动画向量算子的Endless vertical预设输出接到Offset输入即可让字符网格沿垂直方向无限滚动模拟《黑客帝国》的字符雨下落效果AnimVec2生成随时间线性递增的二维向量Offset在 shader 中按fixOffset Offset * float2(-1, 1) / divisions换算为单元级位移Y 方向滚动即为字符雨由于mod取模运算保证了网格的周期性滚动可以无限持续而不会走到底。进一步的增强思路基于 shader 结构可以安全推导在Offset上叠加 X 向小幅漂移可以做出雨幕摇摆把Randomize调高可增强字符随机闪烁将GainAndBias随时间动画则能周期性地呼吸明暗。示例工程 AsciiRenderExample.t3 中还用AnimValueRate0.125驱动偏移、用PerlinNoise驱动景深与模糊演示了如何把字符画融入完整的 3D 场景渲染。可复现的调试路径与仓库资源导航查看算子源码AsciiRender.cs输入/输出槽定义与 AsciiRender.hlsl核心像素着色器查看符号图结构AsciiRender.t3子图编排与所有连接、界面布局见 AsciiRender.t3ui查看字体构建器BuildAsciiFontSorting.cs运行官方示例AsciiRenderExample.t3含 2K 分辨率、噪声驱动景深、材质球渲染的完整场景社区作品参考MarsAsciiMirrorScene.t3 展示了字符画在镜面类创意场景中的实际应用字体资源font-6x6px.png默认 6×6 像素字模96×96 图集着色器辅助函数bias-functions.hlslGain/Bias、hash-functions.hlslhash11u 随机数。常见问题与排查建议现象可能原因与处理输出全黑或全白ImageA未连接必需输入或亮度被clamp(0.0001, 0.999)之外的极端GainAndBias压死把GainAndBias复位到(0.5, 0.5)字符太脏/噪点重Randomize过大降到 0.2 以下或FilterCharacters中全是标点改为含字母数字的集合字符过密/过疏调整ScaleFactor默认 3与FontCharSize默认 6×6的比例关系想透出原图背景把Background的 Alpha 设为 1走 shader 的半透明混合分支字符色彩不对检查Fill颜色与MixInColors0 为纯色、1 为原图色以上排查建议均由 AsciiRender.hlsl 的实际代码分支推导得出可在 TiXL 中直接验证。结语AsciiRender 是一个小而完整的 TiXL 风格化算子参数少但覆盖了采样、查表、随机、混合的全部环节配合BuildAsciiFontSorting的自动字体排序与FilterCharacters字符筛选可以在不改动一行 shader 的情况下自由更换字体气质再通过AnimVec2的 Endless vertical 驱动Offset就能获得经典的《黑客帝国》字符雨效果。读者可以沿着 AsciiRender.t3 的连线逐节点追踪从字体加载到最终上屏的完整链路并把本文的参数表作为调参速查手册。赞分享音视频图形学桌面应用【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址https://gitcode.com/GitHub_Trending/t3/t3点击查看免费下载相关推荐tsParticles Matrix Shape 实战指南用 tsparticles/shape-matrix 打造黑客帝国风格字符粒子tsParticles Matrix Shape 实战指南用 tsparticles/shape matrix 打造黑客帝国风格字符粒子 本篇指南围绕 ts前端TiXL NumberPattern 算子详解用输入纹理驱动数字列覆盖层HLSL 实现与参数指南TiXL NumberPattern 算子详解用输入纹理驱动数字列覆盖层HLSL 实现与参数指南 NumberPattern 是 TiXL 的 Lib.i音视频图形学桌面应用Hexo主题安知鱼10个让博客脱颖而出的高级功能Hexo主题安知鱼10个让博客脱颖而出的高级功能 安知鱼主题是一款简洁美丽的Hexo主题专为追求个性化博客体验的用户设计。它不仅拥有优雅的视觉设计还内置了创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →