Быстрый способ выбора кубовой грани в GLSL - PullRequest
5 голосов
/ 30 августа 2011

Я ищу, чтобы оптимизировать следующую функцию glsl, которая делает выбор лица cubmap. Он принимает 3-компонентный вектор и возвращает лицо, текстовые координаты для лица и самый большой компонент.

vec4 cubemap( vec3 P )
{
    vec4 Coord;
    vec3    s = abs(P.xyz);
    bvec3   b = greaterThan( P.xyz, vec3(0,0,0) );

    if ( all( greaterThanEqual( s.xx, s.yz ) ) )
    {
        if ( b.x )
            Coord = vec4( -P.z, -P.y, 0, s.x );
        else
            Coord = vec4(  P.z, -P.y, 1, s.x );
    } else 
    if ( all( greaterThanEqual( s.yy, s.xz ) ) )
    {
        if ( b.y )
            Coord = vec4(  P.x,  P.z, 2, s.y );
        else
            Coord = vec4(  P.x, -P.z, 3, s.y );
    } else 
    {
        if ( b.z )
            Coord = vec4(  P.x, -P.y, 4, s.z );
        else
            Coord = vec4( -P.x, -P.y, 5, s.z );
    }

    Coord.xy = ((Coord.xy / Coord.w) + 1.0) * 0.5;
    return Coord;
}

Ответы [ 2 ]

2 голосов
/ 14 марта 2016

Этот путь может все еще быть медленным, но он не делает разветвления:

vec2 directionToUV(vec3 v) {
    vec3 abs = abs(v);
    float max = max(max(abs.x, abs.y), abs.z); // Get the largest component
    vec3 weights = step(max, abs); // 1.0 for the largest component, 0.0 for the others
    float sign = dot(weights, sign(v)) * 0.5 + 0.5; // 0 or 1

    // Find the uv coordinate 
    float sc = dot(weights, mix(vec3(v.z, v.x, -v.x), vec3(-v.z, v.x, v.x), sign));
    float tc = dot(weights, mix(vec3(-v.y, -v.z, -v.y), vec3(-v.y, v.z, -v.y), sign));
    vec2 uv = (vec2(sc, tc) / max) * 0.5 + 0.5;

    // Offset into the right region of the texture
    float offsetX = dot(weights, vec3(0.0, 1.0, 2.0));
    float offsetY = sign;
    uv.x = (uv.x + offsetX) / 3.0;
    uv.y = (uv.y + offsetY) / 2.0;
    return uv;
}

Где кубические карты расположены как

        +----+----+----+
        |  x |  y |  z |
        +----+----+----+
        | -x | -y | -z |
        +----+----+----+
0 голосов
/ 05 ноября 2011

Вы можете оптимизировать динамические ветви.Я не уверен, что это улучшит производительность, но в этом случае вы можете попробовать это.Иногда это повышает производительность шейдерного кода.

Например, для первого условия вы можете / попробовать / что-то вроде:

int condition=(s.x>=s.y)*(s.x>=s.z)*(b.x);
Coord = condition*vec4( (1.-2.*condition)*P.z, -P.y, condition, s.x );

И так далее ... Я думаю, это даст вам производительностькакие-то выгоды, хотя бы незначительные, потому что, насколько мне известно, динамические ветки на графическом процессоре дороги, когда сильно расходятся, и обычно их следует использовать только для условного устранения более крупных блоков операций.

Это самое очевидное, что я вижу.

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