2012-04-17 8 views
2

私はフラグメントシェーダを持っています。小さなルックアップテーブルを作成して補間したいと思います。私の現在のコードは、この(冗長性のために申し訳ありません)です:私は#version 120しかし、それは働いていない(と呼ばれるこの機能は、同じ値を返すすべての反復)で働いていますGLSLシェーダの小さなルックアップテーブルを使用

float inverse_f(float r) 
{ 

    // Build a lookup table on the radius, as a fixed-size table. 
    // We will use a vec3 since we will store the multipled number in the Z coordinate. 
    // So to recap: x will be the radius, y will be the f(x) distortion, and Z will be x * y; 
    vec3[32] lut; 

    // Flame has no overflow bbox so we can safely max out at the image edge, plus some cushion 
    float max_r = sqrt((adsk_input1_aspect * adsk_input1_aspect) + 1) + 0.1; 
    float incr = max_r/32; 
    float lut_r = 0; 
    float f; 
    for(int i=0; i < 32; i++) { 
     f = distortion_f(lut_r); 
     lut[i] = vec3(lut_r, f, lut_r * f); 
     lut_r += incr; 
    } 

    float df; 
    float dz; 
    float t; 

    // Now find the nehgbouring elements 
    for(int i=0; i < 32; i++) { 
     if(lut[i].z < r) { 
      // found! 
      df = lut[i+1].y - lut[i].y; 
      dz = lut[i+1].z - lut[i].z; 
      t = (r - lut[i].z)/dz; 
      return df * t; 
     } 
    } 
} 

。だから私は配列(それは同じ値でいっぱいになってきている)何か間違ってやっているか、ループが私が理解していないいくつかの方法で展開されるので、forループからの戻りは機能しません。この動作(同じ値が渡されたR値とは無関係に返される)を引き起こす可能性のあるものがありますか?

+0

期待どおりに何が起こっているのですか(そして何を期待していますか?)使用しているドライバ/ OpenGLのバージョンとレンダリングするハードウェア/ソフトウェアは何ですか? –

答えて

1

ここで私は3回間違いをしました。

まず、私はそれらの間を補間するために、両方の要素を見つける必要があり、その条件は第二

lut[i].z > r && lut[i-1].z < r 

にする必要があり、私はの初期値を追加する必要があるため、私は、線形補間でミスを犯しました結果にタプルを残しました。

最後のバマーとして、ユニフォームの1つが間違っていたので、デフォルトで0になり、計算が中断されました。最終版(多かれ少なかれ)これです:

float inverse_f(float r) 
{ 

    // Build a lookup table on the radius, as a fixed-size table. 
    // We will use a vec3 since we will store the multipled number in the Z coordinate. 
    // So to recap: x will be the radius, y will be the f(x) distortion, and Z will be x * y; 
    vec3[32] lut; 

    // Flame has no overflow bbox so we can safely max out at the image edge, plus some cushion 
    float max_r = sqrt((adsk_input1_frameratio * adsk_input1_frameratio) + 1) + 1; 
    float incr = max_r/32; 
    float lut_r = 0; 
    float f; 
    for(int i=0; i < 32; i++) { 
     f = distortion_f(lut_r); 
     lut[i] = vec3(lut_r, f, lut_r * f); 
     lut_r += incr; 
    } 

    float df; 
    float dr; 
    float t; 

    // Now find the nehgbouring elements 
    for(int i=0; i < 32; i++) { 
     if(lut[i].z > r && lut[i-1].z < r) { 
      // found! 
      df = lut[i+1].y - lut[i].y; 
      dr = lut[i+1].z - lut[i].z; 
      t = (r - lut[i].z)/dr; 
      return lut[i].y + (df * t); 
     } 
    } 
} 
1

それが動作するはずのようなコードは、ルックアップテーブルが完全に均一(adsk_input1_frameratioが均一varとdistortion_fある任意の可変長を読んでいない)であれば、けれども、見えますあなたは、CPU上のラットを計算し、ユニフォームを設定するときに一度計算する均一な配列にする方がずっと優れています。

+0

私はそれを本当にしたいと思っていますが、システムのCPU部分にアクセスすることはできません。シェーダをロードするだけです。そして私は、制服を定義するときにforループを行うことはできません。 – Julik

関連する問題