我有一个片段着色器,我想构建一个小的loookup表并在其上进行插值。我目前的代码是这样的(对于冗长而言):
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 :(得分: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 :(得分:1)
代码看起来应该可以工作,但是如果查找表完全一致(adsk_input1_frameratio是一个统一的var并且distortion_f没有读取任何变化),那么你最好不要计算lut on CPU,并使它成为一个统一的数组,当你设置制服时,你可以计算一次。