Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Outline - Shader generujący obrys wokół kształtów na zadanym tle

Ostatnio zmodyfikowano wczoraj o godz. 19:04
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
Outline - Shader generujący obrys wokół kształtów na zadanym tle
» 2025-11-05 17:40:59
Witam. Poszukuje shadera do generowania outline na teksturze w taki sposób, że:
-outlineColor - określa kolor obrysu
-outlineWidth - określa szerokość obrysu
-backgroundColor - określa kolor na którym jest generowany obrys
-outline jest generowany "na zewnątrz"

Mam algorytm od ChataGPT ale na obrys "do wewnątrz":

C/C++
std::string outline_shader_source = R"( uniform sampler2D texture; uniform vec2 texelSize; // 1/rozmiar tekstury uniform float width; // 0..8 (promień w px) uniform vec4 backgroundColor; // kolor tła uniform vec4 outlineColor; // kolor obrysu (rgb) + siła a (0..1) uniform float threshold; // tolerancja dopasowania koloru tła (np. 0.02..0.1) float colorDistance(vec3 a, vec3 b) { return length(a - b); } void main() { vec2 uv = gl_TexCoord[0].xy; vec4 base = texture2D(texture, uv); // bieżący piksel to tło? float isBg = step(colorDistance(base.rgb, backgroundColor.rgb), threshold); // promień (zaokrąglony, ograniczony do 8) int r = int(ceil(clamp(width, 0.0, 8.0))); // czy w sąsiedztwie leży cokolwiek NIE będącego tłem? float hasNonBgNeighbor = 0.0; for (int dy = -8; dy <= 8; ++dy) { for (int dx = -8; dx <= 8; ++dx) { if (abs(dx) > r || abs(dy) > r) continue; if (dx*dx + dy*dy > r*r) continue; // koło if (dx == 0 && dy == 0) continue; // pomijamy siebie vec2 o = vec2(float(dx), float(dy)) * texelSize; vec3 c = texture2D(texture, uv + o).rgb; float isBgSample = step(colorDistance(c, backgroundColor.rgb), threshold); hasNonBgNeighbor = max(hasNonBgNeighbor, 1.0 - isBgSample); } } // obrys powstaje TYLKO na pikselach tła stykających się z obiektem float edge = isBg * hasNonBgNeighbor; // kolorujemy piksele tła tam, gdzie edge==1, reszta bez zmian vec3 rgbOut = mix(base.rgb, outlineColor.rgb, edge * outlineColor.a); float aOut = base.a; // nie ruszamy alfy gl_FragColor = vec4(rgbOut, aOut); } )";
P-183394
tBane
Temat założony przez niniejszego użytkownika
» 2025-11-05 17:59:57
Dobra. Udało się. Oto dany shader generujący outline :-)



C/C++
std::string outline_shader_source = R"( uniform sampler2D u_tex; uniform vec2 texelSize; // 1.0 / textureSize uniform float outlineWidth; // 0..8 px uniform vec4 backgroundColor; // kolor tła (color key) uniform vec4 outlineColor; // kolor obrysu (rgb) + siła a [0..1] uniform float threshold; // tolerancja podobieństwa do tła (0.02..0.08) float colorDistance(vec3 a, vec3 b) { return length(a - b); } void main() { vec2 uv = gl_TexCoord[0].xy; vec4 base = texture2D(u_tex, uv); // bieżący piksel to tło? float isBg = step(colorDistance(base.rgb, backgroundColor.rgb), threshold); // promień próbkowania (max 8) int r = int(ceil(clamp(outlineWidth, 0.0, 8.0))); // wykryj, czy w sąsiedztwie jest piksel NIE-będący tłem (czyli „obiekt”) float hasNonBgNeighbor = 0.0; if (r > 0) { for (int dy = -outlineWidth; dy <= outlineWidth; dy++) { for (int dx = -outlineWidth; dx <= outlineWidth; dx++) { if (abs(dx) > r || abs(dy) > r) continue; if (dx*dx + dy*dy > r*r) continue; // koło if (dx == 0 && dy == 0) continue; // pomijamy siebie vec2 o = vec2(float(dx), float(dy)) * texelSize; vec3 c = texture2D(u_tex, uv + o).rgb; float isBgSample = step(colorDistance(c, backgroundColor.rgb), threshold); hasNonBgNeighbor = max(hasNonBgNeighbor, 1.0 - isBgSample); } } } // malujemy TYLKO na pikselach tła stykających się z obiektem (zewnętrzny obrys) float edge = isBg * hasNonBgNeighbor; // kolorujemy tło na krawędzi; piksele obiektu zostają nietknięte; alfa bez zmian vec3 rgbOut = mix(base.rgb, outlineColor.rgb, edge * outlineColor.a); float aOut = base.a; gl_FragColor = vec4(rgbOut, aOut); } )";
P-183395
« 1 »
  Strona 1 z 1