- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我看到一些我无法在我编写的 WebGL 着色器中解释的奇怪行为。这不是我的专业领域,所以我完全有可能误解了一些非常简单的事情,但我不确定是什么。
我有一个代码笔来说明这里的奇怪行为 https://codepen.io/bjvanminnen/pen/XqMpvL .
void main () {
vec3 color = vec3(0.);
vec2 loc1 = vec2(0.5, 0.) / u_res;
vec2 loc2 = vec2(1.5, 0.) / u_res;
float val1 = texture2D(u_tex, loc1).r * 255.;
float val2 = texture2D(u_tex, loc1).r * 255.;
color.r = val1 == val2 ? 1. : 0.;
// commenting/uncommenting this line somehow affects the b value
// on iOS, when uncommented we end up with (53, 0, 255, 255)
// when commented we end up with (255, 0, 0, 255)
// I can think of no reason why the below line should affect color.b
color.r = floor(val1) / 255.;
color.b = val1 == 53. ? 1. : 0.;
gl_FragColor = vec4(color, 1.);
}
正在发生的事情的总结
在 JS 中,我创建了一个纹理,其中每个像素都是 #350000
在我的片段着色器中,读取前两个像素
如果两个像素相同(它们应该是),则最初将输出的 r 值设置为 1
取消注释时,根据 val1 的底部更改 color.r 的值(我不希望此步骤影响 color.b)
如果像素值为 53(即 0x35),则将输出的 b 值设置为 1。
然后我在 JS 中检查生成的像素值。
我的期望:当第二个 color.r
行被注释掉时,我希望结果为 (53, 0, 255, 255)。这是我在桌面上看到的,但在我的 iOS 设备上看到的是 (53, 0, 0, 255)。似乎 val1 在 iOS 上最终略大于 53。我假设这只是浮点怪异。
非常奇怪而且我无法理解的是,当我注释掉第二行 color.r
时,我在桌面上得到 (255, 0, 255, 255) - 这是有道理的- 但在我的 iOS 设备上是 (255, 0, 0, 255)。
换句话说,行 color.r = floor(val1)/255.;
的存在/不存在以某种方式改变了 color.b< 的结果
.
我是遇到了一些奇怪的 iOS 错误,还是我误解了什么?
最佳答案
在 GLSL ES 1.0 spec 中查找从第 4.6 节开始有很多关于不变性的部分
您案例的重要部分可能是 4.6.2
4.6.2 Invariance Within Shaders
When a value is stored in a variable, it is usually assumed it will remain constant unless explicitly changed. However, during the process of optimization, it is possible that the compiler may choose to recompute a value rather than store it in a register. Since the precision of operations is not completely specified (e.g. a low precision operation may be done at medium or high precision), it would be possible for the recomputed value to be different from the original value.
Values are allowed to be variant within a shader. To prevent this, the invariant qualifier or invariant pragma must be used.
Within a shader, there is no invariance for values generated by different non-constant expressions, even if those expressions are identical.
Example 1:
precision mediump;
vec4 col;
vec2 a = ...
...
col = texture2D(tex, a); // a has a value a1
...
col = texture2D(tex, a); // a has a value a2 where possibly a1 ≠ a2To enforce invariance in this example use:
#pragma STDGL invariant(all)
Example 2:
vec2 m = ...;
vec2 n = ...;
vec2 a = m + n;
vec2 b = m + n; // a and b are not guaranteed to be exactly equalThere is no mechanism to enforce invariance between a and b.
您将 float 与精确值进行比较,这在几乎所有语言中都显得很危险。如果我改变这一行
color.b = val1 == 53. ? 1. : 0.;
到
color.b = val1 > 52.9 && val1 < 53.1 ? 1. : 0.;
然后它按我预期的方式工作。另外,如果我用
写出val1
color.g = val1 / 153.;
我看不出有什么变化。即使您的测试失败,该行是否被注释掉也是 88。在我看来,这表明在一种情况下它不是 53.0。它是 53.000000000001 或 52.9999999999999 等...
关于ios - iOS 上 WebGL 着色器的莫名其妙行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50106581/
echo "Language"; echo " Select... English(US) English(AU)
好吧,我真的不知道为什么会这样。我目前正在实现一个线程容器,它以分离的方式运行无限循环,限制在每次迭代之间的特定速度。 标题: class timeloop { public: std::th
我收到 System.InvalidOperationException: Collection was modified;枚举操作可能无法执行: ExceptionLoggingLibrary.Lo
我是一名优秀的程序员,十分优秀!