GLSL中的swizzling能以某种方式与减号一起使用吗?例如: vec.-yx-wz
这样做的目的是通过简单的定义来获得2d normale:
#DEFINE NORMALE_PACK(v) (v).-yx-wz
#DEFINE NORMALE_1(v) dir.-yx
#DEFINE NORMALE_2(v) vec.-wz
void main(){
...
float l = dot( NORMALE_PACK(dir), dir2);
}没有这一点,我就能做到这一点:
void main(){
...
vec4 normale = vec4(-dir.y, dir.x, -dir.w, dir.z); // +1 cycle on modern hardware, more - on older
float l = dot( normale, dir2);
}发布于 2014-03-31 13:11:48
与什么相比+1个周期?你有没有其他的选择,只有一条指令,没有额外的开销?
我所见过的任何着色器汇编语言都不能执行每个组件的求反。您所描述的是两个混合的mov(其中一个带有否定前缀),例如
MOV result.position.xz, -vertex.position.yyww;
MOV result.position.yw, vertex.position.xxzz;您可以使用vec4 n = vec4(dir.yxwz) * vec4(-1.0, 1.0, -1.0, 1.0)之类的命令将其简化为一条指令。这将是这样的:
PARAM c[1] = { { -1, 1 } };
MUL result.position, vertex.position.yxwz, c[0].xyxy;(在这两种情况下,我都使用了ARB vertex程序中的result.position和vertex.position作为示例)。
但是,它使用额外的常量寄存器,所以它不一定更好。
当然,这两个版本都可以封装到宏中。
更新
我现在知道你想做什么了。一些生成代码的东西,比如(针对最新的AMD):
0 x: DOT4 R0.x, -R0.y, R1.x
y: DOT4 ____, R0.x, R1.y
z: DOT4 ____, -R0.w, R1.z
w: DOT4 ____, R0.z, R1.w 相反,您会看到额外的MOVs。然而,它看起来不像是有效的代码(我不认为DOT可以接受部分否定的参数。如果不仔细阅读说明手册,就不能说更多),所以编译器添加了额外的MOV (顺便说一句,这不一定会导致额外的周期-取决于附近的其他指令)。
https://stackoverflow.com/questions/22753762
复制相似问题