来自文档:seq
set-if-equal destination = source1 == source2 ?1 : 0,按组件
我还没有彻底测试它,但到目前为止,我的片段着色器在两台机器(台式电脑)上都工作,其中 context3D 初始化成功作为 DirectX,但不适用于闪存回退到软件渲染的机器。
seq ft2.x, ft0.x, fc0.x
ft.x
在硬件上设置为1
,当当前像素红色值,存储在ft0.x
等于常量fc0.x
时,存储50/255
. 所以我想要发生的事情确实发生#32????
在硬件上的 (50 == 0x32) 彩色像素上,但不会发生在软件上。
我已经测试了一种解决方法,我可以用seq
更复杂的算法替换操作码,包括slt
(如果小于则设置)或sge
(如果大于或等于则设置)。
因此,问题似乎在于我提供给 GPU 的常数(50/255)和实际红色值(纹理中为 50)的比较。如果它是其他任何东西(例如 RGBA 值有不同的顺序),slt
也会sge
失败。
我在这里做错了吗?我是否应该以某种方式舍入比较值(例如乘以 255 然后删除小数)以确保它可以在所有设备和模式下工作?
更新: 其中一台具有软件渲染后备功能的机器设置为 16 位图形,但将其更改为 32 位并不能解决问题。我还盲目尝试将颜色值除以 256、128 和 127 而不是 255,希望如果浮点数具有不同的精度(并且更高和更低的数字只要它们等于256px 长渐变内的像素之一),但我的希望没有得到回报。
然后我尝试了将常量存储为整数的解决方法,并在着色器内部将值乘以 255 并删除小数,令我惊讶的是,当它在 GPU 上工作时,它在软件渲染上失败了:
mul ft0.x, ft0.x, fc0.y
通过将ft0.x(红色通道)乘以常数255将其转换为整数
frc ft4.x, ft0.x
得到一个分数
sub ft0.x, ft0.x, ft4.x
删除小数,截断整数
现在进行比较,例如seq ft2.x, ft0.x, fc0.x
add ft0.x, ft0.x, ft4.x
添加小数,这一步可能没有必要
div ft0.x, ft0.x, fc0.y
将整数值除以 255 以将其转换回浮点数(我的意思是 0..1 范围内的数字)
接下来我要尝试的解决方法是简单地进行一系列小于比较,将临时寄存器设置为 1,将其添加到另一个临时寄存器(计数器),以便通过检查计数器我可以看到值在哪个范围内。