glsl减去调情

时间:2014-03-31 04:41:15

标签: opengl glsl swizzling

可以在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);
}

1 个答案:

答案 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.positionvertex.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(这不一定会导致额外的循环顺便说一下 - 取决于附近的其他指示。)