2

フラグメントシェーダーがあり、小さなルックアップテーブルを作成して補間したいと思います。私の現在のコードはこれです(冗長性については申し訳ありません):

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;
        }
    }
}

#version 120を使用していますが、機能していません(この関数が呼び出されるすべての反復は、同じ値を返します)。したがって、配列で何か問題が発生している(同じ値で埋められている)か、理解できない方法でループが展開されるため、forループからの戻りが機能しません。この動作を引き起こす可能性のある何かが思い浮かびますか(渡されたR値とは関係なく同じ値が返されます)?

4

2 に答える 2

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);
        }
    }
}
于 2012-04-17T17:16:45.700 に答える
1

コードは機能するように見えますが、ルックアップテーブルが完全に均一である場合(adsk_input1_frameratioは均一な変数であり、dustation_fは変化を読み取​​らない)、CPUでlutを計算して均一にする方がはるかに優れています。ユニフォームを設定するときに一度計算する配列。

于 2012-04-17T17:55:39.550 に答える