 向量不等比较函数详解:逐分量语义、语法要点与片段着色器实战(The Book of Shaders 术语精讲))
【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载notEqual()是 GLSL 内置的向量关系函数Vector Relational Functions之一用于对两个同类型向量执行逐分量component-wise的不相等比较并返回一个由布尔值组成的向量。本文以 The Book of Shaders 仓库 glossary/notEqual/README-ua.md 为骨架完整讲解其函数签名、参数语义、与equal()等姊妹函数的异同并结合仓库中的着色器代码展示它在像素级编程中的典型用法。读完本文你将能熟练使用notEqual()及其配套关系函数处理向量比较逻辑并理解bvec布尔向量在 GLSL 分支与混色中的实际价值。一、函数签名与声明notEqual()属于 GLSL 内置的向量关系函数族重载覆盖了最常用的浮点向量与整型向量类型。它在 GLSL ES 1.00 / GLSL 1.20 及更高版本中均可使用其完整声明如下取自 glossary/notEqual/README-ua.mdbvec2 notEqual(vec2 x, vec2 y) bvec3 notEqual(vec3 x, vec3 y) bvec4 notEqual(vec4 x, vec4 y) bvec2 notEqual(ivec2 x, ivec2 y) bvec3 notEqual(ivec3 x, ivec3 y) bvec4 notEqual(ivec4 x, ivec4 y)注意以下几个关键点参数类型必须一致x与y必须是完全相同的向量类型同为vec2/vec3/vec4或同为ivec2/ivec3/ivec4不允许混合传入不同维度或不同基础类型的向量。返回类型是bvec返回值不是bool而是bvec2/bvec3/bvec4这样的布尔向量其中每个分量是booltrue或false。对标量同样有效虽然官方重载只列出向量版本但 GLSL 内置运算符!天然支持标量与向量逐分量比较如vec2 ! vec2、float ! floatnotEqual()是对逐分量比较这一语义的显式函数化封装在逻辑等价于逐分量x[i] ! y[i]。二、参数说明参数类型含义xvec2/vec3/vec4或ivec2/ivec3/ivec4参与比较运算的第一个向量yvec2/vec3/vec4或ivec2/ivec3/ivec4参与比较运算的第二个向量两个参数扮演完全对等的比较角色对第i个分量而言notEqual(x, y)的结果仅取决于x[i]与y[i]是否不同与哪个向量在前无关即比较是对称的notEqual(x, y)与notEqual(y, x)结果一致。三、核心语义逐分量不相等比较notEqual()的语义非常直观返回一个布尔向量其中每个元素i按x[i] ! y[i]计算。例如vec3 a vec3(1.0, 2.0, 3.0); vec3 b vec3(1.0, 0.0, 3.0); bvec3 r notEqual(a, b); // r bvec3(false, true, false)等价地它的行为可以用逐分量展开来理解bvec3 r; r.x (a.x ! b.x); // false r.y (a.y ! b.y); // true r.z (a.z ! b.z); // false正是因为返回的是布尔向量而非单个布尔值notEqual()在 GLSL 中常与any()、all()、not()等布尔向量归约函数配合使用见后文姊妹函数一节以把逐分量比较结果折叠成单一的bool用于控制流。四、与姊妹关系函数的对比notEqual()是 GLSL 向量关系函数族的一员仓库 glossary/README.md 的 VECTOR RELATIONAL FUNCTIONS 分类中将其与以下函数并列列出equal()逐分量判断相等返回bvec其中每个元素按x[i] y[i]计算——是notEqual()的严格逻辑取反lessThan()逐分量判断x[i] y[i]lessThanEqual()逐分量判断x[i] y[i]greaterThan()逐分量判断x[i] y[i]greaterThanEqual()逐分量判断x[i] y[i]any()只要布尔向量中任意一个元素为true即返回trueall()仅当布尔向量中所有元素均为true时才返回truenot()对布尔向量逐分量取反返回bvec。由此可以派生出常见的组合用法// 只要 x 与 y 在任一分量上不同整体即视为不相等 bool differs any(notEqual(x, y)); // 所有分量都不同才算完全不相等 bool totallyDiffers all(notEqual(x, y)); // 等价写法equal() 结果逐分量取反 bvec3 sameAs not(equal(x, y));需要特别强调的是notEqual()返回的是bvec不能直接把它的结果当作bool用于if条件在严格模式下编译会报类型错误必须先用any()/all()归约或逐分量取出如r.x再使用。五、仓库中的实践印证从颜色章节到八卦着色器The Book of Shaders 在多个章节中都提到了这组向量关系函数。在 06/README-ua.md颜色章节的注释中作者明确指出除几何函数外GLSL 还提供lessThan()、lessThanEqual()、greaterThan()、greaterThanEqual()、equal()与notEqual()这些特殊的向量比较函数用于处理向量间的比较逻辑——这提示读者在处理颜色、坐标等vec数据时逐分量比较是比手写if分支更地道、更高效的做法。仓库中的实际着色器代码也大量依赖此类比较/分支逻辑。例如 11/iching-03.frag《易经》八卦示例中// 根据整数 N 的二进制位构造 6 个布尔值分别控制六条爻的形态 bool b[6]; float remain floor(mod(N,64.)); for(int i 0; i 6; i){ b[i] mod(remain,2.)1.?true:false; remain ceil(remain/2.); } return hex(st,b[0],b[1],b[2],b[3],b[4],b[5]);这里用 1.判断每个二进制位是否为 1并据此填充布尔数组——正是逐分量比较 → 布尔结果 → 驱动分支/形状选择这一模式的典型落地。类似的ipos.x 1.0这类浮点坐标比较也出现在 09/iching-01.frag 与 10/iching-02.frag 中。在需要多条件同时成立例如用坐标分量组合判断像素是否落在某个矩形内时就可以用notEqual()结合any()/all()写出等价于多个if的向量化判断。六、实战示例用 notEqual() 编写一个差异检测着色器下面是一个可以直接在 The Book of Shaders 配套的着色器运行环境中试跑的片段着色器它演示了notEqual()的核心用法——检测两个输入向量是否不同并用比较结果驱动颜色输出#ifdef GL_ES precision mediump float; #endif uniform vec2 u_resolution; uniform float u_time; void main(){ vec2 st gl_FragCoord.xy / u_resolution.xy; // 构造两个随时间漂移的向量 vec2 a vec2(st.x, st.y); vec2 b vec2(st.x 0.02 * sin(u_time), st.y - 0.02 * cos(u_time)); // 逐分量比较结果是一个 bvec2 bvec2 diff notEqual(a, b); // 归约为单一布尔值任一分量不同即为 true bool anyDiff any(diff); bool allDiff all(diff); // 用比较结果驱动颜色 vec3 color vec3(0.0); if (anyDiff) { color vec3(0.2, 0.4, 1.0); // 存在差异的区域 } if (allDiff) { color vec3(0.8, 0.0, 0.2); // 两个分量都不同的区域 } gl_FragColor vec4(color, 1.0); }运行该示例可以得到直观结论notEqual()返回的布尔向量精确记录了差异发生在哪个分量上而any()则回答是否发生差异这一整体问题。这种逐分量比较 布尔归约的组合在抗锯齿边缘检测、图像差异蒙版、碰撞判定等需要逐通道R/G/B 或 x/y/z独立判断的场景中非常实用。七、使用注意事项浮点比较的精度问题GLSL 中的浮点运算是近似运算两个在数学上相等的表达式如a * b与c其浮点结果可能并不严格相等导致notEqual()意外返回true。当需要近似相等判断时应改用abs(a - b) epsilon这类容差比较而不是直接依赖notEqual()/equal()。类型严格匹配notEqual()的重载要求参数类型与维度完全一致混合vec2与vec3、或vec与ivec都会导致编译错误。GLSL 也不会自动做标量到向量的隐式扩展。返回值不能直接进入ifbvec类型必须先用any()/all()归约或通过.x/.y/.z取出单个分量才能用于标量布尔上下文。与!运算符的关系notEqual(x, y)与逐分量地书写x[i] ! y[i]语义完全等价官方文档明确其每个元素i按x[i] ! y[i]计算因此它本质上是显式函数化的向量不等比较便于与其他向量关系函数统一使用。八、相关资源索引本词条原始文档glossary/notEqual/README-ua.md英文原版见 glossary/notEqual/README.md术语总索引按主题/字母排序glossary/README.md姊妹词条equal()、lessThan()、lessThanEqual()、greaterThan()、greaterThanEqual()、any()、all()、not()正文提及这组函数的章节06/README-ua.md颜色章节使用向量比较/分支逻辑的着色器实例11/iching-03.frag、09/iching-01.frag、10/iching-02.frag赞分享【免费下载链接】thebookofshadersStep-by-step guide through the abstract and complex universe of Fragment Shaders.项目地址https://gitcode.com/gh_mirrors/th/thebookofshaders点击查看免费下载相关推荐GLSL notEqual() 函数详解The Book of Shaders 中的逐分量不等比较GLSL notEqual 函数详解The Book of Shaders 中的逐分量不等比较 notEqual 是 GLSLOpenGL ES ShadiThe Book of Shaders 之 GLSL lessThanEqual()向量逐分量“小于等于”比较的声明、语义与着色器实战The Book of Shaders 之 GLSL lessThanEqual 向量逐分量“小于等于”比较的声明、语义与着色器实战 lessThanEquaAnime4K GLSL 着色器 Linux 安装与 mpv 实时放大实战指南v4.xAnime4K GLSL 着色器 Linux 安装与 mpv 实时放大实战指南v4.x Anime4K 是一套开源的实时高质量动漫视频放大算法集合通过 m上一篇炸鲜奶制作全流程实战配方工艺详解与 RAG 结构化菜谱数据解析下一篇Julep dotctx SkillsSKILL.md 侧车文件与 __load_skill__ 渐进式披露实现指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考