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サイクル?1 つの命令のみで、追加のオーバーヘッドがない他のオプションはありますか?

私が見たシェーダー アセンブリ言語は、コンポーネントごとの否定を実行できません。あなたが説明したのは、次のような2つのスウィズルされたmovsです(そのうちの1つは否定プレフィックス付きです)

MOV result.position.xz, -vertex.position.yyww;
MOV result.position.yw, vertex.position.xxzz;

のようなものを使用して、1 つの命令に減らすことができます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 を追加します (必ずしも余分なサイクルが発生するわけではありません)。 、ちなみに-近くの他の指示に依存します)。

于 2014-03-31T05:11:48.150 に答える