在我的 Minecraft 着色器中,这行代码未按预期工作:
finalDayColor = mix(vec3(1.00, 0.37, 0.00), vec3(1.00, 0.92, 0.82), clamp(worldTime, 0.0, 1.0));
变量
worldTime
是统一整数,finalDayColor
是vec3
。代码正在编译,没有错误。
我期望的是
finalDayColor
将返回基于 worldTime
的颜色。相反,它会返回相同的颜色,而不取决于 worldTime
。我认为这是因为钳位函数返回了其他东西。
我尝试弄乱这些值并寻找替代函数,但无济于事。我是不是做错了什么?
让我们从基础知识开始:您写道
worldTime
是一个整数,这意味着它不能存储小数。所以该值可以是-1、0、1、2等,但不能是0.5。
函数 clamp
没有带有参数 int
、float
、float
的签名,但是(桌面)GLSL 可以将 int
转换为 float
(隐式转换)。因此,虽然 worldTime
是 int
,但它会转换为 float
。 float
s 可以存储小数,但由于它是从 int
转换而来的,因此小数部分始终为 0。
clamp
函数有3个参数:x
、minVal
和maxVal
。如果它位于 x
和 minVal
之间,则返回 maxVal
。如果 minVal
低于 x
,则返回 minVal
;如果 maxVal
大于 x
,则返回 maxVal
。所以本质上返回的值总是在 minVal
和 maxVal
之间。根据您的参数,如果 wordTime
小于或等于 0.0,则返回值为 0.0;如果 wordTime
大于或等于 1.0,则返回 1.0。我不确定你在 wordTime
中存储了什么,但我想象每帧或每秒都会增加一些东西,这意味着 clamp
几乎总是返回 1.0。
mix
函数根据第三个参数(clamp
函数调用)混合(线性插值)2个向量。因此,如果 clamp
返回 0.0,mix
将返回 vec3(1.00, 0.37, 0.00)
,如果 clamp
返回 1.0,mix
将返回 vec3(1.00, 0.92, 0.82)
。如果 clamp
返回 0.5,mix
将返回这些向量中间的一个向量。但是,正如我之前提到的,在这种情况下,clamp
不会返回 0.5,只会返回 0.0 或 1.0。所以结果将是 2 个向量之一,很可能是第二个。
所以从技术上讲,
finalDayColor
取决于wordTime
,但你可以操纵它,这样你就不会看到两个向量之间的逐渐变化(我认为这是你的目标)。如果你想要逐渐改变,我会这样做:
finalDayColor = mix(vec3(1.00, 0.37, 0.00), vec3(1.00, 0.92, 0.82), sin(time) * 0.5 + 0.5);
其中
time
是一个 uniform float
变量,其中包含自启动应用程序以来经过的时间或类似的内容。 sin
函数返回 -1.0 和 1.0 之间的值。然后我将其乘以 0.5,因此间隔将在 -0.5 和 0.5 之间,然后加上 0.5,因此最终间隔将在 0.0 和 1.0 之间,所以您甚至不需要 clamp
。