Шейдер с SpriteKit регистрирует только альфа для черного цвета - PullRequest
1 голос
/ 20 апреля 2020

Я начинаю использовать шейдеры со SpriteKit на iOS. И это настоящее путешествие ...

Сейчас у меня странное поведение.

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

  • Я загрузил текстуру с различными уровнями альфа (в основном 0 и 1) в SKSpriteNode
  • Применил шейдер.
  • Шейдер выглядит следующим образом:

    #ifdef GL_ES
    precision mediump float;
    #endif
    void main() {
        vec4 color = texture2D(u_texture, v_tex_coord);
        if(color.a == 1.)
        {
            color.rgb = vec3(1.,0.,0.);
        }else if(color.a > .6)
        {
            color.rgb = vec3(0.,1.,0.);
        }
    
        else if(color.a == 0.)
        {
            color.rgb = vec3(0.,0.,1.);
        }
        color.a = .3;
        gl_FragColor = color;
    }
    

Я меняю цвет пикселя в зависимости от уровня альфа и применяю 0 к альфа каналу.

Я ожидал, что все изображение будет прозрачным. Но нет! Все полностью видно.

Теперь, если я изменю какой-либо цвет на черный vec3(0.,0.,0.);, результат изображения покажет черный цвет с прозрачностью.

У вас есть идеи, почему это происходит? И, в конце концов, как это исправить?

Вот код для создания узла:

let sp = SKSpriteNode(imageNamed: "EmptyCapsule")
let myShader = SKShader(fileNamed: "WIP")
sp.shader = myShader
sp.anchorPoint = CGPoint(x: 0, y: 0)
addChild(sp)

1 Ответ

2 голосов
/ 21 апреля 2020

Благодаря bg2b я протестировал предварительное умножение альфа, и результат оказался ожидаемым. Я не знаю, есть ли предпочтительный способ сделать это, но в итоге я получил следующее:

vec4 color = texture2D(u_texture, v_tex_coord);
if(color.a == 1.)
{
    color.rgb = vec3(1.,0.,0.);
}else if(color.a > .6)
{
    color.rgb = vec3(0.,1.,0.);
}

else if(color.a == 0.)
{
    color.rgb = vec3(0.,0.,1.);
}
color.a = .9;
gl_FragColor = vec4(color.rgb*color.a, color.a);

Следует отметить: когда я не умножал альфа-умножение, альфа все еще использовалась для смешивания различные объекты SpriteKit. Я добавил еще один SKSpriteNode под тот, которым я манипулирую, и эти 2 изображения смешались друг с другом, но цвета манипулируемого изображения были «полными».

Кроме того, в этом примере я не использовал SKDefaultShading();, чтобы выбрать цвет пикселя. Когда я это делаю, в этом случае нет никакой разницы. Как бы то ни было, если мы изменим альфа-элемент SKSpriteNode непосредственно на объекте, ни один альфа-пиксель не сохранит там первоначальный цвет, а другой изменит цвет, используемый в шейдере ...

...