Warsztat.GDCompo!ProjektyMediaArtykułyQ&AForumOferty pracyPobieranie

Opisz napotkaną sytuację, a redakcja niezwłocznie znajdzie rozwiązanie!

wyślij anuluj

Texture Splatting

Co będzie nam potrzebne:

- 3 tekstury (np. ziemia, trawa, gruz)

- 1 tekstura terenu (pokolorowana 3 kolorami - #ff0000 , #00ff00, #0000ff )

- 1 plik txt

- kubek kawy

- około 10 - 30 minut wolnego czasu

 

Tak więc jak to będzie działać.

Ok więc wiemy co z czego, ale jeszcze jak?

Zacznijmy więc od najważniejszej rzeczy jaką jest fragment shader. Jest on kluczowy w tym aspekcie z racji tego, że to on poteksturuje nam naszą "mape".

uniform sampler2D texMap;
uniform sampler2D finalTex;
uniform sampler2D terrainTex1;
uniform sampler2D terrainTex2;
uniform sampler2D terrainTex3;
uniform sampler2D terrainTex4;
uniform float duplicate;

void main()
{

// [1] 
vec4 map = texture2D(texMap, vec2(gl_TexCoord[0].x,1.0-gl_TexCoord[0].y));
vec4 tRed = texture2D(terrainTex1, gl_TexCoord[0].xy*duplicate);
vec4 tGreen = texture2D(terrainTex2, gl_TexCoord[0].xy*duplicate);
vec4 tBlue = texture2D(terrainTex3, gl_TexCoord[0].xy*duplicate);
vec4 tAlpha = texture2D(terrainTex4, gl_TexCoord[0].xy*duplicate);
vec4 final = texture2D(finalTex,vec2(gl_TexCoord[0].x, gl_TexCoord[0].y));
vec4 t;

// [2]
t.rgba = (tRed.rgb * map.r) + (tGreen.rgb * map.g) + (tBlue.rgb * map.b) + (tAlpha.rgb * ???); //??? - zagadka przez co pomnożyć tekstura która ma być na kanale Alpha

gl_FragColor = t;
}

Jeżeli miał ktoś kiedyś do czynienia z shaderami to ten kod jest dla niego banalny.

uniform - umożliwia "kontaktowanie się" twojej grze z tą zmienną.

sampler2D - teksturka 2D

gl_FragColor - jest zwrotem danego koloru, dla aktualnego pixela. Mamy 3 typy shaderów - Fragment, Vertex i Geometry.

Tak więc co ten shader robi. Ano na początku [1] zczytuje z tekstury kolory aktualnych pixeli. Potem [2] wylicza kolor dla aktualnego pixela. Wyliczanka jest banalnie prosta. Każda tekstura ma swój oddzielny kanał (stąd tRed, tGreen, tBlue i tAlpha i mapa jest kolorowana tylko pełnym kolorem (przejścia gradientem mogą być)). Jeżeli każda tekstura ma swój kanał to trzeba go przez wartość tego kanału pomnożyć. Gdy pixel na mapie (10,250) będzie miał kolor 255,0,0, to na ekranie pojawi się piksel z tekstury numer 1 z (10,250) tejże tekstury. Proste? Tak myślałem.

Jeżeli shader mamy już ogarnięty możemy przystąpić do pisania kodu w grze. Pominę rzeczy jak wczytanie tekstur terenu i podłoża. Aby naszą teksturę wyświetlić potrzebujemy Sprite by narysować finalnie na ekranie naszą mapkę, oraz ustawić shader poprawnie.

sf::Shader shader;
shader.loadFromFile("shader.txt",sf::Shader::Fragment);
shader.setParameter("texMap",mapTexture);
shader.setParameter("terrainTex1", dirtTexture);
shader.setParameter("terrainTex2", grassTexture);
shader.setParameter("terrainTex3", pitTexture);

Tutaj może pojawić się pytanie. Tekstura ma 64x64, a chcę ją narysować na pełnym ekranie 4k czy coś się stanie? Tak zostanie rozciągnięta. Aby tego uniknąć wystarczy dopisać

dirtTexture.setRepeated(true);
pitTexture.setRepeated(true);
grassTexture.setRepeated(true);

Ah zapomniałbym zmienna duplicate jest od tego, by dostosować sobie ile razy tekstura ma zostać powielona. Nie bierze jednak pod uwagę ile została razy powielona przez jej wielkość, więc powielenie finalnie będzie wynosić (rozmiar mapy / rozmiar tekstury) * duplicate.

Samo rysowanie to banał. Jeżeli potrzebujemy rysować teren co klatkę wygląda to następująco

app.draw(spr,&shader);
Jeżeli byśmy chcieli bawić się w rysowanie kiedy potrzeba potrzebowali byśmy to policzyć i przetrzymać aktualny wygląd w RenderTexture.

sf::RectangleShape rect;
rect.setSize(sf::Vector2f(800,600));
rect.setTexture(&mapTexture);

sf::RenderTexture finalTexture(800,600);
sf::Sprite finalSpr;
finalSpr.setTexture(finalTexture.getTexture());

////////////////////////////////////////////////////

finalTexture.draw(rect,&shader);
app.clear();
app.draw(finalSpr);

app.display();

I to było by na tyle :) 

Tekst dodał:
Mateusz Kin
17.04.2014 13:39

Ostatnia edycja:
Mateusz Kin
17.04.2014 13:39


Aby edytować tekst, musisz się zalogować.

# Edytuj Porównaj Czas Autor Rozmiar
#1 edytuj 17.04.2014 13:39 Mateusz Kin 4.54 KB
Zwykły
Do sprawdzenia
Do akceptacji
  • Napisz komentarz:
    Aby dodać swój komentarz, musisz się zalogować.
Licencja Creative Commons

Warsztat używa plików cookies. | Copyright © 2006-2017 Warsztat · Kontakt · Regulamin i polityka prywatności
build #ff080b4740 (Tue Mar 25 11:39:28 CET 2014)