如何在glsl中实现纹理采样功能,如纹理

时间:2016-12-08 03:45:12

标签: c++ opengl

我实现了纹理采样函数,但结果与glsl中的纹理不同。我的代码如下:

// This function warp sample from texture
float MyTexture::Sampler(float u,float v)
{
    float _u = (u - floorf(u)) * float(this->width - 1);
    float _v = (v - floorf(v)) * float(this->height - 1);
    int x0 = floorf(_u);
    int y0 = floorf(_v);
    int x1 = (x0 + 1) % (this->width - 1);
    int y1 = (y0 + 1) % (this->height - 1);

    float u1 = (_u - floorf(_u));
    float v1 = (_v - floorf(_v));
    float u0 = 1.0f - u1;
    float v0 = 1.0f - v1;

    float a = (float)texture[x0 * 4 + y0 * this->width * 4];
    float b = (float)texture[x0 * 4 + y1 * this->width * 4];
    float c = (float)texture[x1 * 4 + y0 * this->width * 4];
    float d = (float)texture[x1 * 4 + y1 * this->width * 4];

    return (u0 * (v0 * a + v1 * b) + u1 * (v0 * c + v1 * d))/255;
}

1 个答案:

答案 0 :(得分:2)

我相信你想做手动双线性过滤? 首先按大小缩放:

u = u * texwidth; 

然后分成整数和分数:

int ui = (int)u;   // works if u is positive
float uf = u - ui; // must be [0..1] 

对v做同样的事情;然后抽样四个邻居,最近邻居:

n[0] = sample(ui,vi); 
n[1] = sample(ui+1,vi);
n[2] = sample(ui,vi+1) 
n[3] = sample(ui+1,vi+1)

然后过滤:

result = lerp ( lerp(n[0],n[1],uf), lerp(n[2],n[3],uf), vf ); 

lerp是线性插值的地方:

lerp(float a, float b, float f) { return a+(b-a)*f; } 

如果需要,可以保留换行和负值。 :)

相关问题