2012-04-17 22 views
2

我有一个片段着色器,我想构建一个小的loookup表并在其上插值。我当前的代码是这样的(遗憾的冗长):在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; 
     } 
    } 
} 

我用的#Version 120。但是它不工作(所有的地方调用此函数返回相同的值迭代)工作。因此,无论我对数组做了什么错误(它将被填充相同的值)或for循环的返回都不起作用,因为循环以某种我不明白的方式展开。是否有什么会引起这种行为(独立于传入的R值而返回相同的值)?

+0

究竟发生了什么与您期望的相反(以及您期望的是什么?)您使用的驱动程序/ OpenGL版本以及用于渲染的硬件/软件是什么? – 2012-04-17 17:55:16

回答

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

代码看起来像它应该工作,如果查找表是完全一致的(adsk_input1_frameratio是一个统一的VAR和distortion_f不读任何varyings)虽然,那么你在计算CPU上的标记并使之成为一个统一的数组时,会更好。

+0

我确实想这样做,但我无法访问系统的CPU部分 - 我只能加载着色器。定义制服时我无法做一个for循环。 – Julik 2012-04-18 10:05:03