GLSL 专题与移植指南
从可运行的案例解释移植、采样、描边、光照与调试。
把 Shadertoy 的 mainImage 放进 Three.js:从全屏画布到模型表面
Shadertoy 的 mainImage 不是 GLSL 的入口函数。移入 Three.js 后,需要补上 main,并从 JavaScript 更新 iTime 和 iResolution。先确认全屏平面运行正常,再为模型更换坐标来源,以便区分入口错误与 UV 错误。
GLSL 和 HLSL 有什么区别?把同一个纹理效果写两遍
比较语法前先确定环境:这里的 GLSL 片段着色器面向 WebGL 2,HLSL 像素着色器面向 Direct3D 11 / Shader Model 5。两者都采样同一张图片,并沿 x 方向逐渐混入暖色。本站只运行 GLSL;HLSL 版本需要 Direct3D 程序负责编译并绑定资源。
SDF 描边为什么缩小后会闪?用 fwidth 保住边缘
距离场使用几何坐标单位,屏幕使用像素。缩放会改变一个距离单位占据的像素数,因此固定的 smoothstep 宽度会呈现不同的边缘厚度。fwidth 估算相邻片段间的数值变化,让过渡区维持约一个像素宽。
图形描边和图片描边有什么区别?距离场、Alpha 和 Sobel 各用在哪
描边对应三种不同输入:SDF 用距离接近零的区域画线;精灵图片先向外扩张 Alpha 遮罩,再减去原遮罩;照片边缘检测则测量亮度变化。用 Sobel 提取叶片轮廓时,内部叶脉也会被检测出来。
Shadertoy 的 iChannel0 从哪里来?把输入图片绑定到 Shader
iChannel0 是运行环境定义的采样器名称,并不会自动关联图片。需要加载纹理、绑定到同名 uniform,并与着色器中的采样器类型匹配。先用带文字和箭头的测试图检查绑定、方向与过滤方式,能更容易看出输入问题。
为什么圆在宽屏上变成椭圆?修正 GLSL 坐标的长宽比
按分辨率分别除两个坐标轴,虽能把它们都映射到 0 到 1,同样的坐标长度却可能占据不同像素数。画圆时可让两轴都除以画布高度,统一像素尺度;采样图片仍使用两轴分别归一化的 UV。
高斯模糊为什么先横着做、再竖着做?
二维高斯核可以拆成水平与垂直两个一维核的乘积。直接做 N×N 卷积,每像素需采样 N² 次;分两遍约需 2N 次,但要额外读写中间纹理。核很小时多一遍未必划算,半径增大后则更有优势。
从一条射线到一个球:Ray Marching 的步长究竟怎么选?
固定步长可能跳过薄物体,也可能在空白区域浪费迭代。球面追踪按到表面的安全距离前进。球的 length(p)-r 是精确距离场;随意缩放或扭曲后的场则未必仍提供不会越过表面的距离下界。
溶解 Shader 怎么保留一圈火边?把一个阈值拆成两个区间
溶解进度和燃烧边缘使用不同遮罩。低于阈值的噪声区域消失,紧挨阈值上方的窄带仍然可见,并被染成火边颜色。如果把整个剩余区域都染色,得到的只是变色,而不是沿消失边界燃烧的效果。
texture2D、texture 和 texelFetch 该用哪个?
ES 1.00 用 texture2D 做带过滤的二维采样;ES 3.00 使用 texture,并按采样器类型选择对应版本。texelFetch 则在指定 mip 层级按整数纹素坐标读取,不做双线性过滤。图片通常需要插值,而细胞状态和精确数据查询往往不能混合相邻数值。
为什么纹理会倒过来?从图片坐标追到 WebGL 采样坐标
图片行的方向、上传时的翻转和着色器 UV 的方向是三个独立环节。用带角落标记和箭头的图排查,先确定 UV 映射,再选择在上传时或采样时翻转。两处都翻转会把图片翻两次。
Shader 里有 mainImage,为什么画布仍是黑的?
沿数据传递顺序缩小黑屏原因:先输出纯红色,确认着色器已链接、顶点覆盖画布且绘制生效,再显示 UV、加入时间,最后接入纹理。每次只增加一个输入,首次出错的步骤就能指出排查方向。
不画三维模型,怎样用法线给距离场打光?
距离场只提供一个数值,光照却需要知道表面朝向。分别采样 x、y、z 两侧的距离,估算梯度,再归一化为方向。RGB 法线图是排查过程中的中间视图;应先确认朝向连续,再调节漫反射或镜面高光。
Shadertoy 的 Buffer A 怎么迁移?用两张纹理保存上一帧
Buffer A 经常读取自身上一帧的结果。WebGL 不允许采样正在写入的纹理,因此需要分开的读取目标和写入目标。每次更新后交换两者,再让显示阶段读取刚完成的纹理。
Bloom 和霓虹光晕有什么区别?用同一个亮点做对照
程序化霓虹在一个片段着色器里计算像素离发光线条的距离。Bloom 则对已有画面做后处理:提取亮区、模糊,再叠加回原图。霓虹计算知道发光几何的位置;Bloom 只读取图像亮度,所以任何足够亮的区域都能贡献光晕。
半调网点和 Bayer 抖动怎么选?用同一张灰阶图看差别
两种方法都用有限的墨色模拟连续明暗,但控制方式不同。半调改变固定格子内圆点的面积;Bayer 抖动把每个位置的亮度与阈值矩阵比较。放大后,前者是大小变化的圆点,后者是规则像素图案,其疏密随亮度变化。