如何让GLSL的step函数返回整数以实现数组索引偏移?
解决GLSL中step函数返回值用于数组索引的问题
GLSL的step()函数确实天生返回浮点数(或浮点向量),没办法直接让它返回整数,但你完全可以用几种优雅的方式解决数组索引的需求,而且不用引入if语句——甚至强制转换在这里其实是完全安全的,不用有顾虑。
方法1:安全强制转换为整数
你担心强制转换不妥,但step()的返回值是严格的0.0或1.0,这两个浮点数在转换为整数时不会有任何精度损失,因为它们正好对应整数0和1的浮点表示。直接用int()转换就行:
const int[8] constIndicies = int[](0,1,2,3, 1,3,0,2); // ... float ratioEdge = 17.0f; float myFloatValue = 9.0f; // ... int stepResult = int(step(ratioEdge, myFloatValue)); constIndicies[4 * stepResult]
这个写法完全符合GLSL规范,编译器也会优化成无分支的代码,和你用step()的初衷一致。
方法2:用三元运算符替代(无分支优化)
如果你实在不想用强制转换,也可以用GLSL的三元运算符。对于这种条件结果是布尔值的场景,编译器会自动将它优化为无分支的硬件指令,和step()的性能表现一致:
const int[8] constIndicies = int[](0,1,2,3, 1,3,0,2); // ... float ratioEdge = 17.0f; float myFloatValue = 9.0f; // ... int offset = (myFloatValue >= ratioEdge) ? 1 : 0; constIndicies[4 * offset]
这里的三元运算符不会引入你担心的分支开销,本质上和step()的逻辑是等价的。
为什么step()返回浮点数?
顺便提一句,GLSL设计step()返回浮点数是为了让它能无缝融入浮点运算管线——比如用于颜色混合、纹理坐标插值这类场景,浮点返回值比整数更灵活。但在你这种需要整数索引的场景,精确转换完全没问题。
内容的提问来源于stack exchange,提问作者Mr. Smith
相关产品推荐
相关产品推荐

