1

在 GLSL 中调酒能以某种方式减去吗?例如: vec.-yx-wz
这样做的目的是通过简单的定义获得 2d 法线:

#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);
}
4

1 回答 1

3

+1 周期相比什么?您是否有其他选择工作,只有一条指令,没有额外的开销?

我见过的任何着色器汇编语言都不能执行每个组件的否定。您所描述的是两个 swizzled 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;

result.position(在这两种情况下,我都使用vertex.positionARB 顶点程序作为示例)。

但是,它使用额外的常量寄存器,所以不一定更好。

当然,这两个版本都可以包装成宏。

更新

我现在明白你想做什么了。生成代码的东西(对于最新的 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(这不一定会导致额外的循环,顺便说一句-取决于附近的其他说明)。

于 2014-03-31T05:11:48.150 回答