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

[SFML] TextureSplatting

Ostatnio zmodyfikowano 2017-05-25 20:46
Autor Wiadomość
Rughailon
Temat założony przez niniejszego użytkownika
[SFML] TextureSplatting
» 2017-05-19 00:46:43
Witam!

Mam mapę z kafelkami i chciałbym stworzyć płynne przejścia między ich rodzajami. Testowałem klasę sf::Blend, ale nie miałem płynnych przejść, więc wyczytałem w internecie o texturesplattingu.
Problem w tym, że nie wiem, jak się do tego zabrać. Znalazłem taki kod fragment shadera:

C/C++
uniform sampler2D texMap;
uniform sampler2D terrainTex1;
uniform sampler2D terrainTex2;
uniform sampler2D terrainTex3;
uniform sampler2D terrainTex4;
uniform float overlap;

void main()
{
    vec4 map = texture2D( texMap, vec2( gl_TexCoord[ 0 ].x, gl_TexCoord[ 0 ].y ) );
    vec4 tRed = texture2D( terrainTex1, gl_TexCoord[ 0 ].xy * overlap );
    vec4 tGreen = texture2D( terrainTex2, gl_TexCoord[ 0 ].xy * overlap );
    vec4 tBlue = texture2D( terrainTex3, gl_TexCoord[ 0 ].xy * overlap );
    vec4 tAlpha = texture2D( terrainTex4, gl_TexCoord[ 0 ].xy * overlap );
    vec4 t;
    t.rgb =( tRed.rgb * map.r ) +( tGreen.rgb * map.g ) +( tBlue.rgb * map.b ) );
    t.a = 1.0;
    gl_FragColor = t;
}

Jednak nie mam pojęcia, co przekazać w kodzie. Każdy rodzaj kafelka i jedną teksturę całej mapy? W miejscu znalezienia kodu nie było to wyjaśnione.

Tak więc byłbym wdzięczny, gdyby ktoś mnie naprowadził.
P-161279
czaffik
» 2017-05-20 05:41:00
To wygląda tak jakbyś miał przekazać pięć próbek tekstury do utworzenia pieciu tekseli, tj. jednej tekstury mapy i czterech tekstur kafelków.

Przesłanie próbki tekstury to po prostu nadanie kolejnego numeru porządkowego, w twoim przypadku to będzie:
C/C++
glUniform1i( glGetUniformLocation( id_programu, "texMap" ), 0 );
glUniform1i( glGetUniformLocation( id_programu, "terrainTex1" ), 1 );
glUniform1i( glGetUniformLocation( id_programu, "terrainTex2" ), 2 );
glUniform1i( glGetUniformLocation( id_programu, "terrainTex3" ), 3 );
glUniform1i( glGetUniformLocation( id_programu, "terrainTex4" ), 4 );

potem tylko aktywujesz i bindujesz odpowiednie tekstury przed rysowaniem terenu.

To mi wygląda tak że dostaniesz obraz terenu pokrytego teksturą mapy i kafelkami (ilość w zależności od parametru overlap) przy czym każdy kafelek to mieszanina barw z każdej z czterech tekstur "terrainTex" z odpowiednią składową koloru głównej tekstury mapy, więc wygląda na to że finalny obraz to mapa pokryta jakąś tam ilością takich samych kafelków.
P-161324
Rughailon
Temat założony przez niniejszego użytkownika
» 2017-05-21 21:21:44
No właśnie nie wiem, jaka to ma być tekstura mapy. Przecież mapa jest zbudowana z kafelków, a te tekstury przekazuję w terrainTex1-4.

Zna ktoś inny sposób na stworzenie texturesplattingu w sfml albo ogólnie w 2D?
P-161394
czaffik
» 2017-05-25 20:31:01
To jest tekstura która pokrywa całą płaszczyznę mapy. Jak chcesz bez niej to pokombinuj z shaderem, może coś takiego:

C/C++
uniform sampler2D terrainTex1;
uniform sampler2D terrainTex2;
uniform sampler2D terrainTex3;
uniform sampler2D terrainTex4;
uniform float overlap;

void main()
{
    vec4 t1 = texture2D( terrainTex1, gl_TexCoord[ 0 ].xy * overlap );
    vec4 t2 = texture2D( terrainTex2, gl_TexCoord[ 0 ].xy * overlap );
    vec4 t3 = texture2D( terrainTex3, gl_TexCoord[ 0 ].xy * overlap );
    vec4 t4 = texture2D( terrainTex4, gl_TexCoord[ 0 ].xy * overlap );
    vec4 color;
    color.rgb = t1.rgb + t2.rgb + t3.rgb + t4.rgb;
    t.a = 1.0;
    gl_FragColor = color;
}

Nie wiem jak i gdzie przełączasz kafelki na terenie, i czy to jedna tekstura, ale załóżmy że masz pole z jednym kafelkiem i pole z drugim kafelkiem, pomiędzy nimi pole gdzie chcesz mieć przejście, mógłbyś dla takiego przejścia użyć shadera:

C/C++
uniform sampler2D terrainTex1;
uniform sampler2D terrainTex2;
uniform float value;
uniform float overlap;


void main()
{
    vec4 t1 = texture2D( terrainTex1, gl_TexCoord[ 0 ].xy * overlap );
    vec4 t2 = texture2D( terrainTex2, gl_TexCoord[ 0 ].xy * overlap );
   
    vec4 color;
    color = mix( t1, t2, value );
   
    gl_FragColor = color;
}

z parameterm value 0.5.
Przekazujesz obie tekstury, parametr overlap określa na ile kafelków tekstur będzie mapa podzielona, value określa która tekstura będzie bardziej widoczna, (0.0 - tekstura 1, 1.0 - tekstura 2, 0.5 - obie po 50%), ale nie wiem czy wyjdzie to co byś chciał.

Co do texturesplattingu używając bibliotek nie mam pojęcia, btw używasz opengla czy smfmlowej biblioteki do generowania obrazu 2d? nie wiem na czym on jest oparty ale chyba nie na openglu, w takim razie nic ci po shaderach.
P-161571
Saran
» 2017-05-25 20:38:59
Na OpenGLu.
P-161572
czaffik
» 2017-05-25 20:46:58
no to w takim razie... ucz się shaderów, myślę że warto i pokombinuj co ci wyjdzie.

To tutaj wyglądało by tak, że ustawiasz fragment shadera na jakąś wartość value, np na 0 i rysujesz te kawałki mapy na których ma być widoczna pierwsza tekstura, ustawiasz value na 1 i rysujesz te kawałki mapy na których ma być widoczny drugi kafelek, miejsca gdzie kafelki mają się łączyć rysujesz ustalając wartość value dla shadera na 0.5, oczywiście efekt tutaj będzie zależny od wielkości kafelków.
P-161573
« 1 »
  Strona 1 z 1