条件数学和 GLSL
Conditional math and GLSL
我目前正在使用 pixijs 学习 GLSL,我在一个超级简单的脚本中看到这个简单条件的奇怪行为。基本上,代码会询问 x 坐标的绝对值是否 <= 1、大于 1 或其他……并且“其他”分支会触发!
澄清一下,一个数字将小于或等于1,或大于1,应该没有其他可能性(除非我有脑放屁:-))
更多上下文:分辨率是统一的,值为 [10.0,10.0]。
谁能解释一下这怎么可能?我唯一能想到的是 x 坐标不是浮点数。这可能吗?
precision mediump float;
uniform vec2 resolution;
void main()
{
vec2 uv = ( gl_FragCoord.xy / resolution.xy ) * 2.0 - 1.225;
uv.y *= resolution.y/resolution.x;
if (abs(uv.x) <= 1.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
} else if (abs(uv.x) > 1.0) {
gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);
} else {
/// this fires - WTF?
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
}
更新:这看起来像是一个 pixijs 问题,因为当我在 GLSL 代码中手动指定 resolution
时它起作用了。这是设置着色器的代码:
const uniforms = {
time: 0,
resolution: new Point(10.0, 10.0),
}
const filter = new Filter(undefined, fragment, {
...uniforms
});
comp.filters = [filter];
app.ticker.add((delta) => {
filter.uniforms.resolution = new Point(10.0, 10.0);
});
看起来pixi.js不喜欢resolution
作为制服名称。当我将名称更改为 u_resolution
时,它开始工作了。 :耸肩:
大多数 GLSL 实现使用 IEEE 浮点的一些变体进行计算,并且具有 NaN (not-a-number) 值的概念。 NaN 值是持久的——每当您执行涉及一个的操作时,结果都是 NaN,而当您将 NaN 与另一个浮点值进行比较时,结果始终为 false。所以你可以轻松拥有:
if (abs(uv.x) <= 1.0) {
// less than or equal to 1
} else if (abs(uv.x) > 1.0) {
// greater than 1
} else {
// uv.x must be NaN!
有多种方法可以获得 NaN,但最简单的方法是计算 0/0。所以在你的情况下,如果你同时拥有 gl_FragCooord.x == 0 和 resolution.x == 0,你会得到 NaN
我目前正在使用 pixijs 学习 GLSL,我在一个超级简单的脚本中看到这个简单条件的奇怪行为。基本上,代码会询问 x 坐标的绝对值是否 <= 1、大于 1 或其他……并且“其他”分支会触发!
澄清一下,一个数字将小于或等于1,或大于1,应该没有其他可能性(除非我有脑放屁:-))
更多上下文:分辨率是统一的,值为 [10.0,10.0]。
谁能解释一下这怎么可能?我唯一能想到的是 x 坐标不是浮点数。这可能吗?
precision mediump float;
uniform vec2 resolution;
void main()
{
vec2 uv = ( gl_FragCoord.xy / resolution.xy ) * 2.0 - 1.225;
uv.y *= resolution.y/resolution.x;
if (abs(uv.x) <= 1.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
} else if (abs(uv.x) > 1.0) {
gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);
} else {
/// this fires - WTF?
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
}
更新:这看起来像是一个 pixijs 问题,因为当我在 GLSL 代码中手动指定 resolution
时它起作用了。这是设置着色器的代码:
const uniforms = {
time: 0,
resolution: new Point(10.0, 10.0),
}
const filter = new Filter(undefined, fragment, {
...uniforms
});
comp.filters = [filter];
app.ticker.add((delta) => {
filter.uniforms.resolution = new Point(10.0, 10.0);
});
看起来pixi.js不喜欢resolution
作为制服名称。当我将名称更改为 u_resolution
时,它开始工作了。 :耸肩:
大多数 GLSL 实现使用 IEEE 浮点的一些变体进行计算,并且具有 NaN (not-a-number) 值的概念。 NaN 值是持久的——每当您执行涉及一个的操作时,结果都是 NaN,而当您将 NaN 与另一个浮点值进行比较时,结果始终为 false。所以你可以轻松拥有:
if (abs(uv.x) <= 1.0) {
// less than or equal to 1
} else if (abs(uv.x) > 1.0) {
// greater than 1
} else {
// uv.x must be NaN!
有多种方法可以获得 NaN,但最简单的方法是计算 0/0。所以在你的情况下,如果你同时拥有 gl_FragCooord.x == 0 和 resolution.x == 0,你会得到 NaN