smoothstep() returns "identical" 个参数的不同值
smoothstep() returns different values for "identical" arguments
运行 一台配备 Intel® Iris® Plus 显卡的 Surface Laptop 3(驱动程序版本 30.0.101.1191)。也许我正面临英特尔着色器编译器中的错误。虽然,我对着色器的总体经验有限,所以可能会出现以下行为。
前往 https://www.shadertoy.com/new 并尝试下面的着色器。出于某种原因,与 1.0
.
的编译时常量相比,定义 float d = 1.0
似乎会产生不同的结果
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float d = 1.0;
// WHY this returns 1?
#if 1
float x = smoothstep(0.0, 0.0, d);
#else
// Whereas this returns 0?
float x = smoothstep(0.0, 0.0, 1.0);
// OR this for that matter:
// float x = smoothstep(0.000000000000001, 0.0, d);
#endif
fragColor = vec4(1.0, 0.0, 1.0, 1.0) * x;
}
因此,smoothstep(0.0, 0.0, 1.0)
returns 0 但等价于 smoothstep(0.0, 0.0, d)
returns 1。为什么?
smoothstep
要求第一个参数edge0
严格小于第二个参数edge1
。 edge0 >= edge1
.
时结果未定义
这背后的原因很简单。来自 GL 文档 (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/smoothstep.xhtml)
代码看起来像这样:
genType t; /* Or genDType t; */
t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
记下分母,
(edge1 - edge0)
如果这些值相等,则为零除。因此,您的实现返回 0
或 1
因为它不能抛出异常,因为它是 C.
编辑:
关于“为什么返回 0 或 1”的问题:GL 文档中的示例实现将结果从 0 钳位到 1。如果 edge0 > edge1
,生成的负值将钳位到 0
。如果 edge0 == edge1
,除以零会产生正无穷大,它被限定为 1
。
但是,这都是推测,因为您系统的 GL 实现中的实际实现 是一个黑盒子。对于 edge0 >= edge1
的情况,结果未定义,应忽略。
运行 一台配备 Intel® Iris® Plus 显卡的 Surface Laptop 3(驱动程序版本 30.0.101.1191)。也许我正面临英特尔着色器编译器中的错误。虽然,我对着色器的总体经验有限,所以可能会出现以下行为。
前往 https://www.shadertoy.com/new 并尝试下面的着色器。出于某种原因,与 1.0
.
float d = 1.0
似乎会产生不同的结果
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float d = 1.0;
// WHY this returns 1?
#if 1
float x = smoothstep(0.0, 0.0, d);
#else
// Whereas this returns 0?
float x = smoothstep(0.0, 0.0, 1.0);
// OR this for that matter:
// float x = smoothstep(0.000000000000001, 0.0, d);
#endif
fragColor = vec4(1.0, 0.0, 1.0, 1.0) * x;
}
因此,smoothstep(0.0, 0.0, 1.0)
returns 0 但等价于 smoothstep(0.0, 0.0, d)
returns 1。为什么?
smoothstep
要求第一个参数edge0
严格小于第二个参数edge1
。 edge0 >= edge1
.
这背后的原因很简单。来自 GL 文档 (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/smoothstep.xhtml)
代码看起来像这样:
genType t; /* Or genDType t; */
t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
记下分母,
(edge1 - edge0)
如果这些值相等,则为零除。因此,您的实现返回 0
或 1
因为它不能抛出异常,因为它是 C.
编辑:
关于“为什么返回 0 或 1”的问题:GL 文档中的示例实现将结果从 0 钳位到 1。如果 edge0 > edge1
,生成的负值将钳位到 0
。如果 edge0 == edge1
,除以零会产生正无穷大,它被限定为 1
。
但是,这都是推测,因为您系统的 GL 实现中的实际实现 是一个黑盒子。对于 edge0 >= edge1
的情况,结果未定义,应忽略。