可以在GLSL中以某种方式调整减少?例如: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);
}
答案 0 :(得分:3)
+1周期比较什么?你有其他选择工作,只有一条指令,没有额外的开销吗?
我见过的没有着色器汇编语言可以执行每个组件的否定。你所描述的是两个混合的mov
s(其中一个带有否定前缀),如
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顶点程序中的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
相反,你会看到额外的MOV。但是,它看起来不是有效的代码(我不认为DOT可以采取部分否定的参数。如果不仔细阅读说明手册就不能说更多),因此编译器会增加额外的MOV(这不一定会导致额外的循环顺便说一下 - 取决于附近的其他指示。)