Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Úvod do HLSL shaderov v game maker Studio

Určite už si niektorí z vás všimli, že okrem objektov, sprites, pozadia, scriptov apod. Je v GM Studio navyše nový typ resource - shader. Ale čo to vlastne shader je? Jedná sa o (väčšinou) krátky program, ktorý slúži na úpravu vecí kreslených na obrazovku. Používa sa na rôzne efekty.

Shadery sa píšu buď v jazyku GLSL alebo HLSL. V tomto seriáli sa zameriame hlavne na tie v HLSL, ku koncu si povieme aj niečo o GLSL. HLSL je skrátená verzia názvu High Level Shading Language

Na rozdiel od klasických programov, ktoré sa spúšťa v procesore, beží shadery na grafickej karte. Vďaka tomu sú veľmi rýchle.

Každý shader sa skladá z dvoch častí: vertex a fragment. Časť vertex pracuje s vrcholmi trojuholníkov, konci čiar a pod. Používa sa v 3D grafike napr. Na tvorbu svetiel, hmly atď. Oproti tomu fragmentovať časť pracuje s jednotlivými pixely. Tá môže tvoriť napr. Čiernobiele sfarbenie a veľa iných úprav farieb.

Ale rozprávanie už bolo dosť, ideme si to vyskúšať. :) V tomto a niekoľkých ďalších dieloch budeme meniť len fragmentovať časť shaderov a ako vertexové časť (nie, vynechať jej nemôžeme ;) ) Budeme používať tzv. Pass throught shader. Ten nerobí nič a vyzerá takto:

struct a2v {
    float4 Position : POSITION0;
    float4 Color    : COLOR0;
    float2 Texcoord : TEXCOORD0;
};

struct v2p {
    float4 Position : POSITION0;
    float4 Color    : COLOR0;
    float2 Texcoord : TEXCOORD0;
};

void main(in a2v IN, out v2p OUT)
{
    OUT.Color = IN.Color;
    OUT.Texcoord = IN.Texcoord;
    OUT.Position = mul(gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION], IN.Position);
}

Pozn. nezabudnite si hore v editore prepnúť jazyk na HLSL 9.

Zatiaľ si ho jednoducho skopírujte a nemusíte si ho ďalej všímať. Teraz si ešte ukážeme pass throught pre fragmentovať časť:

struct input{
    float4 Color    : COLOR0;
    float2 Texcoord : TEXCOORD0;
};

struct output{
    float4 Color    : COLOR0;
};

void main(in input IN, out output OUT)
{
    OUT.Color = tex2D(gm_BaseTexture, IN.Texcoord);
}

S tým už budeme pracovať, takže si ho trochu vysvetlíme. Kód sa dosť podobá jazyku C.

  • Pomocou slová struct definujeme niečo ako skupinu rôznych premenných
  • void main (...) je tzv. funkcia. Do nej budeme písať kódy našich shaderov
  • OUT.Color je výsledná farba pixelu
  • tex2D (gm_BaseTexture, IN.Texcoord) nám získa aktuálny pixel z textúry (obrázku)

Na testovanie shaderov sa hodí mať niečo, na čom je budeme skúšať. Použijeme na to tento obrázok:

Obrázok k stiahnutiu - Game maker - Efekty

Vytvoríme si objekt s týmto obrázkom a pomenujeme si ho napr. ShaderTester. Do eventu Draw vložíme nasledujúci kód:

shader_set(shader0);  // nastaví shader
draw_self();          // nakreslí sám sebe
shader_reset();       // vypne shader

Vytvorte si miestnosť s týmto objektom a čiernym pozadím. Po spustení by sa mal normálne nakresliť obrázok bez akýchkoľvek úprav.

nakreslený obrázok - Game maker - Efekty

Teraz už začneme s úpravami :) Napríklad prehodíme červenú a zelenú zložku. Pre jednoduchosť budem uvádzať iba vnútro funkcie main.

float4 col = tex2D(gm_BaseTexture, IN.Texcoord);
OUT.Color = float4(col.g, col.r, col.b, col.a);
prehodenie R a G - Game maker - Efekty

A teraz vysvetlenie:

  • float4 col - takto sa v HLSL vytvárajú premennej. Col je jej názov. float4 je typ premennej, vyjadruje skupinu štyroch reálnych čísel (vektor). Do tohto typu premenných budeme ukladať farby, viac si o dátových typoch povieme v budúcom dieli
  • tex2D(gm_BaseTexture, IN.Texcoord) - toto už poznáme, získa nám to daný pixel z obrázku
  • float4(col.g, col.r, col.b, col.a) - takto sa vytvára farba zo zložiek RGBA, zložky berieme z premennej col, len sme prehodili R a G.

O farbách si toho povieme viac. Už vieme, že sa skladajú zo zložiek RGBA (red green blue alpha, kde alpha je priehľadnosť). Pri práci s farbami sa často používajú celé čísla od 0 do 255, ale v Shader je to trochu iné. Tam sa používajú desatinné čísla od 0 do 1. (napr. 255 -> 1, 128 -> 0.5 a pod.) Toho sa dá využiť na získanie určitej časti farby.

Napríklad budeme mať farbu v premennej color, z ktorej chceme získať oranžovú časť. Robí sa to tak, že premennú vynásobíme požadovanou farbou. Oranžová je (255, 128, 0), čo v našom prípade znamená (1, 0.5, 0). Alpha zložku necháme na 1.

float4 col = color * float4(1, 0.5, 0, 1);

Skúsime si nakresliť fialovú zložku obrázka. Určite už vás napadá, ako bude kód vyzerať.

float4 col = color * float4(1, 0.5, 0, 1);
Fialová zložka obrázku - Game maker - Efekty

Môžete si skúsiť pár ďalších farieb, stačí len meniť hodnoty v zátvorke.

Podmienky

Podmienky budú posledná vec, na ktorú sa v tomto dieli zameriame. Určite sa vám nepáči to ružové pozadie okolo obrázka. Pokiaľ ale obrázok ukladáme ako napr. JPEG alebo BMP, je to spôsob, ako označiť priehľadná miesta. Pomocou podmienky môžeme zabezpečiť, aby sa tieto miesta nevykreslovala. To docielime tak, že je vykreslíme so 100% priehľadnosťou (alpha = 0). Podmienky sa píšu rovnako ako v GML (a množstvu ďalších jazykov):

if(podmínka){
    příkaz pokud je podmínka splněna
}else{
    příkaz pokud podmínka není splněna
}

Tak ideme na to. Tá ružová farba je vytvorená ako 100% červené, 0% zelené, 100% modrej a 100% alpha. Pre nás to je teda 1, 0, 1, 1. Pretože v HLSL nemožno jednoducho porovnať dve farby, musíme porovnať ich jednotlivé zložky. K tomu použijeme operátor &&.

float4 col = tex2D(gm_BaseTexture, IN.Texcoord);
if((col.r == 1) && (col.g == 0) && (col.b == 1) && (col.a == 1))
    OUT.Color = float4(0, 0, 0, 0);
else
    OUT.Color = col;
„Umelá“ transparentnosť - Game maker - Efekty

Podmienka by sa dala zjednodušiť pomocou funkcie TRUNC, ktorá zahodí desatinnú časť čísla. Na mieste jedničky (plné zložky) zostane jednička az čohokoľvek menšieho sa stane 0. Že je v premennej nula zistíme v podmienke takto -! Prom, čokoľvek väčšieho nájdeme pomocou samotného názvu:

float4 col = tex2D(gm_BaseTexture, IN.Texcoord);
float4 tcol = trunc(col);
if(tcol.r && !tcol.g && tcol.b && tcol.a)
    OUT.Color = float4(0, 0, 0, 0);
else
    OUT.Color = col;

Tým by som tento diel zakončil. Nabudúce sa pozrieme na premenné a ich typy. Ak máte akýkoľvek dotaz, pod článkom v komentároch je na ne miesta dosť.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 109x (900.09 kB)
Aplikácia je vrátane zdrojových kódov v jazyku GameMaker

 

Všetky články v sekcii
Game maker - Efekty
Článok pre vás napísal Zdeněk Pavlátka
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje spoustě zajímavých věcí ze světa informatiky a grafiky
Aktivity