来自文档:seq
set-if-equal destination = source1 == source2? 1:0,分量
我还没有彻底测试过,但到目前为止,我的片段着色器在两台机器(台式机)上工作,其中context3D初始化成功为DirectX,但在闪存回落到软件渲染的机器上不起作用。 / p>
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)的常量I供应与实际红色值(纹理中的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范围内的数字)
接下来我将尝试作为一种解决方法是简单地进行一系列小于比较,将temp寄存器设置为1,将其添加到另一个临时寄存器(计数器),以便通过检查我可以在柜台内看到哪个范围是值。
答案 0 :(得分:2)
这是最终为我做了诀窍的解决方法。
我在红色Alpha通道上有4种颜色,它们通知着色器该做什么。如果红色值为50,则着色器将左侧像素作为源,如果为100,则将采用顶部像素,依此类推。所以我所要做的只是4 seq
个命令,将0或1个偏移设置为寄存器的4个分量,我可以稍后在寄存器中添加或删除带有采样器位置的寄存器。
因为seq
未能将第一次采样中的像素的红色值与提供的常数进行比较,所以我制作了一个“梯形图”,其中包含set-if-greater-or-equal操作码:
"mov ft3.x, fc0.x \n" + //ft3 = 49/0xFF
"sge ft2.x, ft0.x, ft3.x \n" + //if red > 49/0xFF, set 1 to ft2.x
"add ft3.x, ft3.x, fc0.x \n" + //ft3 = 98/0xFF
"sge ft4.x, ft0.x, ft3.x \n" + //if red > 98/0xFF, set 1 to ft4.x
"add ft2.x, ft2.x, ft4.x \n" + //if 49 < red < 98, ft2.x = 1, if red > 98, ft2.x = 2
"add ft3.x, ft3.x, fc0.x \n" + //ft3 = 147/0xFF
"sge ft4.x, ft0.x, ft3.x \n" + //if red > 147/0xFF, set 1 to ft4.x
"add ft2.x, ft2.x, ft4.x \n" + //if 49 < red < 98, ft2.x = 1, if 98 < red < 147, ft2.x = 2, if red > 147, ft2.x = 3
"add ft3.x, ft3.x, fc0.x \n" + //ft3 = 196/0xFF
"sge ft4.x, ft0.x, ft3.x \n" + //if red > 196/0xFF, set 1 to ft4.x
"add ft2.x, ft2.x, ft4.x \n" + //ft2.x is between 0 and 4 including, where 0 means no control color
现在我有一个寄存器ft2存储:
0
红色低于49
(实际上所有这些红色值都除以255,如上面代码中的注释所示)
1
代表49
和98
2
代表98
和147
3
代表147
和196
4
以上的红色, 196
然后我不是将像素颜色与常数进行比较,而是将ft2.x
计数器状态与常数进行比较(常数为1,2,3,4而不是50,100,150,200)。
不幸的是,这意味着上面的整个代码是一个额外的开销,我可以省去GPU,但无法避免在CPU上,除非我能找到seq
操作码的解决方案总是在CPU上返回0时比较a像素颜色和常数。