Cześć! Przejrzałem Twój kod shadera i widzę w nim błąd składniowy, który najprawdopodobniej powoduje, że shader w ogóle się nie kompiluje lub działa niepoprawnie.
Główny błąd
W warunku if (w operatorze trójelementowym) próbujesz porównać pojedynczy kanał koloru (typ float, np. c.b) do całego wektora koloru (typ vec4, czyli alphaColor).
Masz tam:
c.b == alphaColor
oraz
c.a == alphaColor
To tak, jakbyś próbował porównać jedną liczbę do czterech liczb naraz. Kompilator GLSL tego nie przepuści (lub zwróci błąd, który SFML może ignorować w domyślnej konfiguracji, zostawiając czarny ekran).
Musisz porównywać float z float, czyli odwołać się do konkretnych składowych wektora alphaColor (używając .r, .g, .b, .a lub .x, .y, .z, .w).
Poprawiony kod (pod względem składni)
std::string mask_shader_source = R"(
uniform sampler2D texture;
uniform sampler2D mask;
uniform vec4 alphaColor;
void main() {
vec2 uv = gl_TexCoord[0].xy;
vec4 c = texture2D(texture, uv);
// POPRAWKA: Dodano .b i .a do alphaColor
// Zwróć uwagę na alphaColor.b oraz alphaColor.a
float alpha = (c.r == alphaColor.r && c.g == alphaColor.g && c.b == alphaColor.b && c.a == alphaColor.a)
? 0.0
: texture2D(mask, uv).a;
gl_FragColor = vec4(c.rgb, c.a * alpha);
}
)";
Ważna uwaga dotycząca precyzji (Floating Point)
Używanie operatora == (równości) na liczbach zmiennoprzecinkowych (float) w shaderach jest bardzo ryzykowne. Nawet minimalny błąd zaokrąglenia (rzędu 0.0001) spowoduje, że kolory nie będą równe, a piksel nie stanie się przezroczysty.
Zamiast sprawdzać c.r == alphaColor.r, znacznie lepiej jest sprawdzić, czy różnica między kolorami jest "wystarczająco mała" (tzw. epsilon).
Oto bezpieczniejsza i bardziej profesjonalna wersja tego shadera:
std::string mask_shader_source = R"(
uniform sampler2D texture;
uniform sampler2D mask;
uniform vec4 alphaColor;
void main() {
vec2 uv = gl_TexCoord[0].xy;
vec4 c = texture2D(texture, uv);
// Obliczamy różnicę wektorów.
// Funkcja distance zwraca odległość (długość wektora różnicy).
// Jeśli jest mniejsza niż 0.01 (czyli 1% różnicy), uznajemy, że kolory są równe.
float dist = distance(c.rgb, alphaColor.rgb);
// Sprawdzamy też kanał alfa (jeśli jest potrzebny)
bool isTransparent = (dist < 0.01) && (abs(c.a - alphaColor.a) < 0.01);
float alpha = isTransparent
? 0.0
: texture2D(mask, uv).a;
gl_FragColor = vec4(c.rgb, c.a * alpha);
}
)";
Daj znać, czy po poprawieniu odwołań do .b i .a zaczęło działać!