0001: // ------------------------------------------------------------
0002: // Bitonic sort
0003: // 
0004: // Copyright (c) 2003 IMAGIRE Takashi. All rights reserved.
0005: // ------------------------------------------------------------
0006: 
0007: // ------------------------------------------------------------
0008: // グローバル変数
0009: // ------------------------------------------------------------
0010: float4 BufInfo; // テクスチャのサイズ
0011: float stage;    // ソートするブロックの大きさ(offsetの2倍)
0012: float stepno;   // ソートしようとしている対照の大きさ
0013: float offset;   // 比較対照のテクセルの相対位置
0014: 
0015: // ------------------------------------------------------------
0016: // Textures
0017: // ------------------------------------------------------------
0018: texture SrcMap;
0019: sampler SrcSamp = sampler_state
0020: {
0021:     Texture = <SrcMap>;
0022:     MinFilter = POINT;
0023:     MagFilter = POINT;
0024:     MipFilter = NONE;
0025: 
0026:     AddressU = Clamp;
0027:     AddressV = Clamp;
0028: };
0029: 
0030: // ------------------------------------------------------------
0031: // 頂点シェーダからピクセルシェーダに渡すデータ
0032: // ------------------------------------------------------------
0033: struct VS_OUTPUT
0034: {
0035:     float4 Pos          : POSITION;
0036:     float2 WPOS         : TEXCOORD0;
0037: };
0038: 
0039: // ------------------------------------------------------------
0040: // 1次元のインデックスからテクスチャ座標を算出する
0041: // ------------------------------------------------------------
0042: float2 convert1dto2d(float index)
0043: {
0044:     float2 dst;
0045:     
0046:     dst.x = fmod (index,  BufInfo.x) / BufInfo.x;
0047:     dst.y = floor(index / BufInfo.x) / BufInfo.y;
0048:     
0049:     return dst;
0050: }
0051: // ------------------------------------------------------------
0052: // Bitonic sort
0053: // ------------------------------------------------------------
0054: float4 BitonicSortPS(VS_OUTPUT In) : COLOR
0055: {
0056:     float4 dst;
0057:     
0058:     // 次のインデックス化のために小数部を切り取る
0059:     float2 elem2d = BufInfo * In.WPOS;
0060:     elem2d = floor(elem2d);
0061:     
0062:     // 1次元のIndexを求める
0063:     float  elem1d = elem2d.y * BufInfo.x + elem2d.x;
0064:     
0065:     // 上と下のどちらのテクセルと比較するのか?
0066:     float csign = (fmod(elem1d, stage)< offset) ? 1 : -1;
0067:     // ソートの向き
0068:     float cdir  = (fmod(floor(elem1d/stepno),2)<=0.5) ? 1 : -1;
0069:     
0070:     // レンダリング位置のテクセルを読み込む
0071:     float4 val0 = tex2D( SrcSamp, In.WPOS );
0072:     
0073:     // ソート対象のテクセルを読む込む
0074:     float adr1d = csign*offset + elem1d;// 比較対照のテクセル
0075:     float2 adr2d = convert1dto2d( adr1d );// インデックスからテクスチャ座標に変換
0076:     float4 val1 = tex2D( SrcSamp, adr2d );
0077:     
0078:     // y 成分をソートのキーとして使用
0079:     float4 cmin = (val0.y<val1.y) ? val0: val1;// 小さいほう
0080:     float4 cmax = (val0.y<val1.y) ? val1: val0;// 大きいほう
0081:     
0082:     // ソートの向きとデータサンプルの向きを比較して、どちらの値を採用するか決める
0083:     dst = (csign==cdir) ? cmin : cmax;
0084:     
0085:     return dst;
0086: }
0087: // ------------------------------------------------------------
0088: // テクニック
0089: // ------------------------------------------------------------
0090: technique TShader
0091: {
0092:     pass P0
0093:     {
0094:         PixelShader = compile ps_2_0 BitonicSortPS();
0095:     }
0096: }
0097: