ошибка смещения после 2-го доступа к текстуре - PullRequest
1 голос
/ 13 декабря 2011

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

На первом шаге указатель считывается из подизображения 2x2 в позиции 0x0, используя предоставленные координаты uv. Затем этот указатель используется для доступа к другой части 2x2 той же текстуры. Однако для каждого дочернего элемента корневого узла увеличивается ошибка смещения, которая приводит к неправильному цвету.

Вот мой шейдер (для отладочных циклов цикл фиксируется за одну итерацию, поэтому доступны только 2 уровня четырехугольного дерева).

Также для отладки я поместил красное изображение 2х2 в местоположение верхнего левого потомка, зеленое изображение в верхнем правом углу, синий для нижнего левого и желтый для нижнего правого дочернего.

Полученное изображение выглядит так: enter image description here

Я совершенно невежественен. Может ли кто-нибудь из вас придумать причину, по которой это происходит? Я проверяю все преобразования координат и вычисления 3 раза, все они верны.

Вот шейдер:

// virtual_image.fs
precision highp float;

uniform sampler2D t_atlas;
uniform sampler2D t_tree;

uniform vec2 gridpoolSize;
uniform vec2 atlasTileSize;
uniform vec2 atlasSize;

varying vec2 v_texcoord;

const float LEAF_MARKER = 1.0;
const float NODE_MARKER = 0.0;

const float CHANNEL_PERECISION = 255.0;

vec2 decode(const vec2 vec){
    return vec * CHANNEL_PERECISION;
}

void main ()
{
    vec4 oc = vec4(1); // output color
    vec4 tColor = texture2D(t_tree, v_texcoord); // only for debuging
    vec4 aColor = texture2D(t_atlas, v_texcoord); // only for debuging
    // oc = mix(tColor, aColor, 0.5);

    highp vec2 localCoord = v_texcoord;

    // by convention the root node starts at [0,0]
    // so we read the first pointer relative to that point
    // we use the  invertedGridpoolSize to convert the local coords in local coords of the first grid at [0,0]
    highp vec3 pointer = texture2D(t_tree, localCoord / gridpoolSize).rgb;// pointer is correct at this point!

    for(int i = 0 ; i < 1; i++) {

        // divides the local coords into 4 quadrants
        localCoord = fract(localCoord * 2.0); // localCoord is correct!


        // branch
        if(pointer.b <= NODE_MARKER + 0.1){
            highp vec2 index = decode(pointer.rg);// index is correct!
            highp vec2 absoluteCoord = (localCoord + index) / gridpoolSize;// absoluteCoord is correct!
            // we have a inner node get next pointer and continue
            pointer = texture2D(t_tree, absoluteCoord).rgb;
            oc.rgb = pointer.rgb; // this point in the code introduces a growing offset, I don't know where this comes from. BUG LOCATION
            //gl_FragColor = vec4(1,0,0,1);
        } else {
            if(pointer.b >= LEAF_MARKER - 0.1){
                // we have a leaf
                vec2 atlasCoord = ((decode(pointer.rg)  * atlasTileSize) / atlasSize) + (localCoord * (atlasTileSize / atlasSize));
                vec4 atlasColor = texture2D(t_atlas, atlasCoord);
                //vec4 atlasCoordColor = vec4(atlasCoord,0,1);
                //gl_FragColor = mix(atlasColor, vec4(localCoord, 0, 1), 1.0);
                //gl_FragColor = vec4(localCoord, 0, 1);
                oc = vec4(1,0,1,1);
            } else {
                // we have an empty cell
                oc = vec4(1,0,1,1);
            }
        }
    }
    //oc.rgb = pointer;
    //oc.rgb = oc.rgb * (255.0 / 20.0 );
    gl_FragColor = oc;
}

Подробную информацию о том, как сериализовать дерево квадов в качестве текстуры, можно найти в этой статье: Текстуры Octree на графическом процессоре

1 Ответ

1 голос
/ 14 декабря 2011

Оказывается, это проблема округления.

Код в функции декодирования должен быть изменен на:

vec2 decode(const vec2 vec){
    return floor(0.5 + (vec * CHANNEL_PERECISION))
}

Возвращаемыми значениями должны были быть индексы типа int, но с небольшим или небольшим значением, например 5.99 вместо 6.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...