Фрагментные шейдеры на картах ATI и NVIDIA - PullRequest
2 голосов
/ 29 июня 2011

Я использую этот шейдер fragent (вдохновленный некоторым руководством, найденным на сайте NVIDIA некоторое время назад). Он в основном вычисляет билинейную интерполяцию 2D текстуры.

uniform sampler2D myTexture;
uniform vec2 textureDimension;

#define texel_size_x 1.0 / textureDimension[0]
#define texel_size_y 1.0 / textureDimension[1]

vec4 texture2D_bilinear( sampler2D texture, vec2 uv)
{
    vec2 f;
    uv = uv + vec2( - texel_size_x / 2.0, - texel_size_y / 2.0);

    f.x = fract( uv.x * textureDimension[0]);
    f.y = fract( uv.y * textureDimension[1]);

    vec4 t00 = texture2D( texture, vec2(uv));
    vec4 t10 = texture2D( texture, vec2(uv) + vec2( texel_size_x, 0));
    vec4 tA = mix( t00, t10, f.x);

    vec4 t01 = texture2D( texture, vec2(uv) + vec2( 0, texel_size_y));
    vec4 t11 = texture2D( texture, vec2(uv) + vec2( texel_size_x, texel_size_y));
    vec4 tB = mix( t01, t11, f.x);

    vec4 result = mix( tA, tB, f.y);
    return result;
}

Это выглядит довольно просто и прямолинейно. Я недавно протестировал его на нескольких картах ATI (последние версии драйверов ...) и получил следующий результат:

Original data (Nearest neighbor) Shader in use

(Слева: ближайший сосед) (Справа: более жесткий)

Как видите, появляются горизонтальные и вертикальные линии, важно отметить, что они не зафиксированы ни в координатах порта просмотра, ни в координатах текстуры.

Мне пришлось портировать несколько шейдеров, чтобы заставить их корректно работать на картах ATI, кажется, реализация NVIDIA немного более разрешительная относительно плохого кода, который я написал когда-то. Но в этом случае я не вижу, что мне следует изменить!

Что-нибудь общее, что я должен знать о различиях между NVIDIA и ATI GLSL, чтобы преодолеть это?

Ответы [ 2 ]

4 голосов
/ 29 июня 2011

nVidia более разрешительна, например, nVidia позволяет вам разыгрывать неправильно (т.е. float4 to float), только делая это предупреждение, ATI не будет (ошибка).Существует большая разница, если вы используете OpenGL, чем если вы используете DirectX, например, у меня был довольно сложный вершинный шейдер (скины матрицы), и даже без малейшего предупреждения он не работал на ATI (но на nVidia).

Так что, если вы не хотите, чтобы шейдеры работали «везде», приобретите карту ATI :-) (или лучше, встроенный чипсет ^^).

2 голосов
/ 30 июня 2011

Насколько я могу судить, вы не измеряете координату текстуры перед выборкой текстуры.Это может быть причиной появления этих линий, потому что ваша входная координата текстуры лежит именно на границе между текселями.Поэтому вам нужно сначала квантовать uv в тексельные центры.Имейте в виду, что координаты текстуры 0 и 1 находятся не в центрах текселей, а определяют границы сетки, где ячейки сетки - это тексели, а центры текселей - в (texel_n + 0.5) / texture_dim, или вы используете функцию GLSL texelFetch доступно GLSL 1.30и позже.

...