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

其次,我在线性插值中犯了一个错误,因为我需要将左元组的初始值添加到结果中。

而且,作为最后的无赖,其中一件制服被命名为错误,因此它默认为 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 是统一的 var,而失真_f 没有读取任何变化),那么最好在 CPU 上计算 lut 并使其成为统一的设置制服时计算一次的数组。

于 2012-04-17T17:55:39.550 回答