14

glsl でバイキュービック テクスチャ フィルタリングを実行するための完全で機能する効率的なコードを誰かが持っているかどうか疑問に思っています。これがあります:

http://www.codeproject.com/Articles/236394/Bi-Cubic-and-Bi-Linear-Interpolation-with-GLSL または https://github.com/visionworkbench/visionworkbench/blob/master/src/vw/ GPU/シェーダー/Interp/interpolation-bicubic.glsl

ただし、どちらも 16 のテクスチャ読み取りを行いますが、必要なのは 4 つだけです。

https://groups.google.com/forum/#!topic/comp.graphics.api.opengl/kqrujgJfTxo

ただし、上記の方法では、何をすべきかわからない不足している「cubic()」関数を使用しており、説明のつかない「texscale」パラメーターも使用しています。

NVidia バージョンもあります。

https://developer.nvidia.com/gpugems/gpugems2/part-iii-high-quality-rendering/chapter-20-fast-third-order-texture-filtering

しかし、これはNVidiaのカードに固有のCUDAを使用していると思います。glslが必要です。

おそらく nvidia バージョンを glsl に移植することもできますが、最初に、完全に動作する glsl バイキュービック シェーダーを誰かがすでに持っているかどうかを確認するように依頼したいと思いました。

4

8 に答える 8

10

古い Perforce アクティビティを掘り下げてみることにしましたが、欠落している cube() 関数を見つけました。楽しい!:)

vec4 cubic(float v)
{
    vec4 n = vec4(1.0, 2.0, 3.0, 4.0) - v;
    vec4 s = n * n * n;
    float x = s.x;
    float y = s.y - 4.0 * s.x;
    float z = s.z - 4.0 * s.y + 6.0 * s.x;
    float w = 6.0 - x - y - z;
    return vec4(x, y, z, w);
}
于 2014-05-21T13:32:36.647 に答える
7

JAre の回答に欠けている機能cubic()は次のようになります。

vec4 cubic(float x)
{
    float x2 = x * x;
    float x3 = x2 * x;
    vec4 w;
    w.x =   -x3 + 3*x2 - 3*x + 1;
    w.y =  3*x3 - 6*x2       + 4;
    w.z = -3*x3 + 3*x2 + 3*x + 1;
    w.w =  x3;
    return w / 6.f;
}

3 次 B スプラインの 4 つの重みを返します。

それはすべてNVidia Gemsで説明されています。

于 2013-02-09T19:47:02.277 に答える
6

わお。上記のコードは 2011 年の初めに思いついたので認識しています (評判が 50 未満でコメントできません)。私が解決しようとしていた問題は、古い IBM T42 に関連していました (正確なモデル番号は不明です) ラップトップとそれは ATI グラフィック スタックです。NV カードでコードを開発し、当初は 16 のテクスチャ フェッチを使用していました。それはちょっと遅かったですが、私の目的には十分な速さでした。誰かが彼のラップトップで動作しないと報告したとき、フラグメントごとに十分なテクスチャ フェッチをサポートしていないことが明らかになりました。私は回避策を設計する必要があり、私が思いついた最善の方法は、機能するテクスチャ フェッチの数でそれを行うことでした。

私は次のように考えました: さて、各クワッド (2x2) を線形フィルターで処理する場合、残りの問題は、行と列が重みを共有できるかということです。コードの作成に着手したとき、それが唯一の問題でした。もちろん、共有することもできます。重みは各列と行で同じです。完全!

今、私は4つのサンプルを持っていました。残りの問題は、サンプルを正しく組み合わせる方法でした。それが克服すべき最大の障害でした。鉛筆と紙で約10分かかりました。震える手でコードを入力したところ、うまくいきました。それからバイナリを彼の T42 (?) でチェックアウトすると約束した人にアップロードしたところ、彼はそれが機能したと報告しました。終わり。:)

方程式がチェックアウトされ、サンプルを個別に計算するのと数学的に同一の結果が得られることを保証できます。参考までに: CPU では、水平スキャンと垂直スキャンを別々に行う方が高速です。GPU では、複数のパスを使用することは、特に一般的なユース ケースで実現不可能な場合は特に、それほど優れたアイデアではありません。

参考までに、cubic() 関数にテクスチャ ルックアップを使用することは可能です。どちらが速いかは GPU によって異なりますが、一般的に言えば、サンプラーは ALU 側で軽く、演算を行うだけでバランスが取れます。YMMV。

于 2014-05-21T10:34:26.683 に答える
4

(編集)

3 次スプライン

  • Texscale は、ウィンドウ サイズ係数のサンプリングです。1.0 値から開始できます。

vec4 filter(sampler2D texture, vec2 texcoord, vec2 texscale)
{
    float fx = fract(texcoord.x);
    float fy = fract(texcoord.y);
    texcoord.x -= fx;
    texcoord.y -= fy;

    vec4 xcubic = cubic(fx);
    vec4 ycubic = cubic(fy);

    vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y -
0.5, texcoord.y + 1.5);
    vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x +
ycubic.y, ycubic.z + ycubic.w);
    vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) /
s;

    vec4 sample0 = texture2D(texture, vec2(offset.x, offset.z) *
texscale);
    vec4 sample1 = texture2D(texture, vec2(offset.y, offset.z) *
texscale);
    vec4 sample2 = texture2D(texture, vec2(offset.x, offset.w) *
texscale);
    vec4 sample3 = texture2D(texture, vec2(offset.y, offset.w) *
texscale);

    float sx = s.x / (s.x + s.y);
    float sy = s.z / (s.z + s.w);

    return mix(
        mix(sample3, sample2, sx),
        mix(sample1, sample0, sx), sy);
}

ソース

于 2012-11-21T21:37:56.937 に答える
2

tri -cubic 補間を行う GLSL コードに興味のある方は、 http ://www.dannyruijters.nl/cubicinterpolation/CI.zip の examples/glCubicRayCast フォルダーに、3 次補間を使用したレイキャスティング コードを見つけることができます 。

編集: 3 次補間コードが github で利用できるようになりました: CUDAバージョンとWebGLバージョン、およびGLSLサンプル。

于 2013-08-05T09:21:08.677 に答える
1

@Maf の 3 次スプライン レシピを 1 年以上使用してきました。3 次 B スプラインがニーズを満たす場合は、それをお勧めします。

しかし最近、私の特定のアプリケーションでは、強度がサンプル ポイントで正確に一致することが重要であることに気付きました。そこで、次のように少し異なるレシピを使用する Catmull-Rom スプラインの使用に切り替えました。

// Catmull-Rom spline actually passes through control points
vec4 cubic(float x) // cubic_catmullrom(float x)
{
    const float s = 0.5; // potentially adjustable parameter
    float x2 = x * x;
    float x3 = x2 * x;
    vec4 w;
    w.x =    -s*x3 +     2*s*x2 - s*x + 0;
    w.y = (2-s)*x3 +   (s-3)*x2       + 1;
    w.z = (s-2)*x3 + (3-2*s)*x2 + s*x + 0;
    w.w =     s*x3 -       s*x2       + 0;
    return w;
}

http://www.cs.cmu.edu/afs/cs/academic/class/15462-s10/www/lecの講義ノートで、これらの係数に加えて、3 次スプラインの他の多くの係数を見つけました 。 -スライド/lec06.pdf

于 2015-09-18T18:35:55.513 に答える